summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--e2fsck/e2fsck.c1
-rw-r--r--e2fsck/e2fsck.h4
-rw-r--r--e2fsck/pass1.c7
-rw-r--r--e2fsck/unix.c15
4 files changed, 24 insertions, 3 deletions
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index 2ba72c89..e2434da8 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -31,6 +31,7 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret)
context->process_inode_size = 256;
context->ext_attr_ver = 2;
+ context->blocks_per_page = 1;
time_env = getenv("E2FSCK_TIME");
if (time_env)
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 96b83dab..25a97737 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -327,11 +327,11 @@ struct e2fsck_struct {
__u32 fs_ext_attr_inodes;
__u32 fs_ext_attr_blocks;
+ /* misc fields */
time_t now;
-
int ext_attr_ver;
-
profile_t profile;
+ int blocks_per_page;
/*
* For the use of callers of the e2fsck functions; not used by
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index bed1ec89..b4db8efc 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1591,9 +1591,14 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
bad_size = 2;
}
} else {
+ e2_blkcnt_t blkpg = ctx->blocks_per_page;
+
size = EXT2_I_SIZE(inode);
if ((pb.last_block >= 0) &&
- (size < (__u64) pb.last_block * fs->blocksize))
+ /* allow allocated blocks to end of PAGE_SIZE */
+ (size < (__u64)pb.last_block * fs->blocksize) &&
+ (pb.last_block / blkpg * blkpg != pb.last_block ||
+ size < (__u64)(pb.last_block & ~(blkpg-1)) *fs->blocksize))
bad_size = 3;
else if (size > ext2_max_sizes[fs->super->s_log_block_size])
bad_size = 4;
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index 5a617d91..03fa3aeb 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -852,6 +852,7 @@ int main (int argc, char *argv[])
struct problem_context pctx;
int flags, run_result;
int journal_size;
+ int sysval, sys_page_size = 4096;
clear_problem_context(&pctx);
#ifdef MTRACE
@@ -1139,6 +1140,20 @@ restart:
!(ctx->options & E2F_OPT_READONLY))
ext2fs_mark_super_dirty(fs);
+ /*
+ * Calculate the number of filesystem blocks per pagesize. If
+ * fs->blocksize > page_size, set the number of blocks per
+ * pagesize to 1 to avoid division by zero errors.
+ */
+#ifdef _SC_PAGESIZE
+ sysval = sysconf(_SC_PAGESIZE);
+ if (sysval > 0)
+ sys_page_size = sysval;
+#endif /* _SC_PAGESIZE */
+ ctx->blocks_per_page = sys_page_size / fs->blocksize;
+ if (ctx->blocks_per_page == 0)
+ ctx->blocks_per_page = 1;
+
ehandler_init(fs->io);
if (ctx->superblock)