]> www.infradead.org Git - users/hch/misc.git/commitdiff
bcachefs: Fix bch2_indirect_extent_missing_error()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 19 Feb 2025 18:45:02 +0000 (13:45 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 19 Feb 2025 22:33:13 +0000 (17:33 -0500)
We had some error handling confusion here;
-BCH_ERR_missing_indirect_extent is thrown by
trans_trigger_reflink_p_segment(); at this point we haven't decide
whether we're generating an error.

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

index 376fd0a6e868cc75e8d55ee4b633a6b0bd70ffd6..441e648f28b516e8b4a71bc5355e478cffce6805 100644 (file)
@@ -172,7 +172,7 @@ static int bch2_indirect_extent_missing_error(struct btree_trans *trans,
                                              bool should_commit)
 {
        if (REFLINK_P_ERROR(p.v))
-               return -BCH_ERR_missing_indirect_extent;
+               return 0;
 
        struct bch_fs *c = trans->c;
        u64 live_start  = REFLINK_P_IDX(p.v);
@@ -259,8 +259,6 @@ struct bkey_s_c bch2_lookup_indirect_extent(struct btree_trans *trans,
                return k;
 
        if (unlikely(!bkey_extent_is_reflink_data(k.k))) {
-               bch2_trans_iter_exit(trans, iter);
-
                unsigned size = min((u64) k.k->size,
                                    REFLINK_P_IDX(p.v) + p.k->size + le32_to_cpu(p.v->back_pad) -
                                    reflink_offset);
@@ -268,14 +266,16 @@ struct bkey_s_c bch2_lookup_indirect_extent(struct btree_trans *trans,
 
                int ret = bch2_indirect_extent_missing_error(trans, p, reflink_offset,
                                                             k.k->p.offset, should_commit);
-               if (ret)
+               if (ret) {
+                       bch2_trans_iter_exit(trans, iter);
                        return bkey_s_c_err(ret);
+               }
        } else if (unlikely(REFLINK_P_ERROR(p.v))) {
-               bch2_trans_iter_exit(trans, iter);
-
                int ret = bch2_indirect_extent_not_missing(trans, p, should_commit);
-               if (ret)
+               if (ret) {
+                       bch2_trans_iter_exit(trans, iter);
                        return bkey_s_c_err(ret);
+               }
        }
 
        *offset_into_extent = reflink_offset - bkey_start_offset(k.k);
@@ -300,7 +300,7 @@ static int trans_trigger_reflink_p_segment(struct btree_trans *trans,
        if (ret)
                return ret;
 
-       if (bkey_deleted(k.k)) {
+       if (!bkey_refcount_c(k)) {
                if (!(flags & BTREE_TRIGGER_overwrite))
                        ret = -BCH_ERR_missing_indirect_extent;
                goto next;
@@ -381,8 +381,6 @@ static s64 gc_trigger_reflink_p_segment(struct btree_trans *trans,
 not_found:
        if (flags & BTREE_TRIGGER_check_repair) {
                ret = bch2_indirect_extent_missing_error(trans, p, *idx, next_idx, false);
-               if (ret == -BCH_ERR_missing_indirect_extent)
-                       ret = 0;
                if (ret)
                        goto err;
        }