bcachefs: Fix nonce inconsistency in bch2_write_prep_encoded_data()

If we're moving an extent that was partially overwritten,
bch2_write_rechecksum() will trim it to the currenty live range.

If we then also want to compress it, it'll be decrypted - but the nonce
has been advanced for the overwritten start of the extent that we
dropped, and we were using the nonce we calculated before rechecksum().

Reported-by: Gabriel de Perthuis <g2p.code@gmail.com>
Fixes: 127d90d282 ("bcachefs: bch2_write_prep_encoded_data() now returns errcode")
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet
2025-03-25 11:40:35 -04:00
parent d8bdc8daac
commit 5af61dbd96

View File

@@ -839,7 +839,6 @@ 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 nonce nonce = extent_nonce(op->version, op->crc);
int ret = 0;
BUG_ON(bio_sectors(bio) != op->crc.compressed_size);
@@ -866,6 +865,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);
if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io)
goto csum_err;
@@ -905,6 +905,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);
if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io)
goto csum_err;