]> www.infradead.org Git - linux.git/commitdiff
bcachefs: Add write buffer flush param to backpointer_get_key()
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 15 Nov 2024 03:13:29 +0000 (22:13 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 29 Dec 2024 18:30:39 +0000 (13:30 -0500)
In an upcoming patch bch2_backpointer_get_key() will be repairing when
it finds a dangling backpointer; it will need to flush the btree write
buffer before it can definitively say there's an error.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/backpointers.c
fs/bcachefs/backpointers.h
fs/bcachefs/ec.c
fs/bcachefs/move.c

index 98d89133fc7545e90d54d53ac5ea8d8638c41a07..d2f0b3140983f22c73f509950df714b59cc460cf 100644 (file)
@@ -218,7 +218,8 @@ static void backpointer_target_not_found(struct btree_trans *trans,
 struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans,
                                         struct bkey_s_c_backpointer bp,
                                         struct btree_iter *iter,
-                                        unsigned iter_flags)
+                                        unsigned iter_flags,
+                                        struct bkey_buf *last_flushed)
 {
        struct bch_fs *c = trans->c;
 
@@ -245,7 +246,7 @@ struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans,
                backpointer_target_not_found(trans, bp, k);
                return bkey_s_c_null;
        } else {
-               struct btree *b = bch2_backpointer_get_node(trans, bp, iter);
+               struct btree *b = bch2_backpointer_get_node(trans, bp, iter, last_flushed);
 
                if (IS_ERR_OR_NULL(b)) {
                        bch2_trans_iter_exit(trans, iter);
@@ -257,7 +258,8 @@ struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans,
 
 struct btree *bch2_backpointer_get_node(struct btree_trans *trans,
                                        struct bkey_s_c_backpointer bp,
-                                       struct btree_iter *iter)
+                                       struct btree_iter *iter,
+                                       struct bkey_buf *last_flushed)
 {
        struct bch_fs *c = trans->c;
 
@@ -486,7 +488,7 @@ check_existing_bp:
        struct bkey_s_c_backpointer other_bp = bkey_s_c_to_backpointer(bp_k);
 
        struct bkey_s_c other_extent =
-               bch2_backpointer_get_key(trans, other_bp, &other_extent_iter, 0);
+               bch2_backpointer_get_key(trans, other_bp, &other_extent_iter, 0, &s->last_flushed);
        ret = bkey_err(other_extent);
        if (ret == -BCH_ERR_backpointer_to_overwritten_btree_node)
                ret = 0;
@@ -866,7 +868,7 @@ static int check_one_backpointer(struct btree_trans *trans,
                return 0;
 
        struct btree_iter iter;
-       struct bkey_s_c k = bch2_backpointer_get_key(trans, bp, &iter, 0);
+       struct bkey_s_c k = bch2_backpointer_get_key(trans, bp, &iter, 0, last_flushed);
        int ret = bkey_err(k);
        if (ret == -BCH_ERR_backpointer_to_overwritten_btree_node)
                return 0;
index 65ede8adbc361283be2714cb6bbb4d75ff8dee9a..060dad1521ee37801b7ed1dd4afa60c9032d6d69 100644 (file)
@@ -158,10 +158,11 @@ static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
        };
 }
 
+struct bkey_buf;
 struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *, struct bkey_s_c_backpointer,
-                                        struct btree_iter *, unsigned);
+                                        struct btree_iter *, unsigned, struct bkey_buf *);
 struct btree *bch2_backpointer_get_node(struct btree_trans *, struct bkey_s_c_backpointer,
-                                       struct btree_iter *);
+                                       struct btree_iter *, struct bkey_buf *);
 
 int bch2_check_btree_backpointers(struct bch_fs *);
 int bch2_check_extents_to_backpointers(struct bch_fs *);
