Whamcloud - gitweb
Teach ext2fs_open2() to honor the EXT2_FLAG_SUPER_ONLY flag
authorTheodore Ts'o <tytso@mit.edu>
Tue, 22 Oct 2019 22:42:25 +0000 (18:42 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 22 Oct 2019 22:55:06 +0000 (18:55 -0400)
Opening the file system with EXT2_FLAG_SUPER_ONLY will leave
fs->group_desc to be NULL and modify "dumpe2fs -h" and tune2fs when it
is emulating e2label to use this flag.  This speeds up "dumpe2fs -h"
and "e2label" when operating on very large file systems.

To allow other libext2fs functions to work without too many surprises,
ext2fs_group_desc() will read in the block group descriptors on
demand.  This allows "dumpe2fs -h" to be able to read the journal
inode, for example.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cray-bug-id: LUS-5777

lib/ext2fs/blknum.c
lib/ext2fs/openfs.c
misc/dumpe2fs.c
misc/tune2fs.c

index 9ee5c66..18af340 100644 (file)
@@ -185,9 +185,42 @@ struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
                                          struct opaque_ext2_group_desc *gdp,
                                          dgrp_t group)
 {
-       int desc_size = EXT2_DESC_SIZE(fs->super) & ~7;
-
-       return (struct ext2_group_desc *)((char *)gdp + group * desc_size);
+       struct ext2_group_desc *ret_gdp;
+       errcode_t       retval;
+       static char     *buf = 0;
+       static int      bufsize = 0;
+       blk64_t         blk;
+       int             desc_size = EXT2_DESC_SIZE(fs->super) & ~7;
+       int             desc_per_blk = EXT2_DESC_PER_BLOCK(fs->super);
+
+       if (group > fs->group_desc_count)
+               return NULL;
+       if (gdp)
+               return (struct ext2_group_desc *)((char *)gdp +
+                                                 group * desc_size);
+       /*
+        * If fs->group_desc wasn't read in when the file system was
+        * opened, then read it on demand here.
+        */
+       if (bufsize < fs->blocksize)
+               ext2fs_free_mem(&buf);
+       if (!buf) {
+               retval = ext2fs_get_mem(fs->blocksize, &buf);
+               if (retval)
+                       return NULL;
+               bufsize = fs->blocksize;
+       }
+       blk = ext2fs_descriptor_block_loc2(fs, fs->super->s_first_data_block,
+                                          group / desc_per_blk);
+       retval = io_channel_read_blk(fs->io, blk, 1, buf);
+       if (retval)
+               return NULL;
+       ret_gdp = (struct ext2_group_desc *)
+               (buf + ((group % desc_per_blk) * desc_size));
+#ifdef WORDS_BIGENDIAN
+       ext2fs_swap_group_desc2(fs, ret_gdp);
+#endif
+       return ret_gdp;
 }
 
 /* Do the same but as an ext4 group desc for internal use here */
index 51b54a4..ec2d6cb 100644 (file)
@@ -393,6 +393,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
        }
        fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
                                          EXT2_DESC_PER_BLOCK(fs->super));
+       if (flags & EXT2_FLAG_SUPER_ONLY)
+               goto skip_read_bg;
        retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
                                &fs->group_desc);
        if (retval)
@@ -479,7 +481,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                if (fs->flags & EXT2_FLAG_RW)
                        ext2fs_mark_super_dirty(fs);
        }
-
+skip_read_bg:
        if (ext2fs_has_feature_mmp(fs->super) &&
            !(flags & EXT2_FLAG_SKIP_MMP) &&
            (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) {
index 384ce92..18148e2 100644 (file)
@@ -666,6 +666,8 @@ int main (int argc, char ** argv)
                flags |= EXT2_FLAG_FORCE;
        if (image_dump)
                flags |= EXT2_FLAG_IMAGE_FILE;
+       if (header_only)
+               flags |= EXT2_FLAG_SUPER_ONLY;
 try_open_again:
        if (use_superblock && !use_blocksize) {
                for (use_blocksize = EXT2_MIN_BLOCK_SIZE;
index 39fce4a..77a4587 100644 (file)
@@ -1698,7 +1698,7 @@ static void parse_e2label_options(int argc, char ** argv)
                        argv[1]);
                exit(1);
        }
-       open_flag = EXT2_FLAG_JOURNAL_DEV_OK;
+       open_flag = EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SUPER_ONLY;
        if (argc == 3) {
                open_flag |= EXT2_FLAG_RW;
                L_flag = 1;