diff options
author | Andreas Dilger <adilger@clusterfs.com> | 2002-05-16 03:20:07 -0600 |
---|---|---|
committer | Andreas Dilger <adilger@clusterfs.com> | 2002-05-16 03:20:07 -0600 |
commit | 932a489cdf6bc83d69e59d3f8e0a57b733799ce1 (patch) | |
tree | 47c7785dbe06875da0942ef42ad984dfbcb00616 | |
parent | 5e941d2979aeab97929de6c0682425dead3bae74 (diff) | |
download | e2fsprogs-932a489cdf6bc83d69e59d3f8e0a57b733799ce1.tar.gz |
Add support for creating and checking 8192-byte blocksize filesystems.
We complain if you try to create such a filesystem on a system with 4096
byte PAGE_SIZE.
Add checks for valid inode size for undocumented -I option.
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | e2fsck/pass1.c | 25 | ||||
-rw-r--r-- | e2fsck/super.c | 7 | ||||
-rw-r--r-- | e2fsck/unix.c | 10 | ||||
-rw-r--r-- | e2fsck/util.c | 3 | ||||
-rw-r--r-- | lib/ext2fs/ext2_fs.h | 13 | ||||
-rw-r--r-- | lib/ext2fs/initialize.c | 4 | ||||
-rw-r--r-- | misc/mke2fs.c | 68 |
8 files changed, 87 insertions, 45 deletions
diff --git a/configure.in b/configure.in index 3449cdd5..6bcc570a 100644 --- a/configure.in +++ b/configure.in @@ -437,7 +437,7 @@ if test $cross_compiling = no; then else AC_CHECK_PROGS(BUILD_CC, gcc cc) fi -AC_CHECK_HEADERS(stdlib.h unistd.h stdarg.h errno.h malloc.h mntent.h paths.h dirent.h getopt.h setjmp.h signal.h termios.h linux/fd.h linux/major.h sys/disklabel.h sys/ioctl.h sys/mkdev.h sys/mount.h sys/sockio.h sys/sysmacros.h sys/time.h sys/stat.h sys/types.h net/if.h netinet/in.h) +AC_CHECK_HEADERS(stdlib.h unistd.h stdarg.h errno.h malloc.h mntent.h paths.h dirent.h getopt.h setjmp.h signal.h termios.h linux/fd.h linux/major.h sys/disklabel.h sys/ioctl.h sys/mkdev.h sys/mount.h sys/sockio.h sys/sysmacros.h sys/time.h sys/stat.h sys/types.h net/if.h netinet/in.h asm/page.h) AC_FUNC_VPRINTF dnl dnl See if struct dirent has a d_namlen field (like bsd systems), implying diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 6a520247..9d041148 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -266,19 +266,17 @@ void e2fsck_pass1(e2fsck_t ctx) mtrace_print("Pass 1"); #endif -#define EXT2_BPP(bits) (1UL << ((bits) - 2)) - - for (i=0; i < 4; i++) { - max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(10+i); - max_sizes = max_sizes + EXT2_BPP(10+i) * EXT2_BPP(10+i); - max_sizes = (max_sizes + - (__u64) EXT2_BPP(10+i) * EXT2_BPP(10+i) * - EXT2_BPP(10+i)); - max_sizes = (max_sizes * (1UL << (10+i))) - 1; - max_sect_limit = 512ULL * ((1LL << 32) - (1 << (i+1))); +#define EXT2_BPP(bits) (1ULL << ((bits) - 2)) + + for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) { + max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i); + max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i); + max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i); + max_sizes = (max_sizes * (1UL << i)) - 1; + max_sect_limit = 512ULL * ((1LL << 32) - (1 << i)); if (max_sizes > max_sect_limit) max_sizes = max_sect_limit; - ext2_max_sizes[i] = max_sizes; + ext2_max_sizes[i - 10] = max_sizes; } #undef EXT2_BPP @@ -451,11 +449,6 @@ void e2fsck_pass1(e2fsck_t ctx) } else if (ino == EXT2_JOURNAL_INO) { ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) { - /* - * XXX arguably this check should be - * in journal.c, before we decide it's - * safe to run the journal... - */ if (!LINUX_S_ISREG(inode.i_mode) && fix_problem(ctx, PR_1_JOURNAL_BAD_MODE, &pctx)) { diff --git a/e2fsck/super.c b/e2fsck/super.c index df784692..e57fd8b7 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -334,11 +334,10 @@ void check_super_block(e2fsck_t ctx) MIN_CHECK, 1, 0); check_super_value(ctx, "first_data_block", sb->s_first_data_block, MAX_CHECK, 0, sb->s_blocks_count); - check_super_value(ctx, "log_frag_size", sb->s_log_frag_size, - MAX_CHECK, 0, 2); check_super_value(ctx, "log_block_size", sb->s_log_block_size, - MIN_CHECK | MAX_CHECK, sb->s_log_frag_size, - 2); + MIN_CHECK | MAX_CHECK, 0, EXT2_MAX_BLOCK_LOG_SIZE); + check_super_value(ctx, "log_frag_size", sb->s_log_frag_size, + 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)); diff --git a/e2fsck/unix.c b/e2fsck/unix.c index e424ac7b..e231888d 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -51,8 +51,6 @@ static int verbose = 0; static int replace_bad_blocks = 0; static char *bad_blocks_file = 0; -static int possible_block_sizes[] = { 1024, 2048, 4096, 8192, 0}; - static int root_filesystem = 0; static int read_only_root = 0; @@ -663,7 +661,6 @@ int main (int argc, char *argv[]) { errcode_t retval = 0; int exit_value = FSCK_OK; - int i; ext2_filsys fs = 0; io_manager io_ptr; struct ext2_super_block *sb; @@ -742,10 +739,11 @@ restart: ctx->superblock, ctx->blocksize, io_ptr, &fs); } else if (ctx->superblock) { - for (i=0; possible_block_sizes[i]; i++) { + int blocksize; + for (blocksize = EXT2_MIN_BLOCK_SIZE; + blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { retval = ext2fs_open(ctx->filesystem_name, flags, - ctx->superblock, - possible_block_sizes[i], + ctx->superblock, blocksize, io_ptr, &fs); if (!retval) break; diff --git a/e2fsck/util.c b/e2fsck/util.c index 227e41da..19d46858 100644 --- a/e2fsck/util.c +++ b/e2fsck/util.c @@ -359,7 +359,8 @@ blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, goto cleanup; sb = (struct ext2_super_block *) buf; - for (blocksize=1024; blocksize <= 8192 ; blocksize = blocksize*2) { + for (blocksize = EXT2_MIN_BLOCK_SIZE; + blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) { superblock = blocksize*8; if (blocksize == 1024) superblock++; diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 11439654..b4d5ae69 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -67,9 +67,10 @@ /* * 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_MIN_BLOCK_LOG_SIZE 10 /* 1024 */ +#define EXT2_MAX_BLOCK_LOG_SIZE 13 /* 8192 */ +#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE) +#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE) #ifdef __KERNEL__ # define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) #else @@ -98,9 +99,9 @@ /* * Macro-instructions used to manage fragments */ -#define EXT2_MIN_FRAG_SIZE 1024 -#define EXT2_MAX_FRAG_SIZE 4096 -#define EXT2_MIN_FRAG_LOG_SIZE 10 +#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE +#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE +#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE #ifdef __KERNEL__ # define EXT2_FRAG_SIZE(s) ((s)->u.ext2_sb.s_frag_size) # define EXT2_FRAGS_PER_BLOCK(s) ((s)->u.ext2_sb.s_frags_per_block) diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index d8fa2289..bf64c683 100644 --- a/lib/ext2fs/initialize.c +++ b/lib/ext2fs/initialize.c @@ -166,8 +166,8 @@ retry: EXT2_DESC_PER_BLOCK(super) - 1) / EXT2_DESC_PER_BLOCK(super); - /* n.b., fs->blocksize is <= 4096 */ - set_field(s_inodes_count, super->s_blocks_count/(4096/fs->blocksize)); + i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize; + set_field(s_inodes_count, super->s_blocks_count / i); /* * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so diff --git a/misc/mke2fs.c b/misc/mke2fs.c index cbaffac5..89b4f6b4 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -44,6 +44,13 @@ extern int optind; #include <sys/ioctl.h> #include <sys/types.h> +#ifdef HAVE_ASM_PAGE_H +#include <asm/page.h> +#define SYS_MAX_BLOCKSIZE PAGE_SIZE +#else +#define SYS_MAX_BLOCKSIZE 4096 +#endif + #include "ext2fs/ext2_fs.h" #include "et/com_err.h" #include "uuid/uuid.h" @@ -137,8 +144,8 @@ struct mke2fs_defaults { { default_str, 3, 1024, 8192 }, { "journal", 0, 4096, 8192 }, { "news", 0, 4096, 4096 }, - { "largefile", 0, 4096, 1024 * 1024 }, - { "largefile4", 0, 4096, 4096 * 1024 }, + { "largefile", 0, SYS_MAX_BLOCKSIZE, 1024 * 1024 }, + { "largefile4", 0, SYS_MAX_BLOCKSIZE, 4096 * 1024 }, { 0, 0, 0, 0}, }; @@ -150,8 +157,7 @@ static void set_fs_defaults(const char *fs_type, int ratio = 0; struct mke2fs_defaults *p; - megs = (super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / - 1024); + megs = super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / 1024; if (inode_ratio) ratio = *inode_ratio; if (!fs_type) @@ -788,6 +794,7 @@ static void PRS(int argc, char *argv[]) blk_t group_blk_max = 8192; int blocksize = 0; int inode_ratio = 0; + int inode_size = 0; int reserved_ratio = 5; ext2_ino_t num_inodes = 0; errcode_t retval; @@ -854,11 +861,16 @@ static void PRS(int argc, char *argv[]) switch (c) { case 'b': blocksize = strtoul(optarg, &tmp, 0); - if (blocksize < 1024 || blocksize > 4096 || *tmp) { + if (blocksize < EXT2_MIN_BLOCK_SIZE || + blocksize > EXT2_MAX_BLOCK_SIZE || *tmp) { com_err(program_name, 0, _("bad block size - %s"), optarg); exit(1); } + if (blocksize > 4096) + fprintf(stderr, _("Warning: blocksize %d not " + "usable on most systems.\n"), + blocksize); param.s_log_block_size = int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); group_blk_max = blocksize * 8; @@ -869,7 +881,8 @@ static void PRS(int argc, char *argv[]) break; case 'f': size = strtoul(optarg, &tmp, 0); - if (size < 1024 || size > 4096 || *tmp) { + if (size < EXT2_MIN_BLOCK_SIZE || + size > EXT2_MAX_BLOCK_SIZE || *tmp) { com_err(program_name, 0, _("bad fragment size - %s"), optarg); @@ -895,10 +908,13 @@ static void PRS(int argc, char *argv[]) break; case 'i': inode_ratio = strtoul(optarg, &tmp, 0); - if (inode_ratio < 1024 || inode_ratio > 4096 * 1024 || + if (inode_ratio < EXT2_MIN_BLOCK_SIZE || + inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024 || *tmp) { com_err(program_name, 0, - _("bad inode ratio - %s"), optarg); + _("bad inode ratio %s (min %d/max %d"), + optarg, EXT2_MIN_BLOCK_SIZE, + EXT2_MAX_BLOCK_SIZE); exit(1); } break; @@ -953,7 +969,12 @@ static void PRS(int argc, char *argv[]) break; #ifdef EXT2_DYNAMIC_REV case 'I': - param.s_inode_size = atoi(optarg); + inode_size = strtoul(optarg, &tmp, 0); + if (*tmp) { + com_err(program_name, 0, + _("bad inode size - %s"), optarg); + exit(1); + } break; #endif case 'N': @@ -1050,6 +1071,18 @@ static void PRS(int argc, char *argv[]) ext2fs_close(jfs); } + if (blocksize > SYS_MAX_BLOCKSIZE) { + if (!force) { + com_err(program_name, 0, + _("%d-byte blocks too big for system (max %d)"), + blocksize, SYS_MAX_BLOCKSIZE); + proceed_question(); + } + fprintf(stderr, _("Warning: %d-byte blocks too big for system " + "(max %d), forced to continue\n"), + blocksize, SYS_MAX_BLOCKSIZE); + } + if (param.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { if (!fs_type) fs_type = "journal"; @@ -1129,6 +1162,23 @@ static void PRS(int argc, char *argv[]) } } + if (inode_size) { + if (inode_size < EXT2_GOOD_OLD_INODE_SIZE || + inode_size > EXT2_BLOCK_SIZE(¶m) || + inode_size & (inode_size - 1)) { + com_err(program_name, 0, + _("bad inode size %d (min %d/max %d)"), + inode_size, EXT2_GOOD_OLD_INODE_SIZE, + EXT2_BLOCK_SIZE(¶m)); + exit(1); + } + if (inode_size != EXT2_GOOD_OLD_INODE_SIZE) + fprintf(stderr, _("Warning: %d-byte inodes not usable " + "on most systems\n"), + inode_size); + param.s_inode_size = inode_size; + } + /* * Calculate number of inodes based on the inode ratio */ |