diff options
-rw-r--r-- | e2fsck/e2fsck.c | 1 | ||||
-rw-r--r-- | e2fsck/e2fsck.h | 4 | ||||
-rw-r--r-- | e2fsck/pass1.c | 7 | ||||
-rw-r--r-- | e2fsck/unix.c | 15 |
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) |