Whamcloud - gitweb
Add support for the meta_blockgroup filesystem format.
authorTheodore Ts'o <tytso@mit.edu>
Sun, 20 Oct 2002 04:38:57 +0000 (00:38 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 20 Oct 2002 04:38:57 +0000 (00:38 -0400)
15 files changed:
e2fsck/pass1.c
lib/e2p/ChangeLog
lib/e2p/feature.c
lib/e2p/ls.c
lib/ext2fs/ChangeLog
lib/ext2fs/closefs.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2fs.h
lib/ext2fs/initialize.c
lib/ext2fs/openfs.c
lib/ext2fs/swapfs.c
misc/ChangeLog
misc/dumpe2fs.c
misc/e2image.c
misc/mke2fs.c

index 9849645..c685581 100644 (file)
@@ -1793,7 +1793,7 @@ static void mark_table_blocks(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
        blk_t   block, b;
-       int     i,j;
+       int     i, j, has_super, meta_bg, meta_bg_size;
        struct problem_context pctx;
        
        clear_problem_context(&pctx);
@@ -1802,21 +1802,39 @@ static void mark_table_blocks(e2fsck_t ctx)
        for (i = 0; i < fs->group_desc_count; i++) {
                pctx.group = i;
 
-               if (ext2fs_bg_has_super(fs, i)) {
+               has_super = ext2fs_bg_has_super(fs, i);
+               if (has_super)
                        /*
                         * Mark this group's copy of the superblock
                         */
                        ext2fs_mark_block_bitmap(ctx->block_found_map, block);
                
-                       /*
-                        * Mark this group's copy of the descriptors
-                        */
-                       for (j = 0; j < fs->desc_blocks; j++) {
-                               ext2fs_mark_block_bitmap(ctx->block_found_map,
+               meta_bg_size = (fs->blocksize /
+                               sizeof (struct ext2_group_desc));
+               meta_bg = i / meta_bg_size;
+               if (!(fs->super->s_feature_incompat &
+                     EXT2_FEATURE_INCOMPAT_META_BG) ||
+                   (meta_bg < fs->super->s_first_meta_bg)) {
+                       if (has_super) {
+                               /*
+                                * Mark this group's copy of the descriptors
+                                */
+                               for (j = 0; j < fs->desc_blocks; j++) {
+                                       ext2fs_mark_block_bitmap(ctx->block_found_map,
                                                         block + j + 1);
+                               }
                        }
+               } else {
+                       if (has_super)
+                               has_super = 1;
+                       if (((i % meta_bg_size) == 0) ||
+                           ((i % meta_bg_size) == 1) ||
+                           ((i % meta_bg_size) == (meta_bg_size-1)))
+                               ext2fs_mark_block_bitmap(ctx->block_found_map,
+                                                block + has_super);
                }
                
+               
                /*
                 * Mark the blocks used for the inode table
                 */
index ba6c7f9..f3a9b70 100644 (file)
@@ -1,3 +1,8 @@
+2002-10-20  Theodore Ts'o  <tytso@valinux.com>
+
+       * feature.c, ls.c (list_super2): Add support for the
+               meta_blockgroup filesystem format.
+
 2002-10-15    <tytso@snap.thunk.org>
 
        * ls.c (print_mntopts, list_super2): Print any default mount
index 2586727..83cf6f9 100644 (file)
@@ -49,6 +49,8 @@ static struct feature feature_list[] = {
                        "needs_recovery" },
        {       E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
                        "journal_dev" },
+       {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
+                       "meta_bg" },
        {       0, 0, 0 },
 };
 
index c18e0ff..cab3ae1 100644 (file)
@@ -202,6 +202,9 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
        fprintf(f, "Inodes per group:         %u\n", sb->s_inodes_per_group);
        fprintf(f, "Inode blocks per group:   %u\n", inode_blocks_per_group);
        tm = sb->s_mtime;
+       if (sb->s_first_meta_bg)
+               fprintf(f, "First meta block group:   %u\n",
+                       sb->s_first_meta_bg);
        fprintf(f, "Last mount time:          %s", ctime(&tm));
        tm = sb->s_wtime;
        fprintf(f, "Last write time:          %s", ctime(&tm));
index a12a608..7d085e1 100644 (file)
@@ -1,3 +1,10 @@
+2002-10-20  Theodore Ts'o  <tytso@valinux.com>
+
+       * closefs.c (ext2fs_flush, write_bgdesc), ext2_fs.h, ext2fs.h,
+       openfs.c (ext2fs_descriptor_block_loc, ext2fs_open), initialize.c
+       (ext2fs_initialize), swapfs.c (ext2fs_swap_super): Add support for
+       the meta_blockgroup filesystem format.
+
 2002-10-15    <tytso@snap.thunk.org>
 
        * ext2_fs.h: Add new field in superblock for default mount options.
index f52c343..dcf244b 100644 (file)
@@ -113,9 +113,71 @@ void ext2fs_update_dynamic_rev(ext2_filsys fs)
        /* other fields should be left alone */
 }
 
+/*
+ * This writes out the block group descriptors the original,
+ * old-fashioned way.
+ */
+static errcode_t write_bgdesc(ext2_filsys fs, dgrp_t group, blk_t group_block,
+                             struct ext2_group_desc *group_shadow)
+{
+       errcode_t       retval;
+       char            *group_ptr = (char *) group_shadow;
+       int             j;
+       int             has_super = ext2fs_bg_has_super(fs, group);
+       dgrp_t          meta_bg_size, meta_bg;
+       blk_t           blk;
+
+       meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
+       meta_bg = group / meta_bg_size;
+       if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
+           (meta_bg < fs->super->s_first_meta_bg)) {
+               if (!has_super)
+                       return 0;
+               for (j=0; j < fs->desc_blocks; j++) {
+                       retval = io_channel_write_blk(fs->io,
+                                                     group_block+1+j, 1,
+                                                     group_ptr);
+                       if (retval)
+                               return retval;
+                       group_ptr += fs->blocksize;
+               }
+       } else {
+               if (has_super)
+                       group_block++;
+               if (((group % meta_bg_size) == 0) ||
+                   ((group % meta_bg_size) == 1) ||
+                   ((group % meta_bg_size) == (meta_bg_size-1))) {
+                       return io_channel_write_blk(fs->io, group_block,
+                               1, group_ptr + (meta_bg*fs->blocksize));
+               }
+       }
+       return 0;
+}
+
+
+static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
+                                   blk_t group_block,
+                                   struct ext2_super_block *super_shadow)
+{
+       dgrp_t  sgrp = group;
+       
+       if (sgrp > ((1 << 16) - 1))
+               sgrp = (1 << 16) - 1;
+#ifdef EXT2FS_ENABLE_SWAPFS
+       if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+               super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
+       else
+#endif
+               fs->super->s_block_group_nr = sgrp;
+
+       return io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE, 
+                                   super_shadow);
+}
+
+
 errcode_t ext2fs_flush(ext2_filsys fs)
 {
-       dgrp_t          i,j,maxgroup,sgrp;
+       dgrp_t          i,j,maxgroup;
        blk_t           group_block;
        errcode_t       retval;
        char            *group_ptr;
@@ -204,36 +266,16 @@ errcode_t ext2fs_flush(ext2_filsys fs)
        maxgroup = (fs->flags & EXT2_FLAG_MASTER_SB_ONLY) ? 1 :
                fs->group_desc_count;
        for (i = 0; i < maxgroup; i++) {
-               if (!ext2fs_bg_has_super(fs, i))
-                       goto next_group;
-
-               sgrp = i;
-               if (sgrp > ((1 << 16) - 1))
-                       sgrp = (1 << 16) - 1;
-#ifdef EXT2FS_ENABLE_SWAPFS
-               if (fs->flags & EXT2_FLAG_SWAP_BYTES)
-                       super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
-               else
-#endif
-                       fs->super->s_block_group_nr = sgrp;
-
-               if (i !=0 ) {
-                       retval = io_channel_write_blk(fs->io, group_block,
-                                                     -SUPERBLOCK_SIZE,
-                                                     super_shadow);
+               if (i && ext2fs_bg_has_super(fs, i)) {
+                       retval = write_backup_super(fs, i, group_block,
+                                                   super_shadow);
                        if (retval)
                                goto errout;
                }
-               if (fs->flags & EXT2_FLAG_SUPER_ONLY)
-                       goto next_group;
-               group_ptr = (char *) group_shadow;
-               for (j=0; j < fs->desc_blocks; j++) {
-                       retval = io_channel_write_blk(fs->io,
-                                                     group_block+1+j, 1,
-                                                     group_ptr);
-                       if (retval)
+               if (!(fs->flags & EXT2_FLAG_SUPER_ONLY)) {
+                       if ((retval = write_bgdesc(fs, i, group_block, 
+                                                  group_shadow)))
                                goto errout;
-                       group_ptr += fs->blocksize;
                }
        next_group:
                group_block += EXT2_BLOCKS_PER_GROUP(fs->super);
index 56fabbf..2b11261 100644 (file)
@@ -439,7 +439,8 @@ struct ext2_super_block {
        __u8    s_reserved_char_pad;
        __u16   s_reserved_word_pad;
        __u32   s_default_mount_opts;
-       __u32   s_reserved[191];        /* Padding to the end of the block */
+       __u32   s_first_meta_bg;        /* First metablock group */
+       __u32   s_reserved[190];        /* Padding to the end of the block */
 };
 
 /*
@@ -488,9 +489,10 @@ struct ext2_super_block {
 #define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
 #define EXT3_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Journal device */
+#define EXT2_FEATURE_INCOMPAT_META_BG          0x0010
 
 #define EXT2_FEATURE_COMPAT_SUPP       0
-#define EXT2_FEATURE_INCOMPAT_SUPP     EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_INCOMPAT_SUPP     (EXT2_FEATURE_INCOMPAT_FILETYPE)
 #define EXT2_FEATURE_RO_COMPAT_SUPP    (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
index 6f5bc47..992fc74 100644 (file)
@@ -432,10 +432,12 @@ typedef struct ext2_icount *ext2_icount_t;
 #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
                                         EXT2_FEATURE_INCOMPAT_COMPRESSION|\
                                         EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
+                                        EXT2_FEATURE_INCOMPAT_META_BG|\
                                         EXT3_FEATURE_INCOMPAT_RECOVER)
 #else
 #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
                                         EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
+                                        EXT2_FEATURE_INCOMPAT_META_BG|\
                                         EXT3_FEATURE_INCOMPAT_RECOVER)
 #endif
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
@@ -808,6 +810,8 @@ extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size,
 extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
                             int block_size, io_manager manager,
                             ext2_filsys *ret_fs);
+extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, 
+                                        dgrp_t i);
 
 /* get_pathname.c */
 extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
index f132416..d9be945 100644 (file)
@@ -67,6 +67,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        int             i, j;
        blk_t           numblocks;
        char            *buf;
+       int             meta_bg_size, meta_bg, has_super;
 
        if (!param || !param->s_blocks_count)
                return EXT2_ET_INVALID_ARGUMENT;
@@ -113,6 +114,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        set_field(s_feature_compat, 0);
        set_field(s_feature_incompat, 0);
        set_field(s_feature_ro_compat, 0);
+       set_field(s_first_meta_bg, 0);
        if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)
                return EXT2_ET_UNSUPP_FEATURE;
        if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)
