Whamcloud - gitweb
LU-508 ldiskfs: fix race in ext4_ext_walk_space()
[fs/lustre-release.git] / lustre / lvfs / fsfilt_ext3.c
index af1f719..54b16ae 100644 (file)
@@ -983,19 +983,18 @@ static int ext3_ext_new_extent_cb(struct ext3_ext_base *base,
 #endif
         struct inode *inode = ext3_ext_base2inode(base);
         struct ext3_extent nex;
-#if defined(HAVE_EXT4_LDISKFS)
-        struct ext4_ext_path *tmppath = NULL;
-        struct ext4_extent *tmpex;
-#endif
         unsigned long pblock;
         unsigned long tgen;
-        int err, i, depth;
+        int err, i;
         unsigned long count;
         handle_t *handle;
 
-        i = depth = EXT_DEPTH(base);
-        EXT_ASSERT(i == path->p_depth);
+        i = EXT_DEPTH(base);
         EXT_ASSERT(path[i].p_hdr);
+        LASSERTF(i == path->p_depth ||
+                 EXT_GENERATION(base) != path[0].p_generation,
+                 "base vs path extent depth:%d != %d, generation:%lu == %lu\n",
+                 i, path->p_depth, EXT_GENERATION(base), path[0].p_generation);
 
         if (cex->ec_type == EXT3_EXT_CACHE_EXTENT) {
                 err = EXT_CONTINUE;
@@ -1040,21 +1039,13 @@ static int ext3_ext_new_extent_cb(struct ext3_ext_base *base,
 
 #if defined(HAVE_EXT4_LDISKFS)
         /* In 2.6.32 kernel, ext4_ext_walk_space()'s callback func is not
-         * protected by i_data_sem, we need revalidate extent to be created */
+         * protected by i_data_sem as whole. so we patch it to store
+        * generation to path and now verify the tree hasn't changed */
         down_write((&EXT4_I(inode)->i_data_sem));
 
         /* validate extent, make sure the extent tree does not changed */
-        tmppath = ext4_ext_find_extent(inode, cex->ec_block, NULL);
-        if (IS_ERR(tmppath)) {
-                up_write(&EXT4_I(inode)->i_data_sem);
-                ext3_journal_stop(handle);
-                return PTR_ERR(tmppath);
-        }
-        tmpex = tmppath[depth].p_ext;
-        if (tmpex != ex) {
+       if (EXT_GENERATION(base) != path[0].p_generation) {
                 /* cex is invalid, try again */
-                ext4_ext_drop_refs(tmppath);
-                kfree(tmppath);
                 up_write(&EXT4_I(inode)->i_data_sem);
                 ext3_journal_stop(handle);
                 return EXT_REPEAT;
@@ -1096,8 +1087,6 @@ static int ext3_ext_new_extent_cb(struct ext3_ext_base *base,
 
 out:
 #if defined(HAVE_EXT4_LDISKFS)
-        ext4_ext_drop_refs(tmppath);
-        kfree(tmppath);
         up_write((&EXT4_I(inode)->i_data_sem));
 #endif
         ext3_journal_stop(handle);