aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@sandeen.net>2014-10-01 19:24:11 -0400
committerDave Chinner <david@fromorbit.com>2014-10-01 19:24:11 -0400
commit04dd1a0d4b17a71220eae4fb313218f15a49bcdd (patch)
treeb1947cec8a738c5d711b3c6416399080ec145443 /fs/xfs/libxfs
parent6ee49a20c13b4b4e79a3bba406df8106cff284a1 (diff)
xfs: fix crc field handling in xfs_sb_to/from_disk
I discovered this in userspace, but the same change applies to the kernel. If we xfs_mdrestore an image from a non-crc filesystem, lo and behold the restored image has gained a CRC: # db/xfs_metadump.sh -o /dev/sdc1 - | xfs_mdrestore - test.img # xfs_db -c "sb 0" -c "p crc" /dev/sdc1 crc = 0 (correct) # xfs_db -c "sb 0" -c "p crc" test.img crc = 0xb6f8d6a0 (correct) This is because xfs_sb_from_disk doesn't fill in sb_crc, but xfs_sb_to_disk(XFS_SB_ALL_BITS) does write the in-memory CRC to disk - so we get uninitialized memory on disk. Fix this by always initializing sb_crc to 0 when we read the superblock, and masking out the CRC bit from ALL_BITS when we write it. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_sb.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 8426e5e2682e..5f902fa7913f 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -445,6 +445,8 @@ __xfs_sb_from_disk(
445 to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat); 445 to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat);
446 to->sb_features_log_incompat = 446 to->sb_features_log_incompat =
447 be32_to_cpu(from->sb_features_log_incompat); 447 be32_to_cpu(from->sb_features_log_incompat);
448 /* crc is only used on disk, not in memory; just init to 0 here. */
449 to->sb_crc = 0;
448 to->sb_pad = 0; 450 to->sb_pad = 0;
449 to->sb_pquotino = be64_to_cpu(from->sb_pquotino); 451 to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
450 to->sb_lsn = be64_to_cpu(from->sb_lsn); 452 to->sb_lsn = be64_to_cpu(from->sb_lsn);
@@ -550,6 +552,9 @@ xfs_sb_to_disk(
550 if (!fields) 552 if (!fields)
551 return; 553 return;
552 554
555 /* We should never write the crc here, it's updated in the IO path */
556 fields &= ~XFS_SB_CRC;
557
553 xfs_sb_quota_to_disk(to, from, &fields); 558 xfs_sb_quota_to_disk(to, from, &fields);
554 while (fields) { 559 while (fields) {
555 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 560 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);