Whamcloud - gitweb
libext2fs: fix BLOCK_ABORT handling in the block iterator for extents
authorTheodore Ts'o <tytso@mit.edu>
Wed, 15 Feb 2012 22:25:32 +0000 (17:25 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 17 Feb 2012 19:32:17 +0000 (14:32 -0500)
When processing files that contain extents, the block iterator
functions were not properly handling the BLOCK_ABORT bit.  This could
cause problems such as ext2fs_link() adding a directory entry multiple
times.

Thanks to Darrick Wong <djwong@us.ibm.com> for reporting this.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/block.c

index 6a5c10d..85a1803 100644 (file)
@@ -414,7 +414,7 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
                                                0, 0, priv_data);
                                ret |= r;
                                check_for_ro_violation_goto(&ctx, ret,
-                                                           extent_errout);
+                                                           extent_done);
                                if (r & BLOCK_CHANGED) {
                                        ctx.errcode =
                                                ext2fs_extent_set_bmap(handle,
@@ -448,6 +448,8 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
                                                if (ctx.errcode)
                                                        break;
                                        }
+                                       if (ret & BLOCK_ABORT)
+                                               break;
                                }
                                continue;
                        }
@@ -473,23 +475,23 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
                                                0, 0, priv_data);
                                ret |= r;
                                check_for_ro_violation_goto(&ctx, ret,
-                                                           extent_errout);
+                                                           extent_done);
                                if (r & BLOCK_CHANGED) {
                                        ctx.errcode =
                                                ext2fs_extent_set_bmap(handle,
                                                       (blk64_t) blockcnt,
                                                       new_blk, uninit);
                                        if (ctx.errcode)
-                                               goto extent_errout;
+                                               goto extent_done;
                                }
                                if (ret & BLOCK_ABORT)
-                                       break;
+                                       goto extent_done;
                        }
                }
 
-       extent_errout:
+       extent_done:
                ext2fs_extent_free(handle);
-               ret |= BLOCK_ERROR | BLOCK_ABORT;
+               ret |= BLOCK_ERROR; /* ctx.errcode is always valid here */
                goto errout;
        }