summaryrefslogtreecommitdiff
path: root/fs/bcachefs/io.c
diff options
context:
space:
mode:
authorDaniel Hill <daniel@gluo.nz>2022-10-11 21:33:56 +1300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:44 -0400
commit2d485df3da368193dafc78be933669d427b7ddf7 (patch)
treee0c0c4d76c64149bf6acbde2e2847a4304f9962c /fs/bcachefs/io.c
parent55b8550d304a1c0884e98d0bb7126d490a96128f (diff)
downloadlwn-2d485df3da368193dafc78be933669d427b7ddf7.tar.gz
lwn-2d485df3da368193dafc78be933669d427b7ddf7.zip
bcachefs: fix bch2_write_extent() crc corruption.
crc.compression_type & nouce gets reset to inside bch2_rechecksum_bio(), we set it back to the previous values calculated. This fixes incompressible extents being marked as uncompressed. Signed-off-by: Daniel Hill <daniel@gluo.nz> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/io.c')
-rw-r--r--fs/bcachefs/io.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index 648e4a0a21a9..616407fa08ae 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -1074,8 +1074,7 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
saved_iter = dst->bi_iter;
do {
- struct bch_extent_crc_unpacked crc =
- (struct bch_extent_crc_unpacked) { 0 };
+ struct bch_extent_crc_unpacked crc = { 0 };
struct bversion version = op->version;
size_t dst_len, src_len;
@@ -1127,6 +1126,8 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
!crc_is_compressed(crc) &&
bch2_csum_type_is_encryption(op->crc.csum_type) ==
bch2_csum_type_is_encryption(op->csum_type)) {
+ u8 compression_type = crc.compression_type;
+ u16 nonce = crc.nonce;
/*
* Note: when we're using rechecksum(), we need to be
* checksumming @src because it has all the data our
@@ -1145,6 +1146,13 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
bio_sectors(src) - (src_len >> 9),
op->csum_type))
goto csum_err;
+ /*
+ * rchecksum_bio sets compression_type on crc from op->crc,
+ * this isn't always correct as sometimes we're changing
+ * an extent from uncompressed to incompressible.
+ */
+ crc.compression_type = compression_type;
+ crc.nonce = nonce;
} else {
if ((op->flags & BCH_WRITE_DATA_ENCODED) &&
bch2_rechecksum_bio(c, src, version, op->crc,