]> www.infradead.org Git - users/hch/misc.git/commitdiff
bcachefs: Rework bch2_check_lru_key()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 10 Feb 2025 23:48:12 +0000 (18:48 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 15 Mar 2025 01:02:14 +0000 (21:02 -0400)
It's now easier to add new LRU types.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/lru.c

index dc6b9a80a8b5de34a6a9761edd061543bd0a76c6..98ab8496f29db8d206e486cf937989259d484e87 100644 (file)
@@ -116,49 +116,67 @@ fsck_err:
        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);
 
-       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);
+       struct bbpos bp = lru_pos_to_bp(lru_k);
 
-       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);
-
-       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;
-       }
+       enum bch_lru_type type = lru_type(lru_k);
+       u64 idx = bkey_lru_type_idx(c, type, k);
 
-       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;