[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));