summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Dilger <adilger@clusterfs.com>2002-05-16 03:20:07 -0600
committerAndreas Dilger <adilger@clusterfs.com>2002-05-16 03:20:07 -0600
commit932a489cdf6bc83d69e59d3f8e0a57b733799ce1 (patch)
tree47c7785dbe06875da0942ef42ad984dfbcb00616
parent5e941d2979aeab97929de6c0682425dead3bae74 (diff)
downloade2fsprogs-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.in2
-rw-r--r--e2fsck/pass1.c25
-rw-r--r--e2fsck/super.c7
-rw-r--r--e2fsck/unix.c10
-rw-r--r--e2fsck/util.c3
-rw-r--r--lib/ext2fs/ext2_fs.h13
-rw-r--r--lib/ext2fs/initialize.c4
-rw-r--r--misc/mke2fs.c68
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(&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
*/