From a76db26a96982857a306d3e9dbc7f44d5ae45d9d Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 24 Mar 2025 16:40:22 -0400 Subject: [PATCH] bcachefs: Fix duplicate checksum error messages in write path Also, improve the message in prep_encoded_data() - it now prints good/bad checksums, and checksum type. Signed-off-by: Kent Overstreet --- fs/bcachefs/io_write.c | 38 ++++++++++++++++++++------------------ fs/bcachefs/opts.c | 2 +- fs/bcachefs/opts.h | 1 + 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/fs/bcachefs/io_write.c b/fs/bcachefs/io_write.c index 14c5c5c98d51..9613361a519b 100644 --- a/fs/bcachefs/io_write.c +++ b/fs/bcachefs/io_write.c @@ -434,12 +434,6 @@ void bch2_write_op_error(struct bch_write_op *op, u64 offset, const char *fmt, . printbuf_exit(&buf); } -static void bch2_write_csum_err_msg(struct bch_write_op *op) -{ - bch2_write_op_error(op, op->pos.offset, - "error verifying existing checksum while rewriting existing data (memory corruption?)"); -} - void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c, enum bch_data_type type, const struct bkey_i *k, @@ -839,6 +833,7 @@ static noinline int bch2_write_prep_encoded_data(struct bch_write_op *op, struct { struct bch_fs *c = op->c; struct bio *bio = &op->wbio.bio; + struct bch_csum csum; int ret = 0; BUG_ON(bio_sectors(bio) != op->crc.compressed_size); @@ -866,7 +861,7 @@ static noinline int bch2_write_prep_encoded_data(struct bch_write_op *op, struct if (crc_is_compressed(op->crc)) { /* Last point we can still verify checksum: */ struct nonce nonce = extent_nonce(op->version, op->crc); - struct bch_csum csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); + csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io) goto csum_err; @@ -906,7 +901,7 @@ static noinline int bch2_write_prep_encoded_data(struct bch_write_op *op, struct if (bch2_csum_type_is_encryption(op->crc.csum_type) && (op->compression_opt || op->crc.csum_type != op->csum_type)) { struct nonce nonce = extent_nonce(op->version, op->crc); - struct bch_csum csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); + csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io) goto csum_err; @@ -920,7 +915,16 @@ static noinline int bch2_write_prep_encoded_data(struct bch_write_op *op, struct return 0; csum_err: - bch2_write_csum_err_msg(op); + bch2_write_op_error(op, op->pos.offset, + "error verifying existing checksum while moving existing data (memory corruption?)\n" + " expected %0llx:%0llx got %0llx:%0llx type %s", + op->crc.csum.hi, + op->crc.csum.lo, + csum.hi, + csum.lo, + op->crc.csum_type < BCH_CSUM_NR + ? __bch2_csum_types[op->crc.csum_type] + : "(unknown)"); return -BCH_ERR_data_write_csum; } @@ -1047,12 +1051,13 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp, * data can't be modified (by userspace) while it's in * flight. */ - if (bch2_rechecksum_bio(c, src, version, op->crc, + ret = bch2_rechecksum_bio(c, src, version, op->crc, &crc, &op->crc, src_len >> 9, bio_sectors(src) - (src_len >> 9), - op->csum_type)) - goto csum_err; + op->csum_type); + if (ret) + goto err; /* * rchecksum_bio sets compression_type on crc from op->crc, * this isn't always correct as sometimes we're changing @@ -1062,12 +1067,12 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp, crc.nonce = nonce; } else { if ((op->flags & BCH_WRITE_data_encoded) && - bch2_rechecksum_bio(c, src, version, op->crc, + (ret = bch2_rechecksum_bio(c, src, version, op->crc, NULL, &op->crc, src_len >> 9, bio_sectors(src) - (src_len >> 9), - op->crc.csum_type)) - goto csum_err; + op->crc.csum_type))) + goto err; crc.compressed_size = dst_len >> 9; crc.uncompressed_size = src_len >> 9; @@ -1126,9 +1131,6 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp, do_write: *_dst = dst; return more; -csum_err: - bch2_write_csum_err_msg(op); - ret = -BCH_ERR_data_write_csum; err: if (to_wbio(dst)->bounce) bch2_bio_free_pages_pool(c, dst); diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c index 81fd6b7977d3..4eea51edafca 100644 --- a/fs/bcachefs/opts.c +++ b/fs/bcachefs/opts.c @@ -44,7 +44,7 @@ const char * const __bch2_btree_ids[] = { NULL }; -static const char * const __bch2_csum_types[] = { +const char * const __bch2_csum_types[] = { BCH_CSUM_TYPES() NULL }; diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h index bb621804d45a..9a3102f30e11 100644 --- a/fs/bcachefs/opts.h +++ b/fs/bcachefs/opts.h @@ -16,6 +16,7 @@ extern const char * const bch2_version_upgrade_opts[]; extern const char * const bch2_sb_features[]; extern const char * const bch2_sb_compat[]; extern const char * const __bch2_btree_ids[]; +extern const char * const __bch2_csum_types[]; extern const char * const __bch2_csum_opts[]; extern const char * const __bch2_compression_types[]; extern const char * const bch2_compression_opts[]; -- 2.25.1