allow larger block group descriptors

Signed-off-by: Alexandre Ratchov <[EMAIL PROTECTED]>              

Index: e2fsprogs-1.39/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/ext2fs.h     2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/ext2fs.h  2006-09-22 15:53:09.000000000 +0200
@@ -213,6 +213,7 @@ struct struct_ext2_filsys {
        char *                          device_name;
        struct ext2_super_block *       super;
        unsigned int                    blocksize;
+       unsigned int                    desc_size;
        int                             fragsize;
        dgrp_t                          group_desc_count;
        unsigned long                   desc_blocks;
Index: e2fsprogs-1.39/lib/ext2fs/swapfs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/swapfs.c     2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/swapfs.c  2006-09-22 15:53:09.000000000 +0200
@@ -63,6 +63,7 @@ void ext2fs_swap_super(struct ext2_super
        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_desc_size = ext2fs_swab16(sb->s_desc_size);
        sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
        sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
        sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
Index: e2fsprogs-1.39/misc/mke2fs.c
===================================================================
--- e2fsprogs-1.39.orig/misc/mke2fs.c   2006-09-22 15:52:50.000000000 +0200
+++ e2fsprogs-1.39/misc/mke2fs.c        2006-09-22 15:53:09.000000000 +0200
@@ -94,7 +94,7 @@ int linux_version_code = 0;
 static void usage(void)
 {
        fprintf(stderr, _("Usage: %s [-c|-t|-l filename] [-b block-size] "
-       "[-f fragment-size]\n\t[-i bytes-per-inode] [-I inode-size] "
+       "[-f fragment-size]\n\t[-i bytes-per-inode] [-I inode-size] [-D 
descriptor-size]"
        "[-j] [-J journal-options]\n"
        "\t[-N number-of-inodes] [-m reserved-blocks-percentage] "
        "[-o creator-os]\n\t[-g blocks-per-group] [-L volume-label] "
@@ -680,6 +680,8 @@ static void show_stats(ext2_filsys fs)
                s->s_log_block_size);
        printf(_("Fragment size=%u (log=%u)\n"), fs->fragsize,
                s->s_log_frag_size);
+       if (s->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               printf(_("Descriptor size=%u\n"), fs->desc_size);
        printf(_("%u inodes, %llu blocks\n"), s->s_inodes_count,
               EXT2_BLOCKS_COUNT(s));
        printf(_("%llu blocks (%2.2f%%) reserved for the super user\n"),
@@ -689,7 +691,7 @@ static void show_stats(ext2_filsys fs)
        if (s->s_reserved_gdt_blocks)
                printf(_("Maximum filesystem blocks=%llu\n"),
                       (blk_t)((s->s_reserved_gdt_blocks + fs->desc_blocks) *
-                      (fs->blocksize / sizeof(struct ext2_group_desc)) *
+                      (fs->blocksize / fs->desc_size) *
                       s->s_blocks_per_group));
        if (fs->group_desc_count > 1)
                printf(_("%u block groups\n"), fs->group_desc_count);
@@ -822,7 +824,7 @@ static void parse_extended_opts(struct e
                        bpg = param->s_blocks_per_group;
                        if (!bpg)
                                bpg = blocksize * 8;
-                       gdpb = blocksize / sizeof(struct ext2_group_desc);
+                       gdpb = blocksize / EXT2_DESC_SIZE(param);
                        group_desc_count = 
                                ext2fs_div_ceil(EXT2_BLOCKS_COUNT(param), bpg);
                        desc_blocks = (group_desc_count +
@@ -861,7 +863,8 @@ static __u32 ok_features[3] = {
                EXT2_FEATURE_COMPAT_LAZY_BG,    /* Compat */
        EXT2_FEATURE_INCOMPAT_FILETYPE|         /* Incompat */
                EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
-               EXT2_FEATURE_INCOMPAT_META_BG,
+               EXT2_FEATURE_INCOMPAT_META_BG|
+               EXT4_FEATURE_INCOMPAT_64BIT,
        EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
 };
 
@@ -896,6 +899,7 @@ static void PRS(int argc, char *argv[])
        int             blocksize = 0;
        int             inode_ratio = 0;
        int             inode_size = 0;
+       int             desc_size = 0;
        double          reserved_ratio = 5.0;
        int             sector_size = 0;
        int             show_version_only = 0;
@@ -971,7 +975,7 @@ static void PRS(int argc, char *argv[])
        }
 
        while ((c = getopt (argc, argv,
-                   "b:cf:g:i:jl:m:no:qr:s:tvE:FI:J:L:M:N:O:R:ST:V")) != EOF) {
+                   "b:cf:g:i:jl:m:no:qr:s:tvD:E:FI:J:L:M:N:O:R:ST:V")) != EOF) 
{
                switch (c) {
                case 'b':
                        blocksize = strtol(optarg, &tmp, 0);
@@ -1088,6 +1092,14 @@ static void PRS(int argc, char *argv[])
                                exit(1);
                        }
                        break;
+               case 'D':
+                       desc_size = strtoul(optarg, &tmp, 0);
+                       if (*tmp) {
+                               com_err(program_name, 0,
+                                       _("invalid descriptor size - %s"), 
optarg);
+                               exit(1);
+                       }
+                       break;
                case 'v':
                        verbose = 1;
                        break;
@@ -1252,7 +1264,10 @@ static void PRS(int argc, char *argv[])
                                exit(1);
                        }
                        if (dev_size >> 31) {
-                               fs_param.s_feature_incompat |= 
EXT4_FEATURE_INCOMPAT_64BIT;
+                               fs_param.s_feature_incompat |= 
+                                       EXT4_FEATURE_INCOMPAT_64BIT;
+                               fs_param.s_desc_size = 
+                                       EXT2_MIN_DESC_SIZE_64BIT;
                        }
                        EXT2_BLOCKS_COUNT_SET(&fs_param, dev_size);
                        if (sys_page_size > EXT2_BLOCK_SIZE(&fs_param))
@@ -1438,6 +1453,26 @@ static void PRS(int argc, char *argv[])
                                inode_size);
                fs_param.s_inode_size = inode_size;
        }
+       
+       if (desc_size) {
+               unsigned desc_size_min;
+               
+               if (fs_param.s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+                       desc_size_min = EXT2_MIN_DESC_SIZE_64BIT;
+               else
+                       desc_size_min = EXT2_MIN_DESC_SIZE;
+               
+               if (desc_size < desc_size_min ||
+                   desc_size > EXT2_MAX_DESC_SIZE ||
+                   desc_size & (desc_size - 1)) {
+                       com_err(program_name, 0,
+                           _("invalid descriptor size %d (min %d/max %d)"),
+                           desc_size, EXT2_MIN_DESC_SIZE,
+                           EXT2_MAX_DESC_SIZE);
+                       exit(1);
+               }
+               fs_param.s_desc_size = desc_size;
+       }
 
        /* Make sure number of inodes specified will fit in 32 bits */
        if (num_inodes == 0) {
Index: e2fsprogs-1.39/lib/ext2fs/openfs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/openfs.c     2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/openfs.c  2006-09-22 15:53:09.000000000 +0200
@@ -39,7 +39,7 @@ blk_t ext2fs_descriptor_block_loc(ext2_f
            (i < fs->super->s_first_meta_bg))
                return (group_block + i + 1);
 
-       bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
+       bg = (fs->blocksize / fs->desc_size) * i;
        if (ext2fs_bg_has_super(fs, bg))
                has_super = 1;
        ret_blk = EXT2_GROUP_BASE(fs->super, bg) + has_super;
@@ -87,8 +87,10 @@ errcode_t ext2fs_open2(const char *name,
        unsigned long   i;
        int             j, groups_per_block, blocks_per_group, io_flags;
        blk_t           group_block, blk;
-       char            *dest, *cp;
+       char            *cp;
        struct ext2_group_desc *gdp;
+       char            shadow_block[EXT2_MAX_BLOCK_SIZE];
+       size_t          desc_buflen;
        
        EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
 
@@ -231,6 +233,13 @@ errcode_t ext2fs_open2(const char *name,
                        goto cleanup;
                }
        }
+       
+       if (fs->super->s_feature_incompat & 
+           EXT4_FEATURE_INCOMPAT_64BIT) {
+               fs->desc_size = EXT2_DESC_SIZE(fs->super);
+       } else {
+               fs->desc_size = EXT2_MIN_DESC_SIZE;
+       }
        /*
         * Set the blocksize to the filesystem's blocksize.
         */
@@ -262,27 +271,32 @@ errcode_t ext2fs_open2(const char *name,
                                               blocks_per_group);
        fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
                                          EXT2_DESC_PER_BLOCK(fs->super));
-       retval = ext2fs_get_mem(fs->desc_blocks * fs->blocksize,
-                               &fs->group_desc);
+
+       desc_buflen = fs->desc_blocks * EXT2_DESC_PER_BLOCK(fs->super) *
+               sizeof(struct ext2_group_desc);
+       retval = ext2fs_get_mem(desc_buflen, &fs->group_desc);
        if (retval)
                goto cleanup;
+       memset(fs->group_desc, 0, desc_buflen);
+
        if (!group_block)
                group_block = fs->super->s_first_data_block;
-       dest = (char *) fs->group_desc;
-       groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
+       gdp = fs->group_desc;
+       groups_per_block = fs->blocksize / fs->desc_size;
        for (i=0 ; i < fs->desc_blocks; i++) {
                blk = ext2fs_descriptor_block_loc(fs, group_block, i);
-               retval = io_channel_read_blk(fs->io, blk, 1, dest);
+               retval = io_channel_read_blk(fs->io, blk, 1, shadow_block);
                if (retval)
                        goto cleanup;
+               
+               for (j=0; j < groups_per_block; j++) {
+                       memcpy(gdp, shadow_block + j * fs->desc_size, 
fs->desc_size);
 #ifdef EXT2FS_ENABLE_SWAPFS
-               if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-                       gdp = (struct ext2_group_desc *) dest;
-                       for (j=0; j < groups_per_block; j++)
-                               ext2fs_swap_group_desc(gdp++);
-               }
+                       if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+                                       ext2fs_swap_group_desc(gdp);
 #endif
-               dest += fs->blocksize;
+                       gdp++;
+               }
        }
 
        *ret_fs = fs;
Index: e2fsprogs-1.39/lib/ext2fs/closefs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/closefs.c    2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/closefs.c 2006-09-22 15:53:09.000000000 +0200
@@ -80,7 +80,7 @@ int ext2fs_super_and_bgd_loc(ext2_filsys
                super_blk = group_block;
                numblocks--;
        }
-       meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
+       meta_bg_size = (fs->blocksize / fs->desc_size);
        meta_bg = group / meta_bg_size;
 
        if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
@@ -204,14 +204,14 @@ static errcode_t write_backup_super(ext2
 
 errcode_t ext2fs_flush(ext2_filsys fs)
 {
-       dgrp_t          i,j;
+       dgrp_t          i;
        errcode_t       retval;
        unsigned long   fs_state;
        struct ext2_super_block *super_shadow = 0;
-       struct ext2_group_desc *group_shadow = 0;
-       struct ext2_group_desc *s, *t;
-       char    *group_ptr;
-       int     old_desc_blocks;
+       struct ext2_group_desc *gd;
+       char *desc_shadow = NULL;
+       size_t desc_buflen;
+       int old_desc_blocks;
        
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -219,33 +219,36 @@ errcode_t ext2fs_flush(ext2_filsys fs)
 
        fs->super->s_wtime = fs->now ? fs->now : time(NULL);
        fs->super->s_block_group_nr = 0;
+
+       desc_buflen = fs->desc_blocks * fs->blocksize;
+       retval = ext2fs_get_mem(desc_buflen, &desc_shadow);
+       if (retval)
+               goto errout;
+       memset(desc_shadow, 0, desc_buflen);
+
+       /*
+        * copy the group descriptors adjusting size to the
+        * on-disk size. If needed, also bswap them on the fly
+        */
+       for (i = 0; i < fs->group_desc_count; i++) {
+               gd = (struct ext2_group_desc *)(desc_shadow + i * 
fs->desc_size);
+               memcpy(gd, &fs->group_desc[i], fs->desc_size);
+#ifdef EXT2FS_ENABLE_SWAPFS
+               if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+                       ext2fs_swap_group_desc(gd);
+#endif
+       }
+
 #ifdef EXT2FS_ENABLE_SWAPFS
        if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-               retval = EXT2_ET_NO_MEMORY;
                retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
                if (retval)
                        goto errout;
-               retval = ext2fs_get_mem((size_t)(fs->blocksize *
-                                                fs->desc_blocks),
-                                       &group_shadow);
-               if (retval)
-                       goto errout;
-               memset(group_shadow, 0, (size_t) fs->blocksize *
-                      fs->desc_blocks);
-
-               /* swap the group descriptors */
-               for (j=0, s=fs->group_desc, t=group_shadow;
-                    j < fs->group_desc_count; j++, t++, s++) {
-                       *t = *s;
-                       ext2fs_swap_group_desc(t);
-               }
        } else {
                super_shadow = fs->super;
-               group_shadow = fs->group_desc;
        }
 #else
        super_shadow = fs->super;
-       group_shadow = fs->group_desc;
 #endif
        
        /*
@@ -273,7 +276,6 @@ errcode_t ext2fs_flush(ext2_filsys fs)
         * Write out the master group descriptors, and the backup
         * superblocks and group descriptors.
         */
-       group_ptr = (char *) group_shadow;
        if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
                old_desc_blocks = fs->super->s_first_meta_bg;
        else
@@ -297,13 +299,14 @@ errcode_t ext2fs_flush(ext2_filsys fs)
                if ((old_desc_blk) && 
                    (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) || (i == 0))) {
                        retval = io_channel_write_blk(fs->io,
-                             old_desc_blk, old_desc_blocks, group_ptr);
+                             old_desc_blk, old_desc_blocks, desc_shadow);
                        if (retval)
                                goto errout;
                }
                if (new_desc_blk) {
-                       retval = io_channel_write_blk(fs->io, new_desc_blk,
-                               1, group_ptr + (meta_bg*fs->blocksize));
+                       retval = io_channel_write_blk(
+                               fs->io, new_desc_blk, 1, 
+                               desc_shadow + meta_bg * fs->blocksize);
                        if (retval)
                                goto errout;
                }
@@ -352,8 +355,8 @@ errout:
        if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
                if (super_shadow)
                        ext2fs_free_mem(&super_shadow);
-               if (group_shadow)
-                       ext2fs_free_mem(&group_shadow);
+               if (desc_shadow)
+                       ext2fs_free_mem(&desc_shadow);
        }
        return retval;
 }
