Support large blocksize up to PAGESIZE (max 64KB) for ext2/3/4 From: Takashi Sato Orginally from Takashi Sato. Just rebase to 2.6.23-rc4. Compile tested. Will try it with Christoph Lameter's large block patch next. On July 7, 2006, sho wrote: > On Jun 29, 2006, Andreas wrote: > > On Jun 28, 2006 17:50 +0200, Johann Lombardi wrote: > > ext2/ext3_dir_entry_2 has a 16-bit entry(rec_len) and it > > would overflow > > with 64KB blocksize. This patch prevent from overflow by limiting > > rec_len to 65532. > > Having a max rec_len of 65532 is rather unfortunate, since the dir > > blocks always need to filled with dir entries. 65536 - 65532 = 4, > > and the minimum ext3_dir_entry size is 8 bytes. I would instead > > make this maybe 64 bytes less so that there is room for a filename > > in the "tail" dir_entry. > > The fix, adding dummy entry at the tail of a directory block, needs > to regenerate dummy entry when all of the entries are removed in > kernel. > While in e2fsprogs, e2fsck needs to do the same when destroyed by > some reason. Thus procedures get more complicated. > Then I updated the patch to limit rec_len to 65532(64K - 4). The > difference from the previous patch is that the end of a directory > block is changed to 65532(64K - 4) with 64K blocksize. > This is more simple and less tweaky. This necessarily makes 4-bytes > from the end of a directory block useless, but 4-bytes is negligible > compared to 64KB, who cares? These patches support large blocksize up to PAGESIZE (max 64KB). NOTE: They limit the end of a directory block to 65532(64K - 4) to avoid overflow only when using 64KB block. The difference from the previous patches is as follows. - add ext4 support Through mke2fs, ".." entry of root directory is supposed to have rec_len which is equal to blocksize. So just to fix kernel ends up occurring the error in ext2_check_page() etc, if 64KB blocksize. Thus I tested with the provisional fix against e2fsprogs. This patch doesn't include that fix. I tested I/O performance with 4K-64K blocksize on ext3. my box: models :NX-7700i CPU type :Itanium2 number of CPU:1 architecture :ia64 memory size :8309152KB disk size :70007.196(MB) Results: blocksize Read(MB/sec) Write(MB/sec) 4K 58.2 59.7 8K 64.3 60.7 16K 66.8 62.2 32K 65.3 60.2 64K 65.4 60.4 I don't know why 16K-blocksize marks the highest numbers. But without this patch, >4KB blocksize can't be used at least :) The Patch-set consists of the following 4 patches. [1/4] ext2/3/4: enlarge blocksize - Allow blocksize up to pagesize [2/4] ext2: fix rec_len overflow - prevent rec_len from overflow with 64KB blocksize [3/4] ext3: fix rec_len overflow - ditto [4/4] ext4: fix rec_len overflow - ditto Signed-off-by: Takashi Sato Signed-off-by: Mingming Cao --- fs/ext2/super.c | 3 ++- fs/ext3/super.c | 6 +++++- fs/ext4/super.c | 5 +++++ include/linux/ext2_fs.h | 4 ++-- include/linux/ext3_fs.h | 4 ++-- include/linux/ext4_fs.h | 4 ++-- 6 files changed, 18 insertions(+), 8 deletions(-) Index: linux-2.6.23-rc5/fs/ext2/super.c =================================================================== --- linux-2.6.23-rc5.orig/fs/ext2/super.c 2007-09-12 16:17:01.000000000 -0700 +++ linux-2.6.23-rc5/fs/ext2/super.c 2007-09-12 16:26:15.000000000 -0700 @@ -775,7 +775,8 @@ static int ext2_fill_super(struct super_ brelse(bh); if (!sb_set_blocksize(sb, blocksize)) { - printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n"); + printk(KERN_ERR "EXT2-fs: bad blocksize %d.\n", + blocksize); goto failed_sbi; } Index: linux-2.6.23-rc5/fs/ext3/super.c =================================================================== --- linux-2.6.23-rc5.orig/fs/ext3/super.c 2007-09-12 16:17:01.000000000 -0700 +++ linux-2.6.23-rc5/fs/ext3/super.c 2007-09-12 16:26:32.000000000 -0700 @@ -1549,7 +1549,11 @@ static int ext3_fill_super (struct super } brelse (bh); - sb_set_blocksize(sb, blocksize); + if (!sb_set_blocksize(sb, blocksize)) { + printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n", + blocksize); + goto out_fail; + } logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize; offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize; bh = sb_bread(sb, logic_sb_block); Index: linux-2.6.23-rc5/fs/ext4/super.c =================================================================== --- linux-2.6.23-rc5.orig/fs/ext4/super.c 2007-09-12 16:25:17.000000000 -0700 +++ linux-2.6.23-rc5/fs/ext4/super.c 2007-09-12 16:25:40.000000000 -0700 @@ -1602,6 +1602,11 @@ static int ext4_fill_super (struct super goto out_fail; } + if (!sb_set_blocksize(sb, blocksize)) { + printk(KERN_ERR "EXT4-fs: bad blocksize %d.\n", blocksize); + goto out_fail; + } + /* * The ext4 superblock will not be buffer aligned for other than 1kB * block sizes. We need to calculate the offset from buffer start. Index: linux-2.6.23-rc5/include/linux/ext2_fs.h =================================================================== --- linux-2.6.23-rc5.orig/include/linux/ext2_fs.h 2007-09-12 16:17:01.000000000 -0700 +++ linux-2.6.23-rc5/include/linux/ext2_fs.h 2007-09-12 16:25:40.000000000 -0700 @@ -86,8 +86,8 @@ static inline struct ext2_sb_info *EXT2_ * Macro-instructions used to manage several block sizes */ #define EXT2_MIN_BLOCK_SIZE 1024 -#define EXT2_MAX_BLOCK_SIZE 4096 -#define EXT2_MIN_BLOCK_LOG_SIZE 10 +#define EXT2_MAX_BLOCK_SIZE 65536 +#define EXT2_MIN_BLOCK_LOG_SIZE 10 #ifdef __KERNEL__ # define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) #else Index: linux-2.6.23-rc5/include/linux/ext3_fs.h =================================================================== --- linux-2.6.23-rc5.orig/include/linux/ext3_fs.h 2007-09-12 16:17:01.000000000 -0700 +++ linux-2.6.23-rc5/include/linux/ext3_fs.h 2007-09-12 16:25:40.000000000 -0700 @@ -76,8 +76,8 @@ * Macro-instructions used to manage several block sizes */ #define EXT3_MIN_BLOCK_SIZE 1024 -#define EXT3_MAX_BLOCK_SIZE 4096 -#define EXT3_MIN_BLOCK_LOG_SIZE 10 +#define EXT3_MAX_BLOCK_SIZE 65536 +#define EXT3_MIN_BLOCK_LOG_SIZE 10 #ifdef __KERNEL__ # define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) #else Index: linux-2.6.23-rc5/include/linux/ext4_fs.h =================================================================== --- linux-2.6.23-rc5.orig/include/linux/ext4_fs.h 2007-09-12 16:25:17.000000000 -0700 +++ linux-2.6.23-rc5/include/linux/ext4_fs.h 2007-09-12 16:25:40.000000000 -0700 @@ -77,8 +77,8 @@ * Macro-instructions used to manage several block sizes */ #define EXT4_MIN_BLOCK_SIZE 1024 -#define EXT4_MAX_BLOCK_SIZE 4096 -#define EXT4_MIN_BLOCK_LOG_SIZE 10 +#define EXT4_MAX_BLOCK_SIZE 65536 +#define EXT4_MIN_BLOCK_LOG_SIZE 10 #ifdef __KERNEL__ # define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) #else