]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: Allow i_size to be rounded up to the size of a VM page
authorTheodore Ts'o <tytso@mit.edu>
Sat, 4 Aug 2007 00:43:37 +0000 (20:43 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 4 Aug 2007 00:43:37 +0000 (20:43 -0400)
Allow files to be preallocated on-disk up to the next multiple of the
system's page size without complaining about extra blocks.

Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: Girish Shilamkar <girish@clusterfs.com>
Signed-off-by: Kalpak Shah <kalpak@clusterfs.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
e2fsck/e2fsck.c
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/unix.c

index 2ba72c89384b36d304b494d690b2876713655aa4..e2434da85763a94534f1a1604bece72003164d00 100644 (file)
@@ -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)
index 96b83dab6fe63c56db3b59acb7a05264b1d9122f..25a977371b4dc7e30791208fdd551e8149b17297 100644 (file)
@@ -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
index bed1ec8909e609336a708134a3113d49af382dce..b4db8efcfadc56874a4f62d178c26f6d5003d668 100644 (file)
@@ -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;
index 5a617d91cba0a9b75445e5b3eef393ffa65cb0d3..03fa3aebd9132ae6d68962d7e15a0d237a7d34b1 100644 (file)
@@ -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)