bcachefs: Ensure buckets have io_time[READ] set
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 10 Apr 2022 23:59:26 +0000 (19:59 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:31 +0000 (17:09 -0400)
It's an error if a bucket is in state BCH_DATA_cached but not on the LRU
btree - i.e io_time[READ] == 0 - so, make sure it's set before adding
it.

Also, make some of the LRU code a bit clearer and more direct.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/alloc_background.c
fs/bcachefs/btree_gc.c
fs/bcachefs/lru.c
fs/bcachefs/lru.h

index 3be6f0fa89debe36d669924d85a3beb13c1956a7..17b147d15320230ca5c4a894232c5af6911b2d95 100644 (file)
@@ -583,6 +583,11 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
                        return ret;
        }
 
+       if (new_a->data_type == BCH_DATA_cached &&
+           !new_a->io_time[READ])
+               new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now));
+
+
        old_lru = alloc_lru_idx(old_a);
        new_lru = alloc_lru_idx(*new_a);
 
@@ -592,7 +597,7 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,
                if (ret)
                        return ret;
 
-               if (new_lru && new_a->io_time[READ] != new_lru)
+               if (new_a->data_type == BCH_DATA_cached)
                        new_a->io_time[READ] = new_lru;
        }
 
@@ -869,10 +874,10 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
                if (!a.io_time[READ])
                        a.io_time[READ] = atomic64_read(&c->io_clock[READ].now);
 
-               ret = bch2_lru_change(trans,
-                                     alloc_k.k->p.inode,
-                                     alloc_k.k->p.offset,
-                                     0, &a.io_time[READ]);
+               ret = bch2_lru_set(trans,
+                                  alloc_k.k->p.inode,
+                                  alloc_k.k->p.offset,
+                                  &a.io_time[READ]);
                if (ret)
                        goto err;
 
index 0b1717120cc3af5596bdbde101eea155d14e6385..5199f0240fcdd2590aa700c5542f1f091fb610ab 100644 (file)
@@ -1405,6 +1405,13 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
 
        a->v = new;
 
+       /*
+        * The trigger normally makes sure this is set, but we're not running
+        * triggers:
+        */
+       if (a->v.data_type == BCH_DATA_cached && !a->v.io_time[READ])
+               a->v.io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now));
+
        ret = bch2_trans_update(trans, iter, &a->k_i, BTREE_TRIGGER_NORUN);
 fsck_err:
        return ret;
index d8180bc1c6b11a255ebf2b1eaf2b750d9c973eeb..49a0f0d696642fad3ce730e386b52e26973f91a5 100644 (file)
@@ -30,7 +30,7 @@ void bch2_lru_to_text(struct printbuf *out, struct bch_fs *c,
        pr_buf(out, "idx %llu", le64_to_cpu(lru->idx));
 }
 
-static int lru_delete(struct btree_trans *trans, u64 id, u64 idx, u64 time)
+int bch2_lru_delete(struct btree_trans *trans, u64 id, u64 idx, u64 time)
 {
        struct btree_iter iter;
        struct bkey_s_c k;
@@ -72,7 +72,7 @@ err:
        return ret;
 }
 
-static int lru_set(struct btree_trans *trans, u64 lru_id, u64 idx, u64 *time)
+int bch2_lru_set(struct btree_trans *trans, u64 lru_id, u64 idx, u64 *time)
 {
        struct btree_iter iter;
        struct bkey_s_c k;
@@ -119,8 +119,8 @@ int bch2_lru_change(struct btree_trans *trans, u64 id, u64 idx,
        if (old_time == *new_time)
                return 0;
 
-       return  lru_delete(trans, id, idx, old_time) ?:
-               lru_set(trans, id, idx, new_time);
+       return  bch2_lru_delete(trans, id, idx, old_time) ?:
+               bch2_lru_set(trans, id, idx, new_time);
 }
 
 static int bch2_check_lru_key(struct btree_trans *trans,
index e8f508174b0a81671041bf489c7ae169e8c0f3aa..0a01836c07c1d06e29229d8b052f2d5197a4c456 100644 (file)
@@ -10,6 +10,8 @@ void bch2_lru_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
        .val_to_text    = bch2_lru_to_text,     \
 }
 
+int bch2_lru_delete(struct btree_trans *, u64, u64, u64);
+int bch2_lru_set(struct btree_trans *, u64, u64, u64 *);
 int bch2_lru_change(struct btree_trans *, u64, u64, u64, u64 *);
 
 int bch2_check_lrus(struct bch_fs *, bool);