diff options
Diffstat (limited to 'fs/bcachefs/alloc_background.c')
-rw-r--r-- | fs/bcachefs/alloc_background.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index ebb978e68971..42301215e6d7 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -1756,37 +1756,38 @@ void bch2_do_discards(struct bch_fs *c) static int invalidate_one_bucket(struct btree_trans *trans, struct btree_iter *lru_iter, - struct bpos bucket, + struct bkey_s_c lru_k, s64 *nr_to_invalidate) { struct bch_fs *c = trans->c; struct btree_iter alloc_iter = { NULL }; - struct bkey_i_alloc_v4 *a; + struct bkey_i_alloc_v4 *a = NULL; struct printbuf buf = PRINTBUF; + struct bpos bucket = u64_to_bucket(lru_k.k->p.offset); unsigned cached_sectors; int ret = 0; if (*nr_to_invalidate <= 0) return 1; + if (!bch2_dev_bucket_exists(c, bucket)) { + prt_str(&buf, "lru entry points to invalid bucket"); + goto err; + } + a = bch2_trans_start_alloc_update(trans, &alloc_iter, bucket); ret = PTR_ERR_OR_ZERO(a); if (ret) goto out; if (lru_pos_time(lru_iter->pos) != alloc_lru_idx(a->v)) { - prt_printf(&buf, "alloc key does not point back to lru entry when invalidating bucket:\n "); - bch2_bpos_to_text(&buf, lru_iter->pos); - prt_printf(&buf, "\n "); - bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&a->k_i)); - - bch_err(c, "%s", buf.buf); - if (test_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags)) { - bch2_inconsistent_error(c); - ret = -EINVAL; - } + prt_str(&buf, "alloc key does not point back to lru entry when invalidating bucket:"); + goto err; + } - goto out; + if (a->v.data_type != BCH_DATA_cached) { + prt_str(&buf, "lru entry points to non cached bucket:"); + goto err; } if (!a->v.cached_sectors) @@ -1815,6 +1816,26 @@ out: bch2_trans_iter_exit(trans, &alloc_iter); printbuf_exit(&buf); return ret; +err: + prt_str(&buf, "\n lru key: "); + bch2_bkey_val_to_text(&buf, c, lru_k); + + prt_str(&buf, "\n lru entry: "); + bch2_lru_pos_to_text(&buf, lru_iter->pos); + + prt_str(&buf, "\n alloc key: "); + if (!a) + bch2_bpos_to_text(&buf, bucket); + else + bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&a->k_i)); + + bch_err(c, "%s", buf.buf); + if (test_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags)) { + bch2_inconsistent_error(c); + ret = -EINVAL; + } + + goto out; } static void bch2_do_invalidates_work(struct work_struct *work) @@ -1837,9 +1858,7 @@ static void bch2_do_invalidates_work(struct work_struct *work) lru_pos(ca->dev_idx, 0, 0), lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX), BTREE_ITER_INTENT, k, - invalidate_one_bucket(&trans, &iter, - u64_to_bucket(k.k->p.offset), - &nr_to_invalidate)); + invalidate_one_bucket(&trans, &iter, k, &nr_to_invalidate)); if (ret < 0) { percpu_ref_put(&ca->ref); |