Index: e2fsprogs-1.39/lib/ext2fs/ext2_fs.h
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/ext2_fs.h    2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/ext2_fs.h 2006-09-22 18:23:10.000000000 +0200
@@ -225,6 +225,12 @@ struct ext2_dx_countlimit {
 /*
  * Macro-instructions used to manage group descriptors
  */
+#define EXT2_MIN_DESC_SIZE             32
+#define EXT2_MIN_DESC_SIZE_64BIT       64
+#define EXT2_MAX_DESC_SIZE             EXT2_MIN_BLOCK_SIZE
+#define EXT2_DESC_SIZE(s)                                                \
+       ((EXT2_SB(s)->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) ? \
+        EXT2_SB(s)->s_desc_size : EXT2_MIN_DESC_SIZE)
 #define EXT2_BLOCKS_PER_GROUP(s)       ((__u64)EXT2_SB(s)->s_blocks_per_group)
 #define EXT2_INODES_PER_GROUP(s)       (EXT2_SB(s)->s_inodes_per_group)
 #define EXT2_INODES_PER_BLOCK(s)       (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
@@ -235,7 +241,7 @@ struct ext2_dx_countlimit {
 #define EXT2_DESC_PER_BLOCK(s)         (EXT2_SB(s)->s_desc_per_block)
 #define EXT2_DESC_PER_BLOCK_BITS(s)    (EXT2_SB(s)->s_desc_per_block_bits)
 #else
-#define EXT2_DESC_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / sizeof (struct 
ext2_group_desc))
+#define EXT2_DESC_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
 #endif
 
 /*
@@ -556,7 +562,7 @@ struct ext2_super_block {
        __u32   s_hash_seed[4];         /* HTREE hash seed */
        __u8    s_def_hash_version;     /* Default hash version to use */
        __u8    s_jnl_backup_type;      /* Default type of journal backup */
