Whamcloud - gitweb
e2fsck: make sure system.data xattr is present
authorTheodore Ts'o <tytso@mit.edu>
Tue, 31 Jan 2017 19:05:45 +0000 (14:05 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 31 Jan 2017 19:05:45 +0000 (14:05 -0500)
E2fsprogs used to assume that if i_size is less than 60 bytes, the
system.data xattr isn't needed (and should be removed).  The kernel
disagree, and will declare the file system to be corrupted.  Enforce
the tighter constraints assumed by the kernel.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
lib/ext2fs/inline_data.c
tests/f_write_ea_no_extra_isize/expect.1
tests/f_write_ea_no_extra_isize/expect.2
tests/f_write_ea_toobig_extra_isize/expect.1
tests/f_write_ea_toobig_extra_isize/expect.2
tests/f_write_ea_toosmall_extra_isize/expect.1
tests/f_write_ea_toosmall_extra_isize/expect.2
util/gen-sample-fs [changed mode: 0644->0755]

index 8ef40f6..f13809e 100644 (file)
@@ -1359,7 +1359,6 @@ void e2fsck_pass1(e2fsck_t ctx)
 
                /* Test for inline data flag but no attr */
                if ((inode->i_flags & EXT4_INLINE_DATA_FL) && inlinedata_fs &&
-                   EXT2_I_SIZE(inode) > EXT4_MIN_INLINE_DATA_SIZE &&
                    (ino >= EXT2_FIRST_INODE(fs->super))) {
                        size_t size = 0;
                        errcode_t err;
@@ -1393,15 +1392,15 @@ void e2fsck_pass1(e2fsck_t ctx)
                                /* broken EA or no system.data EA; truncate */
                                if (fix_problem(ctx, PR_1_INLINE_DATA_NO_ATTR,
                                                &pctx)) {
-                                       err = ext2fs_inode_size_set(fs, inode,
-                                                       sizeof(inode->i_block));
+                                       err = ext2fs_inode_size_set(fs, inode, 0);
                                        if (err) {
                                                pctx.errcode = err;
                                                ctx->flags |= E2F_FLAG_ABORT;
                                                goto endit;
                                        }
-                                       if (LINUX_S_ISLNK(inode->i_mode))
-                                               inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+                                       inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+                                       memset(&inode->i_block, 0,
+                                              sizeof(inode->i_block));
                                        e2fsck_write_inode(ctx, ino, inode,
                                                           "pass1");
                                        failed_csum = 0;
index c8613f6..c0fc4ed 100644 (file)
@@ -557,9 +557,6 @@ errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
        }
 
        if (size <= EXT4_MIN_INLINE_DATA_SIZE) {
-               retval = ext2fs_inline_data_ea_remove(fs, ino);
-               if (retval)
-                       return retval;
                memcpy((void *)inode->i_block, buf, size);
                return ext2fs_write_inode(fs, ino, inode);
        }
@@ -587,7 +584,10 @@ errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
                return retval;
        data.fs = fs;
        data.ino = ino;
-       data.ea_size = size - EXT4_MIN_INLINE_DATA_SIZE;
+       if (size > EXT4_MIN_INLINE_DATA_SIZE)
+               data.ea_size = size - EXT4_MIN_INLINE_DATA_SIZE;
+       else
+               data.ea_size = 0;
        data.ea_data = (char *) buf + EXT4_MIN_INLINE_DATA_SIZE;
        return ext2fs_inline_data_ea_set(&data);
 }
index b7e7438..43d7d36 100644 (file)
@@ -1,12 +1,29 @@
 Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has INLINE_DATA_FL flag but extended attribute not found.  Truncate? yes
+
+Inode 12 is a zero-length directory.  Clear? yes
+
 Pass 2: Checking directory structure
-Directory inode 12, block #0, offset 4: directory corrupted
-Salvage? yes
+Entry 'x' in / (2) has deleted/unused inode 12.  Clear? yes
 
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
+Inode 2 ref count is 4, should be 3.  Fix? yes
+
 Pass 5: Checking group summary information
+Inode bitmap differences:  -12
+Fix? yes
+
+Free inodes count wrong for group #0 (116, counted=117).
+Fix? yes
+
+Directories count wrong for group #0 (3, counted=2).
+Fix? yes
+
+Free inodes count wrong (116, counted=117).
+Fix? yes
+
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks
+test_filesys: 11/128 files (0.0% non-contiguous), 17/512 blocks
 Exit status is 1
index 3b6073e..8025ccb 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks
+test_filesys: 11/128 files (0.0% non-contiguous), 17/512 blocks
 Exit status is 0
index 4aa86ac..fc9ba6c 100644 (file)
@@ -1,15 +1,32 @@
 Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has INLINE_DATA_FL flag but extended attribute not found.  Truncate? yes
+
 Inode 12 has a extra size (126) which is invalid
 Fix? yes
 
+Inode 12 is a zero-length directory.  Clear? yes
+
 Pass 2: Checking directory structure
-Directory inode 12, block #0, offset 4: directory corrupted
-Salvage? yes
+Entry 'x' in / (2) has deleted/unused inode 12.  Clear? yes
 
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
+Inode 2 ref count is 4, should be 3.  Fix? yes
+
 Pass 5: Checking group summary information
+Inode bitmap differences:  -12
+Fix? yes
+
+Free inodes count wrong for group #0 (116, counted=117).
+Fix? yes
+
+Directories count wrong for group #0 (3, counted=2).
+Fix? yes
+
+Free inodes count wrong (116, counted=117).
+Fix? yes
+
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks
+test_filesys: 11/128 files (0.0% non-contiguous), 17/512 blocks
 Exit status is 1
index 3b6073e..8025ccb 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks
+test_filesys: 11/128 files (0.0% non-contiguous), 17/512 blocks
 Exit status is 0
index eecfc9d..8d9381e 100644 (file)
@@ -1,15 +1,32 @@
 Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has INLINE_DATA_FL flag but extended attribute not found.  Truncate? yes
+
 Inode 12 has a extra size (1) which is invalid
 Fix? yes
 
+Inode 12 is a zero-length directory.  Clear? yes
+
 Pass 2: Checking directory structure
-Directory inode 12, block #0, offset 4: directory corrupted
-Salvage? yes
+Entry 'x' in / (2) has deleted/unused inode 12.  Clear? yes
 
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
+Inode 2 ref count is 4, should be 3.  Fix? yes
+
 Pass 5: Checking group summary information
+Inode bitmap differences:  -12
+Fix? yes
+
+Free inodes count wrong for group #0 (116, counted=117).
+Fix? yes
+
+Directories count wrong for group #0 (3, counted=2).
+Fix? yes
+
+Free inodes count wrong (116, counted=117).
+Fix? yes
+
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks
+test_filesys: 11/128 files (0.0% non-contiguous), 17/512 blocks
 Exit status is 1
index 3b6073e..8025ccb 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 12/128 files (0.0% non-contiguous), 17/512 blocks
+test_filesys: 11/128 files (0.0% non-contiguous), 17/512 blocks
 Exit status is 0
old mode 100644 (file)
new mode 100755 (executable)
index a6d7b31..8e13916
@@ -4,10 +4,10 @@ MNT=/mnt
 FS=/tmp/foo.img
 
 cp /dev/null $FS
-mke2fs -t ext4 -O inline_data -I 256 -b 4096 $FS 256
+mke2fs -q -t ext4 -O inline_data,^has_journal -I 256 -b 4096 -N 64 $FS 256
 mount -t ext4 $FS $MNT
 ln -s symlink_data $MNT/symlink
-for i in 30 70 500 1023 1024 1500; do
+for i in 30 70 500 1023 1024; do
        ln -s /$(perl -e "print 'x' x $i;") $MNT/l_$i
 done
 touch $MNT/acl
@@ -18,13 +18,23 @@ setfacl -m g:daemon:r $MNT/acl
 touch $MNT/simple_acl
 setfacl -m u:daemon:r $MNT/simple_acl
 touch $MNT/xattr
-attr -s foo -V bar $MNT/xattr
-echo -e "one\n\ttwo" | attr -s quux $MNT/xattr
-echo -e "abc\001\002\003" | attr -s def $MNT/xattr
+attr -q -s foo -V bar $MNT/xattr
+echo -e "one\n\ttwo" | attr -q -s quux $MNT/xattr
+echo -e "abc\001\002\003" | attr -q -s def $MNT/xattr
 echo file_data > $MNT/small_inline
 a="I am a very model of a modern major general;"
 a="$a I've information vegetable, animal and mineral"
 echo $a > $MNT/big_inline
+mkdir $MNT/sdir
+touch $MNT/sdir/1
+touch $MNT/sdir/2
+touch $MNT/sdir/3
+touch $MNT/sdir/4
+mkdir $MNT/mdir
+touch $MNT/mdir/1
+touch $MNT/mdir/2
+touch $MNT/mdir/3
+touch $MNT/mdir/4
+touch $MNT/mdir/5
 umount $MNT
-
-
+e2fsck -fp $FS