Whamcloud - gitweb
LU-2638 ldiskfs: update dotdot entry for rename
authorFan Yong <yong.fan@whamcloud.com>
Thu, 10 Jan 2013 13:32:57 +0000 (21:32 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 30 Jan 2013 22:07:21 +0000 (17:07 -0500)
On master, when rename a directory, its old dotdot entry will
be removed firstly, then insert the new dotdot entry, and try
to append FID-in-dirent. But the space for dotdot entry maybe
not enough to hold the new dotdot with FID-in-dirent, such as
the MDT device restored from file-level backup, or the device
is upgraded from 1.8. If we do not move data in the directory
block, the FID-in-dirent will overwrite the dx_root and cause
the directory crashed. Currently, we do not want to introduce
complex logic to handle directory data moving, instead, under
such case, ignore the FID-in-dirent for the new dotdot entry,
and just insert the new dotdot entry.

Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Id38f5136fb2bc607344c37ca10a32e63ab427e3d
Reviewed-on: http://review.whamcloud.com/5179
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
ldiskfs/kernel_patches/patches/ext4_data_in_dirent-rhel6.patch

index b23e2d6..75e5634 100644 (file)
@@ -420,12 +420,13 @@ Index: linux-stage/fs/ext4/namei.c
        else
 -              assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
 +              assert(le16_to_cpu(de->rec_len) >= __EXT4_DIR_REC_LEN(2));
        else
 -              assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
 +              assert(le16_to_cpu(de->rec_len) >= __EXT4_DIR_REC_LEN(2));
-       de->name_len = 2;
-       strcpy (de->name, "..");
-       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
-+      if (data) {
+       de->name_len = 2;
+       strcpy (de->name, "..");
+-      ext4_set_de_type(dir->i_sb, de, S_IFDIR);
++      if (data != NULL && ext4_get_dirent_data_len(de) >= dlen) {
 +              de->name[2] = 0;
 +              de->name[2] = 0;
-+              memcpy(&de->name[2 + 1], data, dlen);
++              memcpy(&de->name[2 + 1], data, *data);
++              ext4_set_de_type(dir->i_sb, de, S_IFDIR);
 +              de->file_type |= EXT4_DIRENT_LUFID;
 +      }
  
 +              de->file_type |= EXT4_DIRENT_LUFID;
 +      }