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>
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);
}
/*
--- /dev/null
+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
--- /dev/null
+fast symlink with external xattr block on bigalloc filesystem
--- /dev/null
+ONE_PASS_ONLY="true"
+. $cmd_dir/run_e2fsck