We had a user report with a filesystem where data has been written out with the incorrect checksum type - including no checksum.
That means we need to check/repair such cases, and rebalance is responsible for handling io path option propagation to extents; thus, rebalance needs to support checksum type. Signed-off-by: Kent Overstreet <[email protected]> --- fs/bcachefs/rebalance.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c index 0d1abb0eeb88..a2fb2f1cec70 100644 --- a/fs/bcachefs/rebalance.c +++ b/fs/bcachefs/rebalance.c @@ -47,10 +47,12 @@ static void bch2_bkey_needs_rebalance(struct bch_fs *c, struct bkey_s_c k, struct bch_inode_opts *io_opts, unsigned *move_ptrs, unsigned *compress_ptrs, + unsigned *csum_ptrs, u64 *sectors) { *move_ptrs = 0; *compress_ptrs = 0; + *csum_ptrs = 0; *sectors = 0; struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); @@ -66,6 +68,9 @@ static void bch2_bkey_needs_rebalance(struct bch_fs *c, struct bkey_s_c k, bch2_compression_opt_to_type(io_opts ? io_opts->background_compression : rb_opts->background_compression); + unsigned csum_type = bch2_csum_opt_to_type(io_opts + ? io_opts->data_checksum + : rb_opts->data_checksum, true); unsigned target = io_opts ? io_opts->background_target : rb_opts->background_target; @@ -87,6 +92,9 @@ static void bch2_bkey_needs_rebalance(struct bch_fs *c, struct bkey_s_c k, if (p.crc.compression_type != compression_type) *compress_ptrs |= ptr_idx; + if (p.crc.csum_type != csum_type) + *csum_ptrs |= ptr_idx; + if (target && !bch2_dev_in_target(c, p.ptr.dev, target)) *move_ptrs |= ptr_idx; } @@ -95,11 +103,11 @@ static void bch2_bkey_needs_rebalance(struct bch_fs *c, struct bkey_s_c k, } if (unwritten) - *compress_ptrs = 0; + *compress_ptrs = *csum_ptrs = 0; if (incompressible) *compress_ptrs = 0; - unsigned rb_ptrs = *move_ptrs | *compress_ptrs; + unsigned rb_ptrs = *move_ptrs | *compress_ptrs | *csum_ptrs; if (!rb_ptrs) return; @@ -116,9 +124,10 @@ u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k) { unsigned move_ptrs = 0; unsigned compress_ptrs = 0; + unsigned csum_ptrs = 0; u64 sectors = 0; - bch2_bkey_needs_rebalance(c, k, NULL, &move_ptrs, &compress_ptrs, §ors); + bch2_bkey_needs_rebalance(c, k, NULL, &move_ptrs, &compress_ptrs, &csum_ptrs, §ors); return sectors; } @@ -128,10 +137,11 @@ static unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, { unsigned move_ptrs = 0; unsigned compress_ptrs = 0; + unsigned csum_ptrs = 0; u64 sectors = 0; - bch2_bkey_needs_rebalance(c, k, opts, &move_ptrs, &compress_ptrs, §ors); - return move_ptrs|compress_ptrs; + bch2_bkey_needs_rebalance(c, k, opts, &move_ptrs, &compress_ptrs, &csum_ptrs, §ors); + return move_ptrs|compress_ptrs|csum_ptrs; } static inline bool bkey_should_have_rb_opts(struct bch_fs *c, @@ -509,9 +519,10 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans, unsigned move_ptrs = 0; unsigned compress_ptrs = 0; + unsigned csum_ptrs = 0; u64 sectors = 0; - bch2_bkey_needs_rebalance(c, k, opts, &move_ptrs, &compress_ptrs, §ors); + bch2_bkey_needs_rebalance(c, k, opts, &move_ptrs, &compress_ptrs, &csum_ptrs, §ors); if (move_ptrs) { prt_str(&buf, "move="); @@ -529,6 +540,14 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans, prt_newline(&buf); } + if (csum_ptrs) { + prt_str(&buf, "csum="); + bch2_prt_csum_opt(&buf, opts->data_checksum); + prt_str(&buf, " "); + bch2_prt_u64_base2(&buf, csum_ptrs); + prt_newline(&buf); + } + trace_rebalance_extent(c, buf.buf); } count_event(c, rebalance_extent); -- 2.50.1