@@ -301,11 +303,35 @@ retry:
                } else
                        numblocks = fs->super->s_blocks_per_group;
 
-               if (ext2fs_bg_has_super(fs, i)) {
-                       for (j=0; j < fs->desc_blocks+1; j++)
+               has_super = ext2fs_bg_has_super(fs, i);
+
+               if (has_super) {
+                       ext2fs_mark_block_bitmap(fs->block_map, group_block);
+                       numblocks--;
+               }
+               meta_bg_size = (fs->blocksize /
+                               sizeof (struct ext2_group_desc));
+               meta_bg = i / meta_bg_size;
+
+               if (!(fs->super->s_feature_incompat &
+                     EXT2_FEATURE_INCOMPAT_META_BG) ||
+                   (meta_bg < fs->super->s_first_meta_bg)) {
+                       if (has_super) {
+                               for (j=0; j < fs->desc_blocks; j++)
+                                       ext2fs_mark_block_bitmap(fs->block_map,
+                                                        group_block + j + 1);
+                               numblocks -= fs->desc_blocks;
+                       }
+               } else {
+                       if (has_super)
+                               has_super = 1;
+                       if (((i % meta_bg_size) == 0) ||
+                           ((i % meta_bg_size) == 1) ||
+                           ((i % meta_bg_size) == (meta_bg_size-1))) {
                                ext2fs_mark_block_bitmap(fs->block_map,
-                                                        group_block + j);
-                       numblocks -= 1 + fs->desc_blocks;
+                                        group_block + has_super);
+                               numblocks--;
+                       }
                }
                
                numblocks -= 2 + fs->inode_blocks_per_group;
