We need to validate fragmenation_lru is consistent with sectors counts and bucket type.
Signed-off-by: Daniel Hill <[email protected]> --- fs/bcachefs/alloc_background.c | 18 ++++++++++++++++++ fs/bcachefs/sb-errors_types.h | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 4de4036ded06..3bf2a2daad93 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -292,6 +292,24 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k, case BCH_DATA_stripe: break; } + + /* this check fails to work during device removal evacuate etc, + * so fall back to something less robust + */ + if (bch2_dev_exists2(c, a.k->p.inode)) { + u64 fragmentation_lru = alloc_lru_idx_fragmentation(*a.v, + bch_dev_bkey_exists(c, a.k->p.inode)); + + bkey_fsck_err_on(a.v->fragmentation_lru != fragmentation_lru, c, err, + alloc_lru_fragmentation_wrong, + "bad fragmentation_lru (got %llu should be %llu)", + a.v->fragmentation_lru, fragmentation_lru); + } + else + bkey_fsck_err_on(a.v->fragmentation_lru && !data_type_movable(a.v->data_type), + c, err, alloc_lru_fragmentation_wrong, + "alloc type %s is unmovabled but fragmentation_lru not 0 (%llu)", + bch2_data_type_str(a.v->data_type), a.v->fragmentation_lru); fsck_err: return ret; } diff --git a/fs/bcachefs/sb-errors_types.h b/fs/bcachefs/sb-errors_types.h index 0df4b0e7071a..cc70a93dfd0d 100644 --- a/fs/bcachefs/sb-errors_types.h +++ b/fs/bcachefs/sb-errors_types.h @@ -264,7 +264,8 @@ x(subvol_children_not_set, 256) \ x(subvol_children_bad, 257) \ x(subvol_loop, 258) \ - x(subvol_unreachable, 259) + x(subvol_unreachable, 259) \ + x(alloc_lru_fragmentation_wrong, 260) enum bch_sb_error_id { #define x(t, n) BCH_FSCK_ERR_##t = n, -- 2.43.0
