summaryrefslogtreecommitdiff
path: root/fs/bcachefs/reflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/reflink.c')
-rw-r--r--fs/bcachefs/reflink.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
index 576cfbccf5b5..be4b47bc7438 100644
--- a/fs/bcachefs/reflink.c
+++ b/fs/bcachefs/reflink.c
@@ -7,6 +7,7 @@
#include "inode.h"
#include "io.h"
#include "reflink.h"
+#include "subvolume.h"
#include <linux/sched/signal.h>
@@ -197,7 +198,8 @@ static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
}
s64 bch2_remap_range(struct bch_fs *c,
- struct bpos dst_start, struct bpos src_start,
+ subvol_inum dst_inum, u64 dst_offset,
+ subvol_inum src_inum, u64 src_offset,
u64 remap_sectors, u64 *journal_seq,
u64 new_i_size, s64 *i_sectors_delta)
{
@@ -205,6 +207,8 @@ s64 bch2_remap_range(struct bch_fs *c,
struct btree_iter dst_iter, src_iter;
struct bkey_s_c src_k;
struct bkey_buf new_dst, new_src;
+ struct bpos dst_start = POS(dst_inum.inum, dst_offset);
+ struct bpos src_start = POS(src_inum.inum, src_offset);
struct bpos dst_end = dst_start, src_end = src_start;
struct bpos src_want;
u64 dst_done;
@@ -238,6 +242,16 @@ s64 bch2_remap_range(struct bch_fs *c,
break;
}
+ ret = bch2_subvolume_get_snapshot(&trans, src_inum.subvol,
+ &src_iter.snapshot);
+ if (ret)
+ continue;
+
+ ret = bch2_subvolume_get_snapshot(&trans, dst_inum.subvol,
+ &dst_iter.snapshot);
+ if (ret)
+ continue;
+
dst_done = dst_iter.pos.offset - dst_start.offset;
src_want = POS(src_start.inode, src_start.offset + dst_done);
bch2_btree_iter_set_pos(&src_iter, src_want);
@@ -311,7 +325,7 @@ s64 bch2_remap_range(struct bch_fs *c,
bch2_trans_begin(&trans);
ret2 = bch2_inode_peek(&trans, &inode_iter, &inode_u,
- dst_start.inode, BTREE_ITER_INTENT);
+ dst_inum, BTREE_ITER_INTENT);
if (!ret2 &&
inode_u.bi_size < new_i_size) {