index d9021d6..4dcae98 100644 (file)
 #endif
 
 #include "ext2_fs.h"
+
+
 #include "ext2fs.h"
 #include "e2image.h"
 
+blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
+{
+       int     bg;
+       int     has_super = 0;
+
+       if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
+           (i < fs->super->s_first_meta_bg))
+               return (group_block + i + 1);
+
+       bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
+       if (ext2fs_bg_has_super(fs, bg))
+               has_super = 1;
+       return (fs->super->s_first_data_block + has_super + 
+               (bg * fs->super->s_blocks_per_group));
+}
+
 /*
  *  Note: if superblock is non-zero, block-size must also be non-zero.
  *     Superblock and block_size can be zero to use the default size.
@@ -44,7 +62,7 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
        ext2_filsys     fs;
        errcode_t       retval;
        int             i, j, groups_per_block, blocks_per_group;
-       blk_t           group_block;
+       blk_t           group_block, blk;
        char            *dest;
        struct ext2_group_desc *gdp;
        
@@ -214,18 +232,17 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
        if (retval)
                goto cleanup;
        if (!group_block)
-               group_block = fs->super->s_first_data_block + 1;
+               group_block = fs->super->s_first_data_block;
        dest = (char *) fs->group_desc;
+       groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
        for (i=0 ; i < fs->desc_blocks; i++) {
-               retval = io_channel_read_blk(fs->io, group_block, 1, dest);
+               blk = ext2fs_descriptor_block_loc(fs, group_block, i);
+               retval = io_channel_read_blk(fs->io, blk, 1, dest);
                if (retval)
                        goto cleanup;
-               group_block++;
 #ifdef EXT2FS_ENABLE_SWAPFS
                if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
                        gdp = (struct ext2_group_desc *) dest;
-                       groups_per_block = fs->blocksize /
-                               sizeof(struct ext2_group_desc);
                        for (j=0; j < groups_per_block; j++)
                                ext2fs_swap_group_desc(gdp++);
                }
index 14165cb..e375c63 100644 (file)
@@ -57,6 +57,7 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
        sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
        sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
        sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
+       sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
        for (i=0; i < 4; i++)
                sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
 }
index 038cb71..63f1d98 100644 (file)
@@ -1,3 +1,9 @@
+2002-10-20  Theodore Ts'o  <tytso@valinux.com>
+
+       * dumpe2fs.c (list_desc), mke2fs.c (PRS), e2image.c
+               (mark_table_blocks): Add support for the meta_blockgroup
+               filesystem format.
+
 2002-10-15    <tytso@snap.thunk.org>
 
        * tune2fs.8.in, tune2fs.c (update_mntopts, main): Add new option
index 14931b0..b4c63a7 100644 (file)
@@ -90,6 +90,7 @@ static void list_desc (ext2_filsys fs)
        char * inode_bitmap = fs->inode_map->bitmap;
        int inode_blocks_per_group;
        int group_desc_blocks;
+       int meta_bg, meta_bg_size, has_super;
 
        inode_blocks_per_group = ((fs->super->s_inodes_per_group *
                                   EXT2_INODE_SIZE(fs->super)) +
@@ -111,14 +112,35 @@ static void list_desc (ext2_filsys fs)
                printf (_("Group %lu: (Blocks "), i);
                printf(range_format, group_blk, next_blk - 1);
                fputs(")\n", stdout);
-               if (ext2fs_bg_has_super (fs, i)) {
-                       printf (_("  %s Superblock at "),
+               has_super = ext2fs_bg_has_super(fs, i);
+               if (has_super) {
+                       printf (_("  %s superblock at "),
                                i == 0 ? _("Primary") : _("Backup"));
                        printf(num_format, group_blk);
-                       printf(_(",  Group Descriptors at "));
+               }
+               meta_bg_size = (fs->blocksize /
+                               sizeof (struct ext2_group_desc));
+               meta_bg = i / meta_bg_size;
+               if (!(fs->super->s_feature_incompat &
+                     EXT2_FEATURE_INCOMPAT_META_BG) ||
+                   (meta_bg < fs->super->s_first_meta_bg)) {
+                       fputc(has_super ? ',' : ' ', stdout);
+                       printf(_(" Group descriptors at "));
                        printf(range_format, group_blk+1,
                               group_blk + group_desc_blocks);
                        fputc('\n', stdout);
+               } else {
+                       if (has_super)
+                               has_super = 1;
+                       if (((i % meta_bg_size) == 0) ||
+                           ((i % meta_bg_size) == 1) ||
+                           ((i % meta_bg_size) == (meta_bg_size-1))) {
+                               fputc(has_super ? ',' : ' ', stdout);
+                               printf(_(" Group descriptor at "));
+                               printf(num_format, group_blk + has_super);
+                               fputc('\n', stdout);
+                       } else if (has_super)
+                               fputc('\n', stdout);
                }
                fputs(_("  Block bitmap at "), stdout);
                printf(num_format, fs->group_desc[i].bg_block_bitmap);
index 1996311..34b1e2c 100644 (file)
@@ -240,7 +240,7 @@ static void mark_table_blocks(ext2_filsys fs)
         */
        for (j = 0; j < fs->desc_blocks; j++) {
                ext2fs_mark_block_bitmap(meta_block_map,
-                                        block + j + 1);
+                        ext2fs_descriptor_block_loc(fs, block, j));
        }
 
        for (i = 0; i < fs->group_desc_count; i++) {
index c37eecc..1c83d9f 100644 (file)
@@ -780,7 +780,8 @@ static __u32 ok_features[3] = {
        EXT3_FEATURE_COMPAT_HAS_JOURNAL |
                EXT2_FEATURE_COMPAT_DIR_INDEX,  /* Compat */
        EXT2_FEATURE_INCOMPAT_FILETYPE|         /* Incompat */
-               EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
+               EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
+               EXT2_FEATURE_INCOMPAT_META_BG,
        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
 };
 
@@ -1164,6 +1165,12 @@ static void PRS(int argc, char *argv[])
            !journal_size)
                journal_size = -1;
 
+       /* Set first meta blockgroup via an environment variable */
+       /* (this is mostly for debugging purposes) */
+       if ((param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
+           ((tmp = getenv("MKE2FS_FIRST_META_BG"))))
+               param.s_first_meta_bg = atoi(tmp);
+
        set_fs_defaults(fs_type, &param, blocksize, &inode_ratio);
 
        if (param.s_blocks_per_group) {