OSDN Git Service

e2fsck: remove EXT4_EOFBLOCKS_FL flag handling
authorLukas Czerner <lczerner@redhat.com>
Thu, 22 Mar 2012 23:42:11 +0000 (18:42 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 22 Mar 2012 23:42:11 +0000 (19:42 -0400)
We've decided to remove EOFBLOCKS_FL from the ext4 file system entirely,
because it is not actually very useful and it is causing more problems
than it solves. We're going to remove it from e2fsprogs first and then
after the new e2fsprogs version is common enough we can remove the
kernel part as well.

This commit changes e2fsck to not check for EOFBLOCKS_FL. Instead we
simply search for initialized extents past the i_size as this should not
happen. Uninitialized extents can be past the i_size as we can do
fallocate with KEEP_SIZE flag.

Also remove the EXT4_EOFBLOCKS_FL from lib/ext2fs/ext2_fs.h since it is
no longer needed.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
e2fsck/problem.c
e2fsck/problem.h
lib/ext2fs/ext2_fs.h
tests/f_bad_disconnected_inode/expect.1

index 9f4142b..c7645d1 100644 (file)
@@ -84,6 +84,7 @@ struct process_block_struct {
        blk64_t         num_blocks;
        blk64_t         max_blocks;
        e2_blkcnt_t     last_block;
+       e2_blkcnt_t     last_init_lblock;
        e2_blkcnt_t     last_db_block;
        int             num_illegal_blocks;
        blk64_t         previous_block;
@@ -1898,6 +1899,9 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
                        pb->last_db_block = blockcnt - 1;
                pb->previous_block = extent.e_pblk + extent.e_len - 1;
                start_block = pb->last_block = extent.e_lblk + extent.e_len - 1;
+               if (is_leaf && !is_dir &&
+                   !(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT))
+                       pb->last_init_lblock = extent.e_lblk + extent.e_len - 1;
        next:
                pctx->errcode = ext2fs_extent_get(ehandle,
                                                  EXT2_EXTENT_NEXT_SIB,
@@ -1964,6 +1968,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
        pb.ino = ino;
        pb.num_blocks = 0;
        pb.last_block = -1;
+       pb.last_init_lblock = -1;
        pb.last_db_block = -1;
        pb.num_illegal_blocks = 0;
        pb.suppress = 0; pb.clear = 0;
@@ -2004,10 +2009,16 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
        if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
                if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL))
                        check_blocks_extents(ctx, pctx, &pb);
-               else
+               else {
                        pctx->errcode = ext2fs_block_iterate3(fs, ino,
                                                pb.is_dir ? BLOCK_FLAG_HOLE : 0,
                                                block_buf, process_block, &pb);
+                       /*
+                        * We do not have uninitialized extents in non extent
+                        * files.
+                        */
+                       pb.last_init_lblock = pb.last_block;
+               }
        }
        end_problem_latch(ctx, PR_LATCH_BLOCK);
        end_problem_latch(ctx, PR_LATCH_TOOBIG);
@@ -2079,12 +2090,12 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                e2_blkcnt_t blkpg = ctx->blocks_per_page;
 
                size = EXT2_I_SIZE(inode);
-               if ((pb.last_block >= 0) &&
+               if ((pb.last_init_lblock >= 0) &&
                    /* 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) &&
-                   !(inode->i_flags & EXT4_EOFBLOCKS_FL))
+                   (size < (__u64)pb.last_init_lblock * fs->blocksize) &&
+                   (pb.last_init_lblock / blkpg * blkpg != pb.last_init_lblock ||
+                    size < (__u64)(pb.last_init_lblock & ~(blkpg-1)) *
+                    fs->blocksize))
                        bad_size = 3;
                else if (!(extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
                         size > ext2_max_sizes[fs->super->s_log_block_size])
@@ -2095,19 +2106,6 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                         ((1ULL << (32 + EXT2_BLOCK_SIZE_BITS(fs->super))) - 1))
                        /* too big for an extent-based file - 32bit ee_block */
                        bad_size = 6;
-
-               /*
-                * Check to see if the EOFBLOCKS flag is set where it
-                * doesn't need to be.
-                */
-               if ((inode->i_flags & EXT4_EOFBLOCKS_FL) &&
-                   (size >= (((__u64)pb.last_block + 1) * fs->blocksize))) {
-                       pctx->blkcount = pb.last_block;
-                       if (fix_problem(ctx, PR_1_EOFBLOCKS_FL_SET, pctx)) {
-                               inode->i_flags &= ~EXT4_EOFBLOCKS_FL;
-                               dirty_inode++;
-                       }
-               }
        }
        /* i_size for symlinks is checked elsewhere */
        if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
index f5c0554..d51a408 100644 (file)
@@ -916,11 +916,6 @@ static struct e2fsck_problem problem_table[] = {
          N_("@i %i has an invalid extent node (blk %b, lblk %c)\n"),
          PROMPT_CLEAR, 0 },
 
-       { PR_1_EOFBLOCKS_FL_SET,
-         N_("@i %i should not have EOFBLOCKS_FL set "
-            "(size %Is, lblk %r)\n"),
-         PROMPT_CLEAR, PR_PREEN_OK },
-
        /* Failed to convert subcluster bitmap */
        { PR_1_CONVERT_SUBCLUSTER,
          N_("Error converting subcluster @b @B: %m\n"),
index 348cfbc..07df810 100644 (file)
@@ -538,8 +538,7 @@ struct problem_context {
 /* Extent node header invalid */
 #define PR_1_EXTENT_HEADER_INVALID     0x01005F
 
-/* EOFBLOCKS flag set when not necessary */
-#define PR_1_EOFBLOCKS_FL_SET          0x010060
+/* PR_1_EOFBLOCKS_FL_SET 0x010060 was here */
 
 /* Failed to convert subcluster bitmap */
 #define PR_1_CONVERT_SUBCLUSTER                0x010061
index 3b01285..20decff 100644 (file)
@@ -300,7 +300,7 @@ struct ext2_dx_countlimit {
 #define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
 #define EXT4_EXTENTS_FL                0x00080000 /* Inode uses extents */
 #define EXT4_EA_INODE_FL               0x00200000 /* Inode used for large EA */
-#define EXT4_EOFBLOCKS_FL              0x00400000 /* Blocks allocated beyond EOF */
+/* EXT4_EOFBLOCKS_FL 0x00400000 was here */
 #define EXT4_SNAPFILE_FL               0x01000000  /* Inode is a snapshot */
 #define EXT4_SNAPFILE_DELETED_FL       0x04000000  /* Snapshot is being deleted */
 #define EXT4_SNAPFILE_SHRUNK_FL                0x08000000  /* Snapshot shrink has completed */
index d3920e3..11862f6 100644 (file)
@@ -2,21 +2,12 @@ Pass 1: Checking inodes, blocks, and sizes
 Inode 1 has EXTENTS_FL flag set on filesystem without extents support.
 Clear? yes
 
-Inode 9 should not have EOFBLOCKS_FL set (size 0, lblk -1)
-Clear? yes
-
-Inode 10 should not have EOFBLOCKS_FL set (size 0, lblk -1)
-Clear? yes
-
 Inode 15 has EXTENTS_FL flag set on filesystem without extents support.
 Clear? yes
 
 Inode 16 has EXTENTS_FL flag set on filesystem without extents support.
 Clear? yes
 
-Inode 13 should not have EOFBLOCKS_FL set (size 0, lblk -1)
-Clear? yes
-
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 /lost+found not found.  Create? yes