-       __u16   s_reserved_word_pad;
+       __u16   s_desc_size;            /* size of group descriptor */
        __u32   s_default_mount_opts;
        __u32   s_first_meta_bg;        /* First metablock group */
        __u32   s_mkfs_time;            /* When the filesystem was created */
Index: e2fsprogs-1.39/lib/ext2fs/initialize.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/initialize.c 2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/initialize.c      2006-09-22 15:53:09.000000000 
+0200
@@ -67,7 +67,7 @@ static unsigned int calc_reserved_gdt_bl
 {
        struct ext2_super_block *sb = fs->super;
        unsigned long bpg = sb->s_blocks_per_group;
-       unsigned int gdpb = fs->blocksize / sizeof(struct ext2_group_desc);
+       unsigned int gdpb = fs->blocksize / fs->desc_size;
        unsigned long max_blocks = 0xffffffff;
        unsigned long rsv_groups;
        unsigned int rsv_gdb;
@@ -106,6 +106,7 @@ errcode_t ext2fs_initialize(const char *
        int             io_flags;
        char            *buf;
        blk_t           inodes;
+       size_t          desc_buflen;
 
        if (!param || !EXT2_BLOCKS_COUNT(param))
                return EXT2_ET_INVALID_ARGUMENT;
@@ -149,6 +150,7 @@ errcode_t ext2fs_initialize(const char *
 
        set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */
        set_field(s_log_frag_size, 0); /* default fragsize: 1024 bytes */
+       set_field(s_desc_size, 0);
        set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
        set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
        set_field(s_errors, EXT2_ERRORS_DEFAULT);
@@ -178,6 +180,7 @@ errcode_t ext2fs_initialize(const char *
 
        fs->blocksize = EXT2_BLOCK_SIZE(super);
        fs->fragsize = EXT2_FRAG_SIZE(super);
+       fs->desc_size = EXT2_DESC_SIZE(super);
        frags_per_block = fs->blocksize / fs->fragsize;
 
        set_field(s_blocks_per_group, fs->blocksize * 8);
@@ -350,12 +353,12 @@ ipg_retry:
 
        ext2fs_free_mem(&buf);
 
-       retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
-                               &fs->group_desc);
+       desc_buflen = fs->desc_blocks * EXT2_DESC_PER_BLOCK(fs->super) * 
+               sizeof(struct ext2_group_desc);
+       retval = ext2fs_get_mem(desc_buflen, &fs->group_desc);
        if (retval)
                goto cleanup;
-
-       memset(fs->group_desc, 0, (size_t) fs->desc_blocks * fs->blocksize);
+       memset(fs->group_desc, 0, desc_buflen);
 
        /*
         * Reserve the superblock and group descriptors for each
Index: e2fsprogs-1.39/resize/resize2fs.c
===================================================================
--- e2fsprogs-1.39.orig/resize/resize2fs.c      2006-09-22 15:52:50.000000000 
+0200
+++ e2fsprogs-1.39/resize/resize2fs.c   2006-09-22 15:53:09.000000000 +0200
@@ -187,6 +187,7 @@ errcode_t adjust_fs_info(ext2_filsys fs,
        unsigned long   i, j, old_desc_blocks, max_group;
        unsigned int    meta_bg, meta_bg_size;
        int             has_super;
+       size_t          odesc_buflen, ndesc_buflen;
        __u64           new_inodes;     /* u64 to check for overflow */
 
        EXT2_BLOCKS_COUNT_SET(fs->super, new_size);
@@ -276,17 +277,20 @@ retry:
         * Reallocate the group descriptors as necessary.
         */
        if (old_fs->desc_blocks != fs->desc_blocks) {
-               retval = ext2fs_resize_mem(old_fs->desc_blocks *
-                                          fs->blocksize,
-                                          fs->desc_blocks * fs->blocksize,
+               odesc_buflen = old_fs->desc_blocks * 
+                       EXT2_DESC_PER_BLOCK(old_fs->super) * 
+                       sizeof(struct ext2_group_desc);
+               ndesc_buflen = fs->desc_blocks * 
+                       EXT2_DESC_PER_BLOCK(fs->super) * 
+                       sizeof(struct ext2_group_desc);
+               retval = ext2fs_resize_mem(odesc_buflen, ndesc_buflen, 
                                           &fs->group_desc);
                if (retval)
                        goto errout;
                if (fs->desc_blocks > old_fs->desc_blocks) 
-                       memset((char *) fs->group_desc + 
-                              (old_fs->desc_blocks * fs->blocksize), 0,
-                              (fs->desc_blocks - old_fs->desc_blocks) *
-                              fs->blocksize);
+                       memset(&fs->group_desc[old_fs->group_desc_count], 0,
+                              (fs->group_desc_count - 
old_fs->group_desc_count) *
+                              sizeof(struct ext2_group_desc));
        }
 
        /*
@@ -365,8 +369,7 @@ retry:
                        fs->super->s_reserved_gdt_blocks;
        for (i = old_fs->group_desc_count;
             i < fs->group_desc_count; i++) {
-               memset(&fs->group_desc[i], 0,
-                      sizeof(struct ext2_group_desc));
+               memset(&fs->group_desc[i], 0, sizeof(struct ext2_group_desc));
                adjblocks = 0;
 
                if (i == fs->group_desc_count-1) {
@@ -383,8 +386,7 @@ retry:
                        ext2fs_mark_block_bitmap(fs->block_map, group_block);
                        adjblocks++;
                }
-               meta_bg_size = (fs->blocksize /
-                               sizeof (struct ext2_group_desc));
+               meta_bg_size = fs->blocksize / fs->desc_size;
                meta_bg = i / meta_bg_size;
                if (!(fs->super->s_feature_incompat &
                      EXT2_FEATURE_INCOMPAT_META_BG) ||
@@ -550,7 +552,7 @@ static errcode_t mark_table_blocks(ext2_
        unsigned long           meta_bg_size;
        unsigned int            old_desc_blocks;
 
-       meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
+       meta_bg_size = fs->blocksize / fs->desc_size;
        if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
                old_desc_blocks = fs->super->s_first_meta_bg;
        else
@@ -717,7 +719,7 @@ static errcode_t blocks_to_move(ext2_res
         * If we're increasing the number of descriptor blocks, life
         * gets interesting....  
         */
-       meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
+       meta_bg_size = fs->blocksize / fs->desc_size;
        for (i = 0; i < max_groups; i++) {
                has_super = ext2fs_bg_has_super(fs, i);
                if (has_super)
Index: e2fsprogs-1.39/lib/ext2fs/dupfs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/dupfs.c      2006-09-22 15:08:12.000000000 
+0200
+++ e2fsprogs-1.39/lib/ext2fs/dupfs.c   2006-09-22 15:53:09.000000000 +0200
@@ -23,6 +23,7 @@ errcode_t ext2fs_dup_handle(ext2_filsys 
 {
        ext2_filsys     fs;
        errcode_t       retval;
+       size_t          desc_buflen;
 
        EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS);
        
@@ -59,12 +60,13 @@ errcode_t ext2fs_dup_handle(ext2_filsys 
                goto errout;
        memcpy(fs->orig_super, src->orig_super, SUPERBLOCK_SIZE);
 
-       retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
-                               &fs->group_desc);
+
+       desc_buflen = fs->desc_blocks * EXT2_DESC_PER_BLOCK(fs->super) * 
+               sizeof(struct ext2_group_desc);
+       retval = ext2fs_get_mem(desc_buflen, &fs->group_desc);
        if (retval)
                goto errout;
-       memcpy(fs->group_desc, src->group_desc,
-              (size_t) fs->desc_blocks * fs->blocksize);
+       memcpy(fs->group_desc, src->group_desc, desc_buflen);
 
        if (src->inode_map) {
                retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map);
-
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to