Whamcloud - gitweb
libext2fs: correctly subtract xattr blocks on bigalloc filesystems
authorEric Biggers <ebiggers@google.com>
Thu, 25 May 2017 01:48:41 +0000 (21:48 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 25 May 2017 01:48:41 +0000 (21:48 -0400)
ext2fs_inode_data_blocks2() calculates an inode's data block count by
subtracting the external xattr block, if any, from the total blocks.
But on bigalloc filesystems, the xattr "block" is actually a whole
cluster, so ext2fs_inode_data_blocks2() would return a too-large value.

It seems this could have caused several different problems, but the one
I encountered was that xfstest generic/399 failed in the "bigalloc"
config because e2fsck incorrectly considered a symlink on the filesystem
to be corrupted at the end of the test.  This happened because e2fsck
incorrectly calculated a nonzero data block count for a "fast" symlink
with an external xattr block and therefore treated it as a "slow"
symlink, which failed validation.

Fix this by updating ext2fs_inode_data_blocks2() to subtract the cluster
size rather than the block size.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/blknum.c
tests/f_bigalloc_symlink_with_xattr/expect.1 [new file with mode: 0644]
tests/f_bigalloc_symlink_with_xattr/image.gz [new file with mode: 0644]
tests/f_bigalloc_symlink_with_xattr/name [new file with mode: 0644]
tests/f_bigalloc_symlink_with_xattr/script [new file with mode: 0644]

index ac80849..aa0e911 100644 (file)
@@ -71,7 +71,7 @@ blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
        return (inode->i_blocks |
                (ext2fs_has_feature_huge_file(fs->super) ?
                 (__u64) inode->osd2.linux2.l_i_blocks_hi << 32 : 0)) -
-               (inode->i_file_acl ? fs->blocksize >> 9 : 0);
+               (inode->i_file_acl ? EXT2_CLUSTER_SIZE(fs->super) >> 9 : 0);
 }
 
 /*
diff --git a/tests/f_bigalloc_symlink_with_xattr/expect.1 b/tests/f_bigalloc_symlink_with_xattr/expect.1
new file mode 100644 (file)
index 0000000..0e6c199
--- /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: 12/16 files (0.0% non-contiguous), 112/128 blocks
+Exit status is 0
diff --git a/tests/f_bigalloc_symlink_with_xattr/image.gz b/tests/f_bigalloc_symlink_with_xattr/image.gz
new file mode 100644 (file)
index 0000000..cbd125d
Binary files /dev/null and b/tests/f_bigalloc_symlink_with_xattr/image.gz differ
diff --git a/tests/f_bigalloc_symlink_with_xattr/name b/tests/f_bigalloc_symlink_with_xattr/name
new file mode 100644 (file)
index 0000000..f612796
--- /dev/null
@@ -0,0 +1 @@
+fast symlink with external xattr block on bigalloc filesystem
diff --git a/tests/f_bigalloc_symlink_with_xattr/script b/tests/f_bigalloc_symlink_with_xattr/script
new file mode 100644 (file)
index 0000000..8ab2b9c
--- /dev/null
@@ -0,0 +1,2 @@
+ONE_PASS_ONLY="true"
+. $cmd_dir/run_e2fsck