Whamcloud - gitweb
Fix e2fsck to not delete symlinks that contain an extended attribute after
authorTheodore Ts'o <tytso@mit.edu>
Thu, 27 Jan 2005 19:28:41 +0000 (14:28 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 27 Jan 2005 19:28:41 +0000 (14:28 -0500)
the ext_attr feature flag has been cleared.  (Addresses Red Hat Bugzilla
#146284)

e2fsck/ChangeLog
e2fsck/pass2.c
tests/ChangeLog
tests/f_clear_xattr/expect.1 [new file with mode: 0644]
tests/f_clear_xattr/expect.2 [new file with mode: 0644]
tests/f_clear_xattr/image.gz [new file with mode: 0644]
tests/f_clear_xattr/name [new file with mode: 0644]

index 4effd27..1d99b1b 100644 (file)
@@ -1,3 +1,12 @@
+2005-01-27  Theodore Ts'o  <tytso@mit.edu>
+
+       * pass2.c (e2fsck_process_bad_inode): Offer to clear i_file_acl
+               before checking to see if an invalid inode should be
+               removed, since otherwise the fast symlink detection code
+               can get confused.  Also clear the inode's entry in
+               inode_bad_map if the inode has been completely fixed.
+               (Addresses Red Hat Bugzilla #146284)
+
 2005-01-25  Theodore Ts'o  <tytso@mit.edu>
 
        * unix.c (main, check_if_skip): Set the valid flag earlier, and if
index 774294c..ef86d31 100644 (file)
@@ -1178,6 +1178,7 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
        ext2_filsys fs = ctx->fs;
        struct ext2_inode       inode;
        int                     inode_modified = 0;
+       int                     not_fixed = 0;
        unsigned char           *frag, *fsize;
        struct problem_context  pctx;
        int     problem = 0;
@@ -1189,6 +1190,14 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
        pctx.dir = dir;
        pctx.inode = &inode;
 
+       if (inode.i_file_acl &&
+           !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
+           fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
+               inode.i_file_acl = 0;
+               inode_modified++;
+       } else
+               not_fixed++;
+
        if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
            !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
            !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
@@ -1217,14 +1226,17 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
                        if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
                                return 0;
                        return 1;
-               }
+               } else
+                       not_fixed++;
                problem = 0;
        }
                
-       if (inode.i_faddr &&
-           fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
-               inode.i_faddr = 0;
-               inode_modified++;
+       if (inode.i_faddr) {
+               if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
+                       inode.i_faddr = 0;
+                       inode_modified++;
+               } else
+                       not_fixed++;
        }
 
        switch (fs->super->s_creator_os) {
@@ -1256,31 +1268,33 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
                if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
                        *fsize = 0;
                        inode_modified++;
-               }
+               } else
+                       not_fixed++;
                pctx.num = 0;
        }
 
        if (inode.i_file_acl &&
-           !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
-           fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
-               inode.i_file_acl = 0;
-               inode_modified++;
-       }
-       if (inode.i_file_acl &&
            ((inode.i_file_acl < fs->super->s_first_data_block) ||
-            (inode.i_file_acl >= fs->super->s_blocks_count)) &&
-           fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
-               inode.i_file_acl = 0;
-               inode_modified++;
+            (inode.i_file_acl >= fs->super->s_blocks_count))) {
+               if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
+                       inode.i_file_acl = 0;
+                       inode_modified++;
+               } else
+                       not_fixed++;
        }
        if (inode.i_dir_acl &&
-           LINUX_S_ISDIR(inode.i_mode) &&
-           fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
-               inode.i_dir_acl = 0;
-               inode_modified++;
+           LINUX_S_ISDIR(inode.i_mode)) {
+               if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
+                       inode.i_dir_acl = 0;
+                       inode_modified++;
+               } else
+                       not_fixed++;
        }
+
        if (inode_modified)
                e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
+       if (!not_fixed)
+               ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
        return 0;
 }
 
index c705a64..c479976 100644 (file)
@@ -1,3 +1,7 @@
+2005-01-27  Theodore Ts'o  <tytso@mit.edu>
+
+       * f_clear_xattr: New test case
+
 2005-01-25  Theodore Ts'o  <tytso@mit.edu>
 
        * f_summary_counts: New test case
diff --git a/tests/f_clear_xattr/expect.1 b/tests/f_clear_xattr/expect.1
new file mode 100644 (file)
index 0000000..5cfbeaf
--- /dev/null
@@ -0,0 +1,38 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 14, i_blocks is 2, should be 0.  Fix? yes
+
+Inode 12, i_blocks is 4, should be 2.  Fix? yes
+
+Inode 13, i_blocks is 2, should be 0.  Fix? yes
+
+Inode 15, i_blocks is 4, should be 2.  Fix? yes
+
+Pass 2: Checking directory structure
+i_file_acl for inode 12 (/dir) is 22, should be zero.
+Clear? yes
+
+i_file_acl for inode 13 (/file) is 22, should be zero.
+Clear? yes
+
+i_file_acl for inode 14 (/symlink) is 22, should be zero.
+Clear? yes
+
+i_file_acl for inode 15 (/long-symlink) is 23, should be zero.
+Clear? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Block bitmap differences:  -(22--23)
+Fix? yes
+
+Free blocks count wrong for group #0 (76, counted=78).
+Fix? yes
+
+Free blocks count wrong (76, counted=78).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 15/16 files (0.0% non-contiguous), 22/100 blocks
+Exit status is 1
diff --git a/tests/f_clear_xattr/expect.2 b/tests/f_clear_xattr/expect.2
new file mode 100644 (file)
index 0000000..306d267
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 15/16 files (0.0% non-contiguous), 22/100 blocks
+Exit status is 0
diff --git a/tests/f_clear_xattr/image.gz b/tests/f_clear_xattr/image.gz
new file mode 100644 (file)
index 0000000..99aca14
Binary files /dev/null and b/tests/f_clear_xattr/image.gz differ
diff --git a/tests/f_clear_xattr/name b/tests/f_clear_xattr/name
new file mode 100644 (file)
index 0000000..2ead690
--- /dev/null
@@ -0,0 +1 @@
+clearing i_file_acl when !ext_attr feature