Whamcloud - gitweb
libext2fs: refactor code which fixes up the checksums in an extent tree
authorTheodore Ts'o <tytso@mit.edu>
Sun, 21 Oct 2018 13:32:37 +0000 (09:32 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 21 Oct 2018 13:34:58 +0000 (09:34 -0400)
The code to recalculate the checksums in an extent tree (which is
needed after an inode is relocated so it has a different inode number)
was duplicated in tune2fs and resize2fs.  In addition, this work could
be done in a much more efficient way inside lib/ext2fs/extent.c.

This commit creates a new library function which corrects the
checksums in an inode's extent tree, named: ext2fs_fix_extents_checksums()

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/ext2fs.h
lib/ext2fs/extent.c
misc/tune2fs.c
resize/resize2fs.c

index 185be5d..a5fc90a 100644 (file)
@@ -1295,7 +1295,9 @@ extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
 extern errcode_t ext2fs_extent_goto2(ext2_extent_handle_t handle,
                                     int leaf_level, blk64_t blk);
 extern errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle);
-size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
+extern size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
+extern errcode_t ext2fs_fix_extents_checksums(ext2_filsys fs, ext2_ino_t ino,
+                                             struct ext2_inode *inode);
 
 /* fallocate.c */
 #define EXT2_FALLOCATE_ZERO_BLOCKS     (0x1)
index a9cdae7..ac3dbfe 100644 (file)
@@ -1737,6 +1737,54 @@ size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle)
        return last_result;
 }
 
+errcode_t ext2fs_fix_extents_checksums(ext2_filsys fs, ext2_ino_t ino,
+                                      struct ext2_inode *inode)
+{
+       ext2_extent_handle_t    handle;
+       struct ext2fs_extent    extent;
+       errcode_t               errcode;
+       int                     save_flags = fs->flags;
+
+       if (!ext2fs_has_feature_metadata_csum(fs->super) ||
+           (inode && !(inode->i_flags & EXT4_EXTENTS_FL)))
+               return 0;
+
+       errcode = ext2fs_extent_open2(fs, ino, inode, &handle);
+       if (errcode) {
+               if (errcode == EXT2_ET_INODE_NOT_EXTENT)
+                       errcode = 0;
+               return errcode;
+       }
+
+       fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+       errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
+       if (errcode)
+               goto out;
+
+       do {
+               /* Skip to the end of a block of leaf nodes */
+               if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
+                       errcode = ext2fs_extent_get(handle,
+                                                   EXT2_EXTENT_LAST_SIB,
+                                                   &extent);
+                       if (errcode)
+                               break;
+               }
+
+               errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
+               if (errcode == EXT2_ET_EXTENT_CSUM_INVALID)
+                       errcode = update_path(handle);
+       } while (errcode == 0);
+
+out:
+       /* Ok if we run off the end */
+       if (errcode == EXT2_ET_EXTENT_NO_NEXT)
+               errcode = 0;
+       ext2fs_extent_free(handle);
+       fs->flags = save_flags;
+       return errcode;
+}
+
 #ifdef DEBUG
 /*
  * Override debugfs's prompt
index a680b46..616bdc6 100644 (file)
@@ -497,64 +497,6 @@ static void convert_64bit(ext2_filsys fs, int direction)
                fprintf(stderr, _("' to disable 64-bit mode.\n"));
 }
 
-/* Rewrite extents */
-static errcode_t rewrite_extents(ext2_filsys fs, ext2_ino_t ino,
-                                struct ext2_inode *inode)
-{
-       ext2_extent_handle_t    handle;
-       struct ext2fs_extent    extent;
-       errcode_t               errcode;
-       struct ext2_extent_info info;
-
-       if (!(inode->i_flags & EXT4_EXTENTS_FL) ||
-           !ext2fs_has_feature_metadata_csum(fs->super))
-               return 0;
-
-       errcode = ext2fs_extent_open(fs, ino, &handle);
-       if (errcode)
-               return errcode;
-
-       errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
-       if (errcode)
-               goto out;
-
-       do {
-               errcode = ext2fs_extent_get_info(handle, &info);
-               if (errcode)
-                       break;
-
-               /*
-                * If this is the first extent in an extent block that we
-                * haven't visited, rewrite the extent to force the ETB
-                * checksum to be rewritten.
-                */
-               if (info.curr_entry == 1 && info.curr_level != 0 &&
-                   !(extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)) {
-                       errcode = ext2fs_extent_replace(handle, 0, &extent);
-                       if (errcode)
-                               break;
-               }
-
-               /* Skip to the end of a block of leaf nodes */
-               if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
-                       errcode = ext2fs_extent_get(handle,
-                                                   EXT2_EXTENT_LAST_SIB,
-                                                   &extent);
-                       if (errcode)
-                               break;
-               }
-
-               errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
-       } while (errcode == 0);
-
-out:
-       /* Ok if we run off the end */
-       if (errcode == EXT2_ET_EXTENT_NO_NEXT)
-               errcode = 0;
-       ext2fs_extent_free(handle);
-       return errcode;
-}
-
 /*
  * Rewrite directory blocks with checksums
  */
