[patch 11/12] rfc: 2fsprogs update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



allow larger block group descriptors

Signed-off-by: Alexandre Ratchov <alexandre.ratchov@xxxxxxxx>              

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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux