Skip to content

Commit 1b747b0

Browse files
Li LingfengSasha Levin
authored andcommitted
ext4: recover csum seed of tmp_inode after migrating to extents
[ Upstream commit 07ea7a6 ] When migrating to extents, the checksum seed of temporary inode need to be replaced by inode's, otherwise the inode checksums will be incorrect when swapping the inodes data. However, the temporary inode can not match it's checksum to itself since it has lost it's own checksum seed. mkfs.ext4 -F /dev/sdc mount /dev/sdc /mnt/sdc xfs_io -fc "pwrite 4k 4k" -c "fsync" /mnt/sdc/testfile chattr -e /mnt/sdc/testfile chattr +e /mnt/sdc/testfile umount /dev/sdc fsck -fn /dev/sdc ======== ... Pass 1: Checking inodes, blocks, and sizes Inode 13 passes checks, but checksum does not match inode. Fix? no ... ======== The fix is simple, save the checksum seed of temporary inode, and recover it after migrating to extents. Fixes: e81c930 ("ext4: set csum seed in tmp inode while migrating to extents") Signed-off-by: Li Lingfeng <[email protected]> Reviewed-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 94300aa commit 1b747b0

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

fs/ext4/migrate.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ int ext4_ext_migrate(struct inode *inode)
435435
struct inode *tmp_inode = NULL;
436436
struct migrate_struct lb;
437437
unsigned long max_entries;
438-
__u32 goal;
438+
__u32 goal, tmp_csum_seed;
439439
uid_t owner[2];
440440

441441
/*
@@ -483,6 +483,7 @@ int ext4_ext_migrate(struct inode *inode)
483483
* the migration.
484484
*/
485485
ei = EXT4_I(inode);
486+
tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed;
486487
EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed;
487488
i_size_write(tmp_inode, i_size_read(inode));
488489
/*
@@ -593,6 +594,7 @@ int ext4_ext_migrate(struct inode *inode)
593594
* the inode is not visible to user space.
594595
*/
595596
tmp_inode->i_blocks = 0;
597+
EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed;
596598

597599
/* Reset the extent details */
598600
ext4_ext_tree_init(handle, tmp_inode);

0 commit comments

Comments
 (0)