[rfc, patch 1/3] larger block group descriptors

Alexandre Ratchov <[email protected]>
Newsgroups gmane.comp.file-systems.ext2.devel
Message-ID <[email protected]>
make linux-2.6.16.19 use variable length block group descriptors.


Index: linux-2.6.16.19/include/linux/ext3_fs.h
===================================================================
--- linux-2.6.16.19.orig/include/linux/ext3_fs.h	2006-06-07 13:05:52.000000000 +0200
+++ linux-2.6.16.19/include/linux/ext3_fs.h	2006-06-07 13:20:26.000000000 +0200
@@ -20,7 +20,6 @@
 #include <linux/ext3_fs_i.h>
 #include <linux/ext3_fs_sb.h>
 
-
 struct statfs;
 
 /*
@@ -142,6 +141,9 @@ struct ext3_group_desc
 /*
  * Macro-instructions used to manage group descriptors
  */
+#define EXT3_MIN_DESC_SIZE		32
+#define	EXT3_MAX_DESC_SIZE		EXT3_MIN_BLOCK_SIZE
+#define EXT3_DESC_SIZE(s)		(EXT3_SB(s)->s_desc_size)
 #ifdef __KERNEL__
 # define EXT3_BLOCKS_PER_GROUP(s)	(EXT3_SB(s)->s_blocks_per_group)
 # define EXT3_DESC_PER_BLOCK(s)		(EXT3_SB(s)->s_desc_per_block)
@@ -149,7 +151,7 @@ struct ext3_group_desc
 # define EXT3_DESC_PER_BLOCK_BITS(s)	(EXT3_SB(s)->s_desc_per_block_bits)
 #else
 # define EXT3_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)
-# define EXT3_DESC_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc))
+# define EXT3_DESC_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / EXT3_DESC_SIZE(s))
 # define EXT3_INODES_PER_GROUP(s)	((s)->s_inodes_per_group)
 #endif
 
@@ -453,7 +455,7 @@ struct ext3_super_block {
 	 * things it doesn't understand...
 	 */
 	__le32	s_first_ino;		/* First non-reserved inode */
-	__le16   s_inode_size;		/* size of inode structure */
+	__le16  s_inode_size;		/* size of inode structure */
 	__le16	s_block_group_nr;	/* block group # of this superblock */
 	__le32	s_feature_compat;	/* compatible feature set */
 /*60*/	__le32	s_feature_incompat;	/* incompatible feature set */
@@ -479,7 +481,7 @@ struct ext3_super_block {
 	__le32	s_hash_seed[4];		/* HTREE hash seed */
 	__u8	s_def_hash_version;	/* Default hash version to use */
 	__u8	s_reserved_char_pad;
-	__u16	s_reserved_word_pad;
+	__le16  s_desc_size;		/* size of group descriptor */
 	__le32	s_default_mount_opts;
 	__le32	s_first_meta_bg; 	/* First metablock block group */
 	__u32	s_reserved[190];	/* Padding to the end of the block */
@@ -562,11 +564,13 @@ static inline struct ext3_inode_info *EX
 #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
 #define EXT3_FEATURE_INCOMPAT_META_BG		0x0010
+#define EXT3_FEATURE_INCOMPAT_DESC_SIZE		0x0020
 
 #define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
 #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
 					 EXT3_FEATURE_INCOMPAT_RECOVER| \
-					 EXT3_FEATURE_INCOMPAT_META_BG)
+					 EXT3_FEATURE_INCOMPAT_META_BG| \
+					 EXT3_FEATURE_INCOMPAT_DESC_SIZE)
 #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
 					 EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
 					 EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
Index: linux-2.6.16.19/fs/ext3/balloc.c
===================================================================
--- linux-2.6.16.19.orig/fs/ext3/balloc.c	2006-06-07 13:05:52.000000000 +0200
+++ linux-2.6.16.19/fs/ext3/balloc.c	2006-06-07 13:19:31.000000000 +0200
@@ -68,10 +68,12 @@ struct ext3_group_desc * ext3_get_group_
 		return NULL;
 	}
 
-	desc = (struct ext3_group_desc *) sbi->s_group_desc[group_desc]->b_data;
+	desc = (struct ext3_group_desc *)(
+		(__u8 *)sbi->s_group_desc[group_desc]->b_data +
+		offset * EXT3_DESC_SIZE(sb));
 	if (bh)
 		*bh = sbi->s_group_desc[group_desc];
-	return desc + offset;
+	return desc;
 }
 
 /*
Index: linux-2.6.16.19/fs/ext3/inode.c
===================================================================
--- linux-2.6.16.19.orig/fs/ext3/inode.c	2006-06-07 13:05:52.000000000 +0200
+++ linux-2.6.16.19/fs/ext3/inode.c	2006-06-07 13:19:31.000000000 +0200
@@ -2285,13 +2285,14 @@ static unsigned long ext3_get_inode_bloc
 		return 0;
 	}
 
-	gdp = (struct ext3_group_desc *) bh->b_data;
+	gdp = (struct ext3_group_desc *)((__u8 *)bh->b_data + 
+	    desc * EXT3_DESC_SIZE(sb));
 	/*
 	 * Figure out the offset within the block group inode table
 	 */
 	offset = ((ino - 1) % EXT3_INODES_PER_GROUP(sb)) *
 		EXT3_INODE_SIZE(sb);
-	block = le32_to_cpu(gdp[desc].bg_inode_table) +
+	block = le32_to_cpu(gdp->bg_inode_table) +
 		(offset >> EXT3_BLOCK_SIZE_BITS(sb));
 
 	iloc->block_group = block_group;
Index: linux-2.6.16.19/fs/ext3/super.c
===================================================================
--- linux-2.6.16.19.orig/fs/ext3/super.c	2006-06-07 13:05:52.000000000 +0200
+++ linux-2.6.16.19/fs/ext3/super.c	2006-06-07 13:19:31.000000000 +0200
@@ -1172,7 +1172,8 @@ static int ext3_check_descriptors (struc
 			return 0;
 		}
 		block += EXT3_BLOCKS_PER_GROUP(sb);
-		gdp++;
+		gdp = (struct ext3_group_desc *)
+		    ((__u8 *)gdp + EXT3_DESC_SIZE(sb));
 	}
 
 	sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
@@ -1524,7 +1525,18 @@ static int ext3_fill_super (struct super
 		       sbi->s_frag_size, blocksize);
 		goto failed_mount;
 	}
-	sbi->s_frags_per_block = 1;
+	sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
+	if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_DESC_SIZE)) {
+		if (sbi->s_desc_size < EXT3_MIN_DESC_SIZE ||
+		    sbi->s_desc_size > EXT3_MAX_DESC_SIZE ||
+		    sbi->s_desc_size & (sbi->s_desc_size - 1)) {
+			printk(KERN_ERR
+			       "EXT3-fs: unsupported descriptor size %d\n",
+			       sbi->s_desc_size);
+			goto failed_mount;
+		}
+	} else
+		sbi->s_desc_size = EXT3_MIN_DESC_SIZE;
 	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
 	sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
 	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
@@ -1535,7 +1547,7 @@ static int ext3_fill_super (struct super
 		goto cantfind_ext3;
 	sbi->s_itb_per_group = sbi->s_inodes_per_group /
 					sbi->s_inodes_per_block;
-	sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
+	sbi->s_desc_per_block = blocksize / EXT3_DESC_SIZE(sb);
 	sbi->s_sbh = bh;
 	sbi->s_mount_state = le16_to_cpu(es->s_state);
 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.