]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/lru.c
Update bcachefs sources to bdf6d7c135 fixup! bcachefs: Kill journal buf bloom filter
[bcachefs-tools-debian] / libbcachefs / lru.c
index 1772ccb2b5602a83aabe49dfd16d0a96b4f9e7b4..ce23b38382f5270a94cb93f1ef01971fab4ffb92 100644 (file)
@@ -8,14 +8,18 @@
 #include "lru.h"
 #include "recovery.h"
 
-const char *bch2_lru_invalid(const struct bch_fs *c, struct bkey_s_c k)
+int bch2_lru_invalid(const struct bch_fs *c, struct bkey_s_c k,
+                    int rw, struct printbuf *err)
 {
        const struct bch_lru *lru = bkey_s_c_to_lru(k).v;
 
-       if (bkey_val_bytes(k.k) < sizeof(*lru))
-               return "incorrect value size";
+       if (bkey_val_bytes(k.k) < sizeof(*lru)) {
+               pr_buf(err, "incorrect value size (%zu < %zu)",
+                      bkey_val_bytes(k.k), sizeof(*lru));
+               return -EINVAL;
+       }
 
-       return NULL;
+       return 0;
 }
 
 void bch2_lru_to_text(struct printbuf *out, struct bch_fs *c,
@@ -26,12 +30,13 @@ 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 bkey_s_c orig_k)
 {
-       struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct bkey_s_c k;
        u64 existing_idx;
+       struct printbuf buf = PRINTBUF;
        int ret = 0;
 
        if (!time)
@@ -47,18 +52,20 @@ static int lru_delete(struct btree_trans *trans, u64 id, u64 idx, u64 time)
                goto err;
 
        if (k.k->type != KEY_TYPE_lru) {
-               bch2_fs_inconsistent(c,
-                       "pointer to nonexistent lru %llu:%llu",
-                       id, time);
+               bch2_bkey_val_to_text(&buf, trans->c, orig_k);
+               bch2_trans_inconsistent(trans,
+                       "pointer to nonexistent lru %llu:%llu\n%s",
+                       id, time, buf.buf);
                ret = -EIO;
                goto err;
        }
 
        existing_idx = le64_to_cpu(bkey_s_c_to_lru(k).v->idx);
        if (existing_idx != idx) {
-               bch2_fs_inconsistent(c,
-                       "lru %llu:%llu with wrong backpointer: got %llu, should be %llu",
-                       id, time, existing_idx, idx);
+               bch2_bkey_val_to_text(&buf, trans->c, orig_k);
+               bch2_trans_inconsistent(trans,
+                       "lru %llu:%llu with wrong backpointer: got %llu, should be %llu\n%s",
+                       id, time, existing_idx, idx, buf.buf);
                ret = -EIO;
                goto err;
        }
@@ -66,10 +73,11 @@ static int lru_delete(struct btree_trans *trans, u64 id, u64 idx, u64 time)
        ret = bch2_btree_delete_at(trans, &iter, 0);
 err:
        bch2_trans_iter_exit(trans, &iter);
+       printbuf_exit(&buf);
        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;
@@ -111,13 +119,14 @@ err:
 }
 
 int bch2_lru_change(struct btree_trans *trans, u64 id, u64 idx,
-                   u64 old_time, u64 *new_time)
+                   u64 old_time, u64 *new_time,
+                   struct bkey_s_c k)
 {
        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, k) ?:
+               bch2_lru_set(trans, id, idx, new_time);
 }
 
 static int bch2_check_lru_key(struct btree_trans *trans,
@@ -126,10 +135,10 @@ static int bch2_check_lru_key(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct bkey_s_c lru_k, k;
-       struct bkey_alloc_unpacked a;
+       struct bch_alloc_v4 a;
        struct printbuf buf1 = PRINTBUF;
        struct printbuf buf2 = PRINTBUF;
-       u64 idx;
+       struct bpos alloc_pos;
        int ret;
 
        lru_k = bch2_btree_iter_peek(lru_iter);
@@ -140,19 +149,24 @@ static int bch2_check_lru_key(struct btree_trans *trans,
        if (ret)
                return ret;
 
-       idx = le64_to_cpu(bkey_s_c_to_lru(lru_k).v->idx);
+       alloc_pos = POS(lru_k.k->p.inode,
+                       le64_to_cpu(bkey_s_c_to_lru(lru_k).v->idx));
+
+       if (fsck_err_on(!bch2_dev_bucket_exists(c, alloc_pos), c,
+                       "lru key points to nonexistent device:bucket %llu:%llu",
+                       alloc_pos.inode, alloc_pos.offset))
+               return bch2_btree_delete_at(trans, lru_iter, 0);
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
-                            POS(lru_k.k->p.inode, idx), 0);
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc, alloc_pos, 0);
        k = bch2_btree_iter_peek_slot(&iter);
        ret = bkey_err(k);
        if (ret)
                goto err;
 
-       a = bch2_alloc_unpack(k);
+       bch2_alloc_to_v4(k, &a);
 
-       if (fsck_err_on(bucket_state(a) != BUCKET_cached ||
-                       a.read_time != lru_k.k->p.offset, c,
+       if (fsck_err_on(a.data_type != BCH_DATA_cached ||
+                       a.io_time[READ] != lru_k.k->p.offset, c,
                        "incorrect lru entry %s\n"
                        "  for %s",
                        (bch2_bkey_val_to_text(&buf1, c, lru_k), buf1.buf),
@@ -190,7 +204,9 @@ int bch2_check_lrus(struct bch_fs *c, bool initial)
 
        for_each_btree_key(&trans, iter, BTREE_ID_lru, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
-               ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+               ret = __bch2_trans_do(&trans, NULL, NULL,
+                                     BTREE_INSERT_NOFAIL|
+                                     BTREE_INSERT_LAZY_RW,
                        bch2_check_lru_key(&trans, &iter, initial));
                if (ret)
                        break;