@@ -849,7 +791,7 @@ static void rewrite_one_inode(struct rewrite_context *ctx, ext2_ino_t ino,
        if (retval)
                fatal_err(retval, "while writing inode");
 
-       retval = rewrite_extents(ctx->fs, ino, inode);
+       retval = ext2fs_fix_extents_checksums(ctx->fs, ino, inode);
        if (retval)
                fatal_err(retval, "while rewriting extents");
 
index 38032e5..c2e1047 100644 (file)
@@ -1927,59 +1927,6 @@ out:
        return err;
 }
 
-/* Rewrite extents */
-static errcode_t rewrite_extents(ext2_filsys fs, ext2_ino_t ino)
-{
-       ext2_extent_handle_t    handle;
-       struct ext2fs_extent    extent;
-       errcode_t               errcode;
-       struct ext2_extent_info info;
-
-       errcode = ext2fs_extent_open(fs, ino, &handle);
-       if (errcode)
-               return errcode;
-
-       errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
-       if (errcode)
-               goto out;
-
-       do {
-               errcode = ext2fs_extent_get_info(handle, &info);
-               if (errcode)
-                       break;
-
-               /*
-                * If this is the first extent in an extent block that we
-                * haven't visited, rewrite the extent to force the ETB
-                * checksum to be rewritten.
-                */
-               if (info.curr_entry == 1 && info.curr_level != 0 &&
-                   !(extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)) {
-                       errcode = ext2fs_extent_replace(handle, 0, &extent);
-                       if (errcode)
-                               break;
-               }
-
-               /* Skip to the end of a block of leaf nodes */
-               if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
-                       errcode = ext2fs_extent_get(handle,
-                                                   EXT2_EXTENT_LAST_SIB,
-                                                   &extent);
-                       if (errcode)
-                               break;
-               }
-
-               errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
-       } while (errcode == 0);
-
-out:
-       /* Ok if we run off the end */
-       if (errcode == EXT2_ET_EXTENT_NO_NEXT)
-               errcode = 0;
-       ext2fs_extent_free(handle);
-       return errcode;
-}
-
 static void quiet_com_err_proc(const char *whoami EXT2FS_ATTR((unused)),
                               errcode_t code EXT2FS_ATTR((unused)),
                               const char *fmt EXT2FS_ATTR((unused)),
@@ -2276,7 +2223,8 @@ remap_blocks:
                /* Fix up extent block checksums with the new inode number */
                if (ext2fs_has_feature_metadata_csum(rfs->old_fs->super) &&
                    (inode->i_flags & EXT4_EXTENTS_FL)) {
-                       retval = rewrite_extents(rfs->old_fs, new_inode);
+                       retval = ext2fs_fix_extents_checksums(rfs->old_fs,
+                                                             new_inode, NULL);
                        if (retval)
                                goto errout;
                }