]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/backpointers.c
Move c_src dirs back to toplevel
[bcachefs-tools-debian] / libbcachefs / backpointers.c
index 2f194f86cebf4eb54f95cdafd02a719b9b056d84..e358a2ffffdea48c80eee18ab299cd7103d72991 100644 (file)
@@ -3,6 +3,7 @@
 #include "bbpos.h"
 #include "alloc_background.h"
 #include "backpointers.h"
+#include "bkey_buf.h"
 #include "btree_cache.h"
 #include "btree_update.h"
 #include "btree_update_interior.h"
@@ -390,39 +391,32 @@ fsck_err:
 /* verify that every backpointer has a corresponding alloc key */
 int bch2_check_btree_backpointers(struct bch_fs *c)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
-       int ret;
-
-       ret = bch2_trans_run(c,
+       int ret = bch2_trans_run(c,
                for_each_btree_key_commit(trans, iter,
                        BTREE_ID_backpointers, POS_MIN, 0, k,
                        NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                  bch2_check_btree_backpointer(trans, &iter, k)));
-       if (ret)
-               bch_err_fn(c, ret);
+       bch_err_fn(c, ret);
        return ret;
 }
 
-struct bpos_level {
-       unsigned        level;
-       struct bpos     pos;
-};
-
 static int check_bp_exists(struct btree_trans *trans,
                           struct bpos bucket,
                           struct bch_backpointer bp,
                           struct bkey_s_c orig_k,
                           struct bpos bucket_start,
                           struct bpos bucket_end,
-                          struct bpos_level *last_flushed)
+                          struct bkey_buf *last_flushed)
 {
        struct bch_fs *c = trans->c;
        struct btree_iter bp_iter = { NULL };
        struct printbuf buf = PRINTBUF;
        struct bkey_s_c bp_k;
+       struct bkey_buf tmp;
        int ret;
 
+       bch2_bkey_buf_init(&tmp);
+
        if (bpos_lt(bucket, bucket_start) ||
            bpos_gt(bucket, bucket_end))
                return 0;
@@ -439,14 +433,21 @@ static int check_bp_exists(struct btree_trans *trans,
 
        if (bp_k.k->type != KEY_TYPE_backpointer ||
            memcmp(bkey_s_c_to_backpointer(bp_k).v, &bp, sizeof(bp))) {
-               if (last_flushed->level != bp.level ||
-                   !bpos_eq(last_flushed->pos, orig_k.k->p)) {
+               if (!bpos_eq(orig_k.k->p, last_flushed->k->k.p) ||
+                   bkey_bytes(orig_k.k) != bkey_bytes(&last_flushed->k->k) ||
+                   memcmp(orig_k.v, &last_flushed->k->v, bkey_val_bytes(orig_k.k))) {
+                       bch2_bkey_buf_reassemble(&tmp, c, orig_k);
+
+                       if (bp.level) {
+                               bch2_trans_unlock(trans);
+                               bch2_btree_interior_updates_flush(c);
+                       }
+
                        ret = bch2_btree_write_buffer_flush_sync(trans);
                        if (ret)
                                goto err;
 
-                       last_flushed->level = bp.level;
-                       last_flushed->pos = orig_k.k->p;
+                       bch2_bkey_buf_copy(last_flushed, c, tmp.k);
                        ret = -BCH_ERR_transaction_restart_write_buffer_flush;
                        goto out;
                }
@@ -456,6 +457,7 @@ out:
 err:
 fsck_err:
        bch2_trans_iter_exit(trans, &bp_iter);
+       bch2_bkey_buf_exit(&tmp, c);
        printbuf_exit(&buf);
        return ret;
 missing:
@@ -465,8 +467,7 @@ missing:
        prt_printf(&buf, "\nbp pos ");
        bch2_bpos_to_text(&buf, bp_iter.pos);
 
-       if (c->sb.version_upgrade_complete < bcachefs_metadata_version_backpointers ||
-           c->opts.reconstruct_alloc ||
+       if (c->opts.reconstruct_alloc ||
            fsck_err(c, ptr_to_missing_backpointer, "%s", buf.buf))
                ret = bch2_bucket_backpointer_mod(trans, bucket, bp, orig_k, true);
 
@@ -477,7 +478,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
                                        enum btree_id btree, unsigned level,
                                        struct bpos bucket_start,
                                        struct bpos bucket_end,
-                                       struct bpos_level *last_flushed,
+                                       struct bkey_buf *last_flushed,
                                        struct bkey_s_c k)
 {
        struct bch_fs *c = trans->c;
@@ -511,7 +512,7 @@ static int check_btree_root_to_backpointers(struct btree_trans *trans,
                                            enum btree_id btree_id,
                                            struct bpos bucket_start,
                                            struct bpos bucket_end,
-                                           struct bpos_level *last_flushed,
+                                           struct bkey_buf *last_flushed,
                                            int *level)
 {
        struct bch_fs *c = trans->c;
@@ -616,10 +617,13 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
        struct btree_iter iter;
        enum btree_id btree_id;
        struct bkey_s_c k;
+       struct bkey_buf last_flushed;
        int ret = 0;
 
+       bch2_bkey_buf_init(&last_flushed);
+       bkey_init(&last_flushed.k->k);
+
        for (btree_id = 0; btree_id < btree_id_nr_alive(c); btree_id++) {
-               struct bpos_level last_flushed = { UINT_MAX, POS_MIN };
                int level, depth = btree_type_has_ptrs(btree_id) ? 0 : 1;
 
                ret = commit_do(trans, NULL, NULL,
@@ -651,6 +655,8 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
                                }
                                if (ret)
                                        break;
+                               if (bpos_eq(iter.pos, SPOS_MAX))
+                                       break;
                                bch2_btree_iter_advance(&iter);
                        }
                        bch2_trans_iter_exit(trans, &iter);
@@ -662,6 +668,7 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
                }
        }
 
+       bch2_bkey_buf_exit(&last_flushed, c);
        return 0;
 }
 
@@ -756,8 +763,7 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c)
        }
        bch2_trans_put(trans);
 
-       if (ret)
-               bch_err_fn(c, ret);
+       bch_err_fn(c, ret);
        return ret;
 }
 
@@ -811,8 +817,6 @@ static int bch2_check_backpointers_to_extents_pass(struct btree_trans *trans,
                                                   struct bbpos start,
                                                   struct bbpos end)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
        struct bpos last_flushed_pos = SPOS_MAX;
 
        return for_each_btree_key_commit(trans, iter, BTREE_ID_backpointers,
@@ -864,7 +868,6 @@ int bch2_check_backpointers_to_extents(struct bch_fs *c)
        }
        bch2_trans_put(trans);
 
-       if (ret)
-               bch_err_fn(c, ret);
+       bch_err_fn(c, ret);
        return ret;
 }