]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/reflink.c
Fixes tests which have broken since 'list' improvements
[bcachefs-tools-debian] / libbcachefs / reflink.c
index 4a4b17f93a2ef3db040e7ad5e6e95529b710eb12..3c473f1380a6bdedd4c5b77d66bb45f63bd5d300 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcachefs.h"
+#include "bkey_on_stack.h"
 #include "btree_update.h"
 #include "extents.h"
 #include "inode.h"
@@ -39,7 +40,7 @@ enum merge_result bch2_reflink_p_merge(struct bch_fs *c,
 
        if ((u64) l.k->size + r.k->size > KEY_SIZE_MAX) {
                bch2_key_resize(l.k, KEY_SIZE_MAX);
-               __bch2_cut_front(l.k->p, _r);
+               bch2_cut_front_s(l.k->p, _r);
                return BCH_MERGE_PARTIAL;
        }
 
@@ -114,7 +115,7 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
        r_v->v.refcount = 0;
        memcpy(r_v->v.start, e->v.start, bkey_val_bytes(&e->k));
 
-       bch2_trans_update(trans, reflink_iter, &r_v->k_i);
+       bch2_trans_update(trans, reflink_iter, &r_v->k_i, 0);
 
        r_p = bch2_trans_kmalloc(trans, sizeof(*r_p));
        if (IS_ERR(r_p))
@@ -125,12 +126,11 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
        set_bkey_val_bytes(&r_p->k, sizeof(r_p->v));
        r_p->v.idx = cpu_to_le64(bkey_start_offset(&r_v->k));
 
-       bch2_trans_update(trans, extent_iter, &r_p->k_i);
+       bch2_trans_update(trans, extent_iter, &r_p->k_i, 0);
 err:
-       if (!IS_ERR(reflink_iter)) {
+       if (!IS_ERR(reflink_iter))
                c->reflink_hint = reflink_iter->pos.offset;
-               bch2_trans_iter_put(trans, reflink_iter);
-       }
+       bch2_trans_iter_put(trans, reflink_iter);
 
        return ret;
 }
@@ -160,26 +160,25 @@ s64 bch2_remap_range(struct bch_fs *c,
        struct btree_trans trans;
        struct btree_iter *dst_iter, *src_iter;
        struct bkey_s_c src_k;
-       BKEY_PADDED(k) new_dst, new_src;
+       BKEY_PADDED(k) new_dst;
+       struct bkey_on_stack new_src;
        struct bpos dst_end = dst_start, src_end = src_start;
        struct bpos dst_want, src_want;
        u64 src_done, dst_done;
        int ret = 0, ret2 = 0;
 
-       if (!(c->sb.features & (1ULL << BCH_FEATURE_REFLINK))) {
-               mutex_lock(&c->sb_lock);
-               if (!(c->sb.features & (1ULL << BCH_FEATURE_REFLINK))) {
-                       c->disk_sb.sb->features[0] |=
-                               cpu_to_le64(1ULL << BCH_FEATURE_REFLINK);
+       if (!c->opts.reflink)
+               return -EOPNOTSUPP;
 
-                       bch2_write_super(c);
-               }
-               mutex_unlock(&c->sb_lock);
-       }
+       if (!percpu_ref_tryget(&c->writes))
+               return -EROFS;
+
+       bch2_check_set_feature(c, BCH_FEATURE_reflink);
 
        dst_end.offset += remap_sectors;
        src_end.offset += remap_sectors;
 
+       bkey_on_stack_init(&new_src);
        bch2_trans_init(&trans, c, BTREE_ITER_MAX, 4096);
 
        src_iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS, src_start,
@@ -188,7 +187,8 @@ s64 bch2_remap_range(struct bch_fs *c,
                                       BTREE_ITER_INTENT);
 
        while (1) {
-               bch2_trans_begin_updates(&trans);
+               bch2_trans_begin(&trans);
+
                trans.mem_top = 0;
 
                if (fatal_signal_pending(current)) {
@@ -219,14 +219,14 @@ s64 bch2_remap_range(struct bch_fs *c,
                        break;
 
                if (src_k.k->type == KEY_TYPE_extent) {
-                       bkey_reassemble(&new_src.k, src_k);
-                       src_k = bkey_i_to_s_c(&new_src.k);
+                       bkey_on_stack_reassemble(&new_src, c, src_k);
+                       src_k = bkey_i_to_s_c(new_src.k);
 
-                       bch2_cut_front(src_iter->pos,   &new_src.k);
-                       bch2_cut_back(src_end,          &new_src.k.k);
+                       bch2_cut_front(src_iter->pos,   new_src.k);
+                       bch2_cut_back(src_end,          new_src.k);
 
                        ret = bch2_make_extent_indirect(&trans, src_iter,
-                                               bkey_i_to_extent(&new_src.k));
+                                               bkey_i_to_extent(new_src.k));
                        if (ret)
                                goto btree_err;
 
@@ -287,13 +287,17 @@ err:
                ret2 = PTR_ERR_OR_ZERO(inode_iter);
 
                if (!ret2 &&
-                   inode_u.bi_size < new_i_size)
+                   inode_u.bi_size < new_i_size) {
+                       inode_u.bi_size = new_i_size;
                        ret2  = bch2_inode_write(&trans, inode_iter, &inode_u) ?:
-                               bch2_trans_commit(&trans, NULL, journal_seq,
-                                                 BTREE_INSERT_ATOMIC);
+                               bch2_trans_commit(&trans, NULL, journal_seq, 0);
+               }
        } while (ret2 == -EINTR);
 
        ret = bch2_trans_exit(&trans) ?: ret;
+       bkey_on_stack_exit(&new_src, c);
+
+       percpu_ref_put(&c->writes);
 
        return dst_done ?: ret ?: ret2;
 }