diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-08-22 18:48:09 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:10:11 -0400 |
commit | 71aba590297e9b5f71e760b9336ecb3b44c728ef (patch) | |
tree | 60bdb522f9c74d537ec66d1944eca5d315f6640d /fs/bcachefs/alloc_background.c | |
parent | 4491283f8d827bdfc6baed27028ae636494bdbac (diff) | |
download | linux-stable-71aba590297e9b5f71e760b9336ecb3b44c728ef.tar.gz linux-stable-71aba590297e9b5f71e760b9336ecb3b44c728ef.tar.bz2 linux-stable-71aba590297e9b5f71e760b9336ecb3b44c728ef.zip |
bcachefs: Always check alloc data type
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/alloc_background.c')
-rw-r--r-- | fs/bcachefs/alloc_background.c | 101 |
1 files changed, 42 insertions, 59 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 18b97416750f..ad82fbddcbf8 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -240,7 +240,6 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k, enum bkey_invalid_flags flags, struct printbuf *err) { struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k); - int rw = flags & WRITE; if (alloc_v4_u64s(a.v) > bkey_val_u64s(k.k)) { prt_printf(err, "bad val size (%u > %lu)", @@ -254,71 +253,55 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k, return -BCH_ERR_invalid_bkey; } - if (rw == WRITE && - !(flags & BKEY_INVALID_JOURNAL) && - c->curr_recovery_pass > BCH_RECOVERY_PASS_check_btree_backpointers) { - unsigned i, bp_len = 0; - - for (i = 0; i < BCH_ALLOC_V4_NR_BACKPOINTERS(a.v); i++) - bp_len += alloc_v4_backpointers_c(a.v)[i].bucket_len; + if (alloc_data_type(*a.v, a.v->data_type) != a.v->data_type) { + prt_printf(err, "invalid data type (got %u should be %u)", + a.v->data_type, alloc_data_type(*a.v, a.v->data_type)); + return -BCH_ERR_invalid_bkey; + } - if (bp_len > a.v->dirty_sectors) { - prt_printf(err, "too many backpointers"); + switch (a.v->data_type) { + case BCH_DATA_free: + case BCH_DATA_need_gc_gens: + case BCH_DATA_need_discard: + if (a.v->dirty_sectors || + a.v->cached_sectors || + a.v->stripe) { + prt_printf(err, "empty data type free but have data"); return -BCH_ERR_invalid_bkey; } - } - - if (rw == WRITE) { - if (alloc_data_type(*a.v, a.v->data_type) != a.v->data_type) { - prt_printf(err, "invalid data type (got %u should be %u)", - a.v->data_type, alloc_data_type(*a.v, a.v->data_type)); + break; + case BCH_DATA_sb: + case BCH_DATA_journal: + case BCH_DATA_btree: + case BCH_DATA_user: + case BCH_DATA_parity: + if (!a.v->dirty_sectors) { + prt_printf(err, "data_type %s but dirty_sectors==0", + bch2_data_types[a.v->data_type]); + return -BCH_ERR_invalid_bkey; + } + break; + case BCH_DATA_cached: + if (!a.v->cached_sectors || + a.v->dirty_sectors || + a.v->stripe) { + prt_printf(err, "data type inconsistency"); return -BCH_ERR_invalid_bkey; } - switch (a.v->data_type) { - case BCH_DATA_free: - case BCH_DATA_need_gc_gens: - case BCH_DATA_need_discard: - if (a.v->dirty_sectors || - a.v->cached_sectors || - a.v->stripe) { - prt_printf(err, "empty data type free but have data"); - return -BCH_ERR_invalid_bkey; - } - break; - case BCH_DATA_sb: - case BCH_DATA_journal: - case BCH_DATA_btree: - case BCH_DATA_user: - case BCH_DATA_parity: - if (!a.v->dirty_sectors) { - prt_printf(err, "data_type %s but dirty_sectors==0", - bch2_data_types[a.v->data_type]); - return -BCH_ERR_invalid_bkey; - } - break; - case BCH_DATA_cached: - if (!a.v->cached_sectors || - a.v->dirty_sectors || - a.v->stripe) { - prt_printf(err, "data type inconsistency"); - return -BCH_ERR_invalid_bkey; - } - - if (!a.v->io_time[READ] && - c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_to_lru_refs) { - prt_printf(err, "cached bucket with read_time == 0"); - return -BCH_ERR_invalid_bkey; - } - break; - case BCH_DATA_stripe: - if (!a.v->stripe) { - prt_printf(err, "data_type %s but stripe==0", - bch2_data_types[a.v->data_type]); - return -BCH_ERR_invalid_bkey; - } - break; + if (!a.v->io_time[READ] && + c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_to_lru_refs) { + prt_printf(err, "cached bucket with read_time == 0"); + return -BCH_ERR_invalid_bkey; + } + break; + case BCH_DATA_stripe: + if (!a.v->stripe) { + prt_printf(err, "data_type %s but stripe==0", + bch2_data_types[a.v->data_type]); + return -BCH_ERR_invalid_bkey; } + break; } return 0; |