Whamcloud - gitweb
Add support for creating and checking 8192-byte blocksize filesystems.
authorAndreas Dilger <adilger@clusterfs.com>
Thu, 16 May 2002 09:20:07 +0000 (03:20 -0600)
committerAndreas Dilger <adilger@clusterfs.com>
Thu, 16 May 2002 09:20:07 +0000 (03:20 -0600)
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.

configure.in
e2fsck/pass1.c
e2fsck/super.c
e2fsck/unix.c
e2fsck/util.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/initialize.c
misc/mke2fs.c

index 3449cdd..6bcc570 100644 (file)
@@ -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
index 6a52024..9d04114 100644 (file)
@@ -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)) {
index df78469..e57fd8b 100644 (file)
@@ -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));
index e424ac7..e231888 100644 (file)
@@ -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;
index 227e41d..19d4685 100644 (file)
@@ -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++;
index 1143965..b4d5ae6 100644 (file)
 /*
  * 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)
index d8fa228..bf64c68 100644 (file)
@@ -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
index cbaffac..89b4f6b 100644 (file)
@@ -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(&param) ||
+                   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(&param));
+                       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
         */