index 3e7e41cd8380603e6050cbc6c23ef7d17234f876..d2a5e76e64791ed9ca3114382cb8856661f5a4a1 100644 (file)
@@ -1265,7 +1265,8 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
                                   struct bch_dev *ca,
                                   struct bpos bucket, u8 gen,
                                   struct ec_stripe_buf *s,
-                                  struct bkey_s_c_backpointer bp)
+                                  struct bkey_s_c_backpointer bp,
+                                  struct bkey_buf *last_flushed)
 {
        struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
        struct bch_fs *c = trans->c;
@@ -1282,7 +1283,7 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
                struct btree_iter node_iter;
                struct btree *b;
 
-               b = bch2_backpointer_get_node(trans, bp, &node_iter);
+               b = bch2_backpointer_get_node(trans, bp, &node_iter, last_flushed);
                bch2_trans_iter_exit(trans, &node_iter);
 
                if (!b)
@@ -1296,7 +1297,7 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
                return -EIO;
        }
 
-       k = bch2_backpointer_get_key(trans, bp, &iter, BTREE_ITER_intent);
+       k = bch2_backpointer_get_key(trans, bp, &iter, BTREE_ITER_intent, last_flushed);
        ret = bkey_err(k);
        if (ret)
                return ret;
@@ -1363,6 +1364,10 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
 
        struct bpos bucket_pos = PTR_BUCKET_POS(ca, &ptr);
 
+       struct bkey_buf last_flushed;
+       bch2_bkey_buf_init(&last_flushed);
+       bkey_init(&last_flushed.k->k);
+
        ret = for_each_btree_key_max_commit(trans, bp_iter, BTREE_ID_backpointers,
                        bucket_pos_to_bp_start(ca, bucket_pos),
                        bucket_pos_to_bp_end(ca, bucket_pos), 0, bp_k,
@@ -1376,9 +1381,10 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
                        continue;
 
                ec_stripe_update_extent(trans, ca, bucket_pos, ptr.gen, s,
-                                       bkey_s_c_to_backpointer(bp_k));
+                                       bkey_s_c_to_backpointer(bp_k), &last_flushed);
        }));
 
+       bch2_bkey_buf_exit(&last_flushed, c);
        bch2_dev_put(ca);
        return ret;
 }
index 6d38afcaaaab9e72fa8b102194414d642e415de8..184620d5a3b4500c3b5b0c2d73d57de4d19633d3 100644 (file)
@@ -677,6 +677,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
        struct bkey_s_c k;
        struct data_update_opts data_opts;
        unsigned sectors_moved = 0;
+       struct bkey_buf last_flushed;
        int ret = 0;
 
        struct bch_dev *ca = bch2_dev_tryget(c, bucket.inode);
@@ -685,6 +686,8 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
 
        trace_bucket_evacuate(c, &bucket);
 
+       bch2_bkey_buf_init(&last_flushed);
+       bkey_init(&last_flushed.k->k);
        bch2_bkey_buf_init(&sk);
 
        /*
@@ -726,7 +729,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
                struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
 
                if (!bp.v->level) {
-                       k = bch2_backpointer_get_key(trans, bp, &iter, 0);
+                       k = bch2_backpointer_get_key(trans, bp, &iter, 0, &last_flushed);
                        ret = bkey_err(k);
                        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                                continue;
@@ -784,7 +787,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
                } else {
                        struct btree *b;
 
-                       b = bch2_backpointer_get_node(trans, bp, &iter);
+                       b = bch2_backpointer_get_node(trans, bp, &iter, &last_flushed);
                        ret = PTR_ERR_OR_ZERO(b);
                        if (ret == -BCH_ERR_backpointer_to_overwritten_btree_node)
                                goto next;
@@ -822,6 +825,7 @@ err:
        bch2_trans_iter_exit(trans, &bp_iter);
        bch2_dev_put(ca);
        bch2_bkey_buf_exit(&sk, c);
+       bch2_bkey_buf_exit(&last_flushed, c);
        return ret;
 }