mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
bcachefs: Rework bch2_check_lru_key()
It's now easier to add new LRU types. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
3aff608b86
commit
bc76ba70d2
|
|
@ -116,49 +116,67 @@ int bch2_lru_check_set(struct btree_trans *trans,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct bbpos lru_pos_to_bp(struct bkey_s_c lru_k)
|
||||
{
|
||||
enum bch_lru_type type = lru_type(lru_k);
|
||||
|
||||
switch (type) {
|
||||
case BCH_LRU_read:
|
||||
case BCH_LRU_fragmentation:
|
||||
return BBPOS(BTREE_ID_alloc, u64_to_bucket(lru_k.k->p.offset));
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static u64 bkey_lru_type_idx(struct bch_fs *c,
|
||||
enum bch_lru_type type,
|
||||
struct bkey_s_c k)
|
||||
{
|
||||
struct bch_alloc_v4 a_convert;
|
||||
const struct bch_alloc_v4 *a;
|
||||
|
||||
switch (type) {
|
||||
case BCH_LRU_read:
|
||||
a = bch2_alloc_to_v4(k, &a_convert);
|
||||
return alloc_lru_idx_read(*a);
|
||||
case BCH_LRU_fragmentation: {
|
||||
a = bch2_alloc_to_v4(k, &a_convert);
|
||||
|
||||
rcu_read_lock();
|
||||
struct bch_dev *ca = bch2_dev_rcu_noerror(c, k.k->p.inode);
|
||||
u64 idx = ca
|
||||
? alloc_lru_idx_fragmentation(*a, ca)
|
||||
: 0;
|
||||
rcu_read_unlock();
|
||||
return idx;
|
||||
}
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static int bch2_check_lru_key(struct btree_trans *trans,
|
||||
struct btree_iter *lru_iter,
|
||||
struct bkey_s_c lru_k,
|
||||
struct bkey_buf *last_flushed)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_alloc_v4 a_convert;
|
||||
const struct bch_alloc_v4 *a;
|
||||
struct printbuf buf1 = PRINTBUF;
|
||||
struct printbuf buf2 = PRINTBUF;
|
||||
enum bch_lru_type type = lru_type(lru_k);
|
||||
struct bpos alloc_pos = u64_to_bucket(lru_k.k->p.offset);
|
||||
u64 idx;
|
||||
int ret;
|
||||
|
||||
struct bch_dev *ca = bch2_dev_bucket_tryget_noerror(c, alloc_pos);
|
||||
struct bbpos bp = lru_pos_to_bp(lru_k);
|
||||
|
||||
if (fsck_err_on(!ca,
|
||||
trans, lru_entry_to_invalid_bucket,
|
||||
"lru key points to nonexistent device:bucket %llu:%llu",
|
||||
alloc_pos.inode, alloc_pos.offset))
|
||||
return bch2_btree_bit_mod_buffered(trans, BTREE_ID_lru, lru_iter->pos, false);
|
||||
|
||||
k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc, alloc_pos, 0);
|
||||
ret = bkey_err(k);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, bp.btree, bp.pos, 0);
|
||||
int ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
a = bch2_alloc_to_v4(k, &a_convert);
|
||||
enum bch_lru_type type = lru_type(lru_k);
|
||||
u64 idx = bkey_lru_type_idx(c, type, k);
|
||||
|
||||
switch (type) {
|
||||
case BCH_LRU_read:
|
||||
idx = alloc_lru_idx_read(*a);
|
||||
break;
|
||||
case BCH_LRU_fragmentation:
|
||||
idx = alloc_lru_idx_fragmentation(*a, ca);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lru_k.k->type != KEY_TYPE_set ||
|
||||
lru_pos_time(lru_k.k->p) != idx) {
|
||||
if (lru_pos_time(lru_k.k->p) != idx) {
|
||||
ret = bch2_btree_write_buffer_maybe_flush(trans, lru_k, last_flushed);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
@ -176,7 +194,6 @@ static int bch2_check_lru_key(struct btree_trans *trans,
|
|||
err:
|
||||
fsck_err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_dev_put(ca);
|
||||
printbuf_exit(&buf2);
|
||||
printbuf_exit(&buf1);
|
||||
return ret;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user