From b21bf267783274683a432eea6e5c589eab94123e Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Mon, 10 Jun 2002 11:05:56 -0600 Subject: [PATCH] Do sanity checking of the number of blocks and inodes in a group for 8192-byte and 16384-byte blocksize filesystems. Change the default bytes-per-inode ratio of a new filesystem to be at most one inode per block for large blocksizes. --- e2fsck/ChangeLog | 7 +++++++ e2fsck/super.c | 22 ++++++++++++++-------- lib/ext2fs/ChangeLog | 13 +++++++++++++ lib/ext2fs/ext2_fs.h | 16 +++++++++------- lib/ext2fs/initialize.c | 29 +++++++++++++++++++---------- lib/ext2fs/openfs.c | 10 ++++++---- misc/ChangeLog | 5 +++++ misc/mke2fs.c | 3 ++- tests/ChangeLog | 5 +++++ tests/f_16384_block/expect.1 | 7 +++++++ tests/f_16384_block/expect.2 | 7 +++++++ tests/f_16384_block/image.gz | Bin 0 -> 9992 bytes tests/f_16384_block/name | 1 + tests/f_8192_block/expect.1 | 7 +++++++ tests/f_8192_block/expect.2 | 7 +++++++ tests/f_8192_block/image.gz | Bin 0 -> 9992 bytes tests/f_8192_block/name | 1 + 17 files changed, 110 insertions(+), 30 deletions(-) create mode 100644 tests/f_16384_block/expect.1 create mode 100644 tests/f_16384_block/expect.2 create mode 100644 tests/f_16384_block/image.gz create mode 100644 tests/f_16384_block/name create mode 100644 tests/f_8192_block/expect.1 create mode 100644 tests/f_8192_block/expect.2 create mode 100644 tests/f_8192_block/image.gz create mode 100644 tests/f_8192_block/name diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 5952bdcb..c2e7e8d5 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,10 @@ +2002-05-22 Andreas Dilger + + * super.c (check_superblock): Check that the number of inodes and + blocks in a group is less than 2^16, so that the free inode + and block counts for a group fit into the group descriptor + table fields. Any more than that would need a COMPAT flag. + 2002-05-22 Theodore Ts'o * pass1.c (check_ext_attr): Update to support the V2 Bestbits EA diff --git a/e2fsck/super.c b/e2fsck/super.c index c880a9ad..49e97505 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -308,13 +308,20 @@ void check_super_block(e2fsck_t ctx) blk_t first_block, last_block; struct ext2_super_block *sb = fs->super; blk_t blocks_per_group = fs->super->s_blocks_per_group; + blk_t bpg_max; int inodes_per_block; + int ipg_max; dgrp_t i; blk_t should_be; struct problem_context pctx; - - inodes_per_block = (EXT2_BLOCK_SIZE(fs->super) / - EXT2_INODE_SIZE(fs->super)); + + inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super); + ipg_max = inodes_per_block * (blocks_per_group - 4); + if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb)) + ipg_max = EXT2_MAX_INODES_PER_GROUP(sb); + bpg_max = 8 * EXT2_BLOCK_SIZE(sb); + if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb)) + bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb); ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap"); @@ -322,7 +329,7 @@ void check_super_block(e2fsck_t ctx) sizeof(int) * fs->group_desc_count, "invalid_block_bitmap"); ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx, sizeof(int) * fs->group_desc_count, "invalid_inode_table"); - + clear_problem_context(&pctx); /* @@ -341,12 +348,11 @@ void check_super_block(e2fsck_t ctx) MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size); check_super_value(ctx, "frags_per_group", sb->s_frags_per_group, MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group, - 8 * EXT2_BLOCK_SIZE(sb)); + bpg_max); check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group, - MIN_CHECK | MAX_CHECK, 8, 8 * EXT2_BLOCK_SIZE(sb)); + MIN_CHECK | MAX_CHECK, 8, bpg_max); check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group, - MIN_CHECK | MAX_CHECK, inodes_per_block, - inodes_per_block * (blocks_per_group-4)); + MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max); check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count, MAX_CHECK, 0, sb->s_blocks_count / 4); diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog index 77ed4cce..0b31f830 100644 --- a/lib/ext2fs/ChangeLog +++ b/lib/ext2fs/ChangeLog @@ -1,3 +1,16 @@ +2002-06-09 Andreas Dilger + + * ext2_fs.h: Add macros for maximum block/inode counts: + EXT2_INODES_PER_BLOCK, EXT2_MAX_BLOCKS_PER_GROUP, + and EXT2_MAX_INODES_PER_GROUP. + + * openfs.c (ext2fs_open): Check that the number of blocks in a group + is less than 2^16, otherwise we need an INCOMPAT flag (not + in existence yet, if ever) to open such a filesystem. + + * initialize.c (ext2fs_initialize): Limit the number of blocks and + inodes in a group to less than 2^16. + 2002-06-09 Andreas Dilger * ext2_fs.h: Further minor cleanups of the header. Consolidate diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index c9033b1a..766afd74 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -181,15 +181,17 @@ struct ext2_dx_countlimit { /* * Macro-instructions used to manage group descriptors */ +#define EXT2_BLOCKS_PER_GROUP(s) (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)) +/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */ +#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8) +#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s)) #ifdef __KERNEL__ -# define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) -# define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block) -# define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) -# define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits) +#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_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) -# define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) -# define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) +#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) #endif /* diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index bf64c683..f1324163 100644 --- a/lib/ext2fs/initialize.c +++ b/lib/ext2fs/initialize.c @@ -63,6 +63,7 @@ errcode_t ext2fs_initialize(const char *name, int flags, int rem; int overhead = 0; blk_t group_block; + int ipg; int i, j; blk_t numblocks; char *buf; @@ -131,9 +132,11 @@ errcode_t ext2fs_initialize(const char *name, int flags, fs->blocksize = EXT2_BLOCK_SIZE(super); fs->fragsize = EXT2_FRAG_SIZE(super); frags_per_block = fs->blocksize / fs->fragsize; - - /* default: (fs->blocksize*8) blocks/group */ - set_field(s_blocks_per_group, fs->blocksize*8); + + /* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */ + set_field(s_blocks_per_group, fs->blocksize * 8); + if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super)) + super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super); super->s_frags_per_group = super->s_blocks_per_group * frags_per_block; super->s_blocks_count = param->s_blocks_count; @@ -180,14 +183,20 @@ retry: * There should be at least as many inodes as the user * requested. Figure out how many inodes per group that * should be. But make sure that we don't allocate more than - * one bitmap's worth of inodes + * one bitmap's worth of inodes each group. */ - super->s_inodes_per_group = (super->s_inodes_count + - fs->group_desc_count - 1) / - fs->group_desc_count; - if (super->s_inodes_per_group > fs->blocksize*8) - super->s_inodes_per_group = fs->blocksize*8; - + ipg = (super->s_inodes_count + fs->group_desc_count - 1) / + fs->group_desc_count; + if (ipg > fs->blocksize * 8) + ipg = fs->blocksize * 8; + + if (ipg > EXT2_MAX_INODES_PER_GROUP(super)) + ipg = EXT2_MAX_INODES_PER_GROUP(super); + + super->s_inodes_per_group = ipg; + if (super->s_inodes_count > ipg * fs->group_desc_count) + super->s_inodes_count = ipg * fs->group_desc_count; + /* * Make sure the number of inodes per group completely fills * the inode table blocks in the descriptor. If not, add some diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index f3f849f8..d9021d6a 100644 --- a/lib/ext2fs/openfs.c +++ b/lib/ext2fs/openfs.c @@ -43,7 +43,7 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock, { ext2_filsys fs; errcode_t retval; - int i, j, groups_per_block; + int i, j, groups_per_block, blocks_per_group; blk_t group_block; char *dest; struct ext2_group_desc *gdp; @@ -196,14 +196,16 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock, /* * Read group descriptors */ - if ((EXT2_BLOCKS_PER_GROUP(fs->super)) == 0) { + blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super); + if (blocks_per_group == 0 || + blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) || + fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) { retval = EXT2_ET_CORRUPT_SUPERBLOCK; goto cleanup; } fs->group_desc_count = (fs->super->s_blocks_count - fs->super->s_first_data_block + - EXT2_BLOCKS_PER_GROUP(fs->super) - 1) - / EXT2_BLOCKS_PER_GROUP(fs->super); + blocks_per_group - 1) / blocks_per_group; fs->desc_blocks = (fs->group_desc_count + EXT2_DESC_PER_BLOCK(fs->super) - 1) / EXT2_DESC_PER_BLOCK(fs->super); diff --git a/misc/ChangeLog b/misc/ChangeLog index 6bcf5312..0a972d02 100644 --- a/misc/ChangeLog +++ b/misc/ChangeLog @@ -1,3 +1,8 @@ +2002-05-22 Andreas Dilger + + * mke2fs.c (set_fs_defaults): make the default inode ratio at most + one inode per block for large blocksizes. + 2002-05-17 Theodore Ts'o * mke2fs.c (PRS): Determine the page size using sysconf() at diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 4ab4ec31..56254961 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -166,7 +166,8 @@ static void set_fs_defaults(const char *fs_type, (megs > p->size)) continue; if (ratio == 0) - *inode_ratio = p->inode_ratio; + *inode_ratio = p->inode_ratio < blocksize ? + blocksize : p->inode_ratio; if (blocksize == 0) { if (p->blocksize == DEF_MAX_BLOCKSIZE) p->blocksize = sys_page_size; diff --git a/tests/ChangeLog b/tests/ChangeLog index 018ef59e..9df3d48d 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2002-06-09 Andreas Dilger + + * f_8192_block, f_16384_block: Basic tests of 8192-byte block + and 16384-byte blocksize filesystems. + 2002-05-21 Theodore Ts'o * f_badsymlinks: Check for symlink too big error message. diff --git a/tests/f_16384_block/expect.1 b/tests/f_16384_block/expect.1 new file mode 100644 index 00000000..d5a5659c --- /dev/null +++ b/tests/f_16384_block/expect.1 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks +Exit status is 0 diff --git a/tests/f_16384_block/expect.2 b/tests/f_16384_block/expect.2 new file mode 100644 index 00000000..d5a5659c --- /dev/null +++ b/tests/f_16384_block/expect.2 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks +Exit status is 0 diff --git a/tests/f_16384_block/image.gz b/tests/f_16384_block/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..c5f311b0fb0944eb52cbd253ed2e0073994e2279 GIT binary patch literal 9992 zcmeIwZB!Fi8V7K!3hp9Ox2qm?A#N#j`$B8i2G&r7)}C0ayypcbhR{Vq$!v&~9YAb= z$}!Znk&0cYQ-uYTX7UQ+fCQ3At)g22JXju{bl(@9`3WKYlP2fy!^t#iNJ zbMHO(p8Nkj59|1(uFgFesWe^NOS8{e|C_RQWDHwvzAd47Au z?!?6AEzMhM*Z%s8&uU+I`8~l4zpGsv8MOPzFW*m1Jji{Pmw5T|(v{Ul5rB$N(W}?J zeBY?oTCzB*&7hK@F}HR$C!klZ&WH%CT39T$&-INTJ((LGzN51~J8T&2|DjUZur!ym z70)r`SBI!j+uxltCeKZ9C}i_u?WDaSx2yWvj&h%;+IZkL_dAL5*2~kDOC!$1jr+%! z1&ph`uIv7(L*ruvIqQCDF>Z-+USF6#eg4|Miuq}GXvK`9kCgtN?^b*`WZ_nvowxM{ z1?8GrleP|4gvXBM++>?q%K8A!dSfW@Jk=8n_tqb z6JK>pku0ziwoGZZgT_t#qMAcUU$1IiWo&m--G2Q#+3$LIrQf-(;IoZBUEsL?4!>o( zG1C9j56S?#=eC!1=I(*V*B`y|R84a++j!5dR)whPMbE8Un&NAU#bX8in;m5%VI^?x zae0YTT9mu;5s5<3Vqfrof;fQ?=nmfabvrmKd4%C_|(T~c!bh@(JqlpJi zjvf!91Z@tRHC=D}D^J~khmyOXkHqQqL>_cVoF*jr z5G2k>FoLAnY%SDmCSQayM)xHc8u1~r&Wx6)+4LhWkGbW6UV@uQqq*k+GKN_o$*3e0 ztD;il_tju6RAzj33U-R(`8pen`K}V`Pw_&VDFI`V3uR5&`UHFrb78PQTk)Df57LW3^!!|hMQaUh|E=1V)@!Bn$>yj zZ?fe{!eM)mOa-?~wWq;47?tYof+ygPDQz0NWFW&$e9W$hP7NmBK@TX~)+3>KGc^I| z*P9|`H-778Jz49gY&ADj7rtpV)5`zjRt`~x240bARQ6BHc3C>O#2?s&YT=}P1!aWW zqO`}rTKHm=?gsc5_(H1|AxEi(GKIzDlni4R+2SM#OS4gS4MwEKEExeCq^9k%L0HGd zzh|cmh}`%?G%-3e82^Uq1J3Q>9Ve>6cA&RT6A2;{QwdL5`#u?WyfJ#)$6GTy>vTVW zM}c;M_OE0F`o00s;VzV`yh!L#*$ka&$RLR_>R*5@MiTyTPCg5K zjo*W~$}X!gpYW1;PR}4xMD}uQuW5qGASlh(R?gdCkAw=uf_nQpC{N56+S$~kxzng4 zNtL<1JUtd4poZxzUvD8IA~#UqnGJ=eIM*P}_n9APd&mYlX;kFJeNJC4q^^`8H>(UL`A4 zYf7*7y(9r5nu!u0Y-ok_<0HVZ-@WpS3gBsMf)B1gMMD& S{x8y02EUy!p$G`54EPVXU@wpW literal 0 HcmV?d00001 diff --git a/tests/f_16384_block/name b/tests/f_16384_block/name new file mode 100644 index 00000000..79b31121 --- /dev/null +++ b/tests/f_16384_block/name @@ -0,0 +1 @@ +16384 byte blocksize diff --git a/tests/f_8192_block/expect.1 b/tests/f_8192_block/expect.1 new file mode 100644 index 00000000..d5a5659c --- /dev/null +++ b/tests/f_8192_block/expect.1 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks +Exit status is 0 diff --git a/tests/f_8192_block/expect.2 b/tests/f_8192_block/expect.2 new file mode 100644 index 00000000..d5a5659c --- /dev/null +++ b/tests/f_8192_block/expect.2 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks +Exit status is 0 diff --git a/tests/f_8192_block/image.gz b/tests/f_8192_block/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..c5f311b0fb0944eb52cbd253ed2e0073994e2279 GIT binary patch literal 9992 zcmeIwZB!Fi8V7K!3hp9Ox2qm?A#N#j`$B8i2G&r7)}C0ayypcbhR{Vq$!v&~9YAb= z$}!Znk&0cYQ-uYTX7UQ+fCQ3At)g22JXju{bl(@9`3WKYlP2fy!^t#iNJ zbMHO(p8Nkj59|1(uFgFesWe^NOS8{e|C_RQWDHwvzAd47Au z?!?6AEzMhM*Z%s8&uU+I`8~l4zpGsv8MOPzFW*m1Jji{Pmw5T|(v{Ul5rB$N(W}?J zeBY?oTCzB*&7hK@F}HR$C!klZ&WH%CT39T$&-INTJ((LGzN51~J8T&2|DjUZur!ym z70)r`SBI!j+uxltCeKZ9C}i_u?WDaSx2yWvj&h%;+IZkL_dAL5*2~kDOC!$1jr+%! z1&ph`uIv7(L*ruvIqQCDF>Z-+USF6#eg4|Miuq}GXvK`9kCgtN?^b*`WZ_nvowxM{ z1?8GrleP|4gvXBM++>?q%K8A!dSfW@Jk=8n_tqb z6JK>pku0ziwoGZZgT_t#qMAcUU$1IiWo&m--G2Q#+3$LIrQf-(;IoZBUEsL?4!>o( zG1C9j56S?#=eC!1=I(*V*B`y|R84a++j!5dR)whPMbE8Un&NAU#bX8in;m5%VI^?x zae0YTT9mu;5s5<3Vqfrof;fQ?=nmfabvrmKd4%C_|(T~c!bh@(JqlpJi zjvf!91Z@tRHC=D}D^J~khmyOXkHqQqL>_cVoF*jr z5G2k>FoLAnY%SDmCSQayM)xHc8u1~r&Wx6)+4LhWkGbW6UV@uQqq*k+GKN_o$*3e0 ztD;il_tju6RAzj33U-R(`8pen`K}V`Pw_&VDFI`V3uR5&`UHFrb78PQTk)Df57LW3^!!|hMQaUh|E=1V)@!Bn$>yj zZ?fe{!eM)mOa-?~wWq;47?tYof+ygPDQz0NWFW&$e9W$hP7NmBK@TX~)+3>KGc^I| z*P9|`H-778Jz49gY&ADj7rtpV)5`zjRt`~x240bARQ6BHc3C>O#2?s&YT=}P1!aWW zqO`}rTKHm=?gsc5_(H1|AxEi(GKIzDlni4R+2SM#OS4gS4MwEKEExeCq^9k%L0HGd zzh|cmh}`%?G%-3e82^Uq1J3Q>9Ve>6cA&RT6A2;{QwdL5`#u?WyfJ#)$6GTy>vTVW zM}c;M_OE0F`o00s;VzV`yh!L#*$ka&$RLR_>R*5@MiTyTPCg5K zjo*W~$}X!gpYW1;PR}4xMD}uQuW5qGASlh(R?gdCkAw=uf_nQpC{N56+S$~kxzng4 zNtL<1JUtd4poZxzUvD8IA~#UqnGJ=eIM*P}_n9APd&mYlX;kFJeNJC4q^^`8H>(UL`A4 zYf7*7y(9r5nu!u0Y-ok_<0HVZ-@WpS3gBsMf)B1gMMD& S{x8y02EUy!p$G`54EPVXU@wpW literal 0 HcmV?d00001 diff --git a/tests/f_8192_block/name b/tests/f_8192_block/name new file mode 100644 index 00000000..50d8dca3 --- /dev/null +++ b/tests/f_8192_block/name @@ -0,0 +1 @@ +8192 byte blocksize