reflink.c (67e0dd8f0d8b4bf09098c4692abcb43a20089dff) reflink.c (6fed42bb7750e217b0d1169ccfccc7639a3e1d3f)
1// SPDX-License-Identifier: GPL-2.0
2#include "bcachefs.h"
3#include "bkey_buf.h"
4#include "btree_update.h"
5#include "buckets.h"
6#include "extents.h"
7#include "inode.h"
8#include "io.h"
9#include "reflink.h"
1// SPDX-License-Identifier: GPL-2.0
2#include "bcachefs.h"
3#include "bkey_buf.h"
4#include "btree_update.h"
5#include "buckets.h"
6#include "extents.h"
7#include "inode.h"
8#include "io.h"
9#include "reflink.h"
10#include "subvolume.h"
10
11#include <linux/sched/signal.h>
12
13static inline unsigned bkey_type_to_indirect(const struct bkey *k)
14{
15 switch (k->type) {
16 case KEY_TYPE_extent:
17 return KEY_TYPE_reflink_v;

--- 174 unchanged lines hidden (view full) ---

192 }
193
194 if (bkey_cmp(iter->pos, end) >= 0)
195 bch2_btree_iter_set_pos(iter, end);
196 return ret ? bkey_s_c_err(ret) : bkey_s_c_null;
197}
198
199s64 bch2_remap_range(struct bch_fs *c,
11
12#include <linux/sched/signal.h>
13
14static inline unsigned bkey_type_to_indirect(const struct bkey *k)
15{
16 switch (k->type) {
17 case KEY_TYPE_extent:
18 return KEY_TYPE_reflink_v;

--- 174 unchanged lines hidden (view full) ---

193 }
194
195 if (bkey_cmp(iter->pos, end) >= 0)
196 bch2_btree_iter_set_pos(iter, end);
197 return ret ? bkey_s_c_err(ret) : bkey_s_c_null;
198}
199
200s64 bch2_remap_range(struct bch_fs *c,
200 struct bpos dst_start, struct bpos src_start,
201 subvol_inum dst_inum, u64 dst_offset,
202 subvol_inum src_inum, u64 src_offset,
201 u64 remap_sectors, u64 *journal_seq,
202 u64 new_i_size, s64 *i_sectors_delta)
203{
204 struct btree_trans trans;
205 struct btree_iter dst_iter, src_iter;
206 struct bkey_s_c src_k;
207 struct bkey_buf new_dst, new_src;
203 u64 remap_sectors, u64 *journal_seq,
204 u64 new_i_size, s64 *i_sectors_delta)
205{
206 struct btree_trans trans;
207 struct btree_iter dst_iter, src_iter;
208 struct bkey_s_c src_k;
209 struct bkey_buf new_dst, new_src;
210 struct bpos dst_start = POS(dst_inum.inum, dst_offset);
211 struct bpos src_start = POS(src_inum.inum, src_offset);
208 struct bpos dst_end = dst_start, src_end = src_start;
209 struct bpos src_want;
210 u64 dst_done;
211 int ret = 0, ret2 = 0;
212
213 if (!percpu_ref_tryget(&c->writes))
214 return -EROFS;
215

--- 17 unchanged lines hidden (view full) ---

233
234 bch2_trans_begin(&trans);
235
236 if (fatal_signal_pending(current)) {
237 ret = -EINTR;
238 break;
239 }
240
212 struct bpos dst_end = dst_start, src_end = src_start;
213 struct bpos src_want;
214 u64 dst_done;
215 int ret = 0, ret2 = 0;
216
217 if (!percpu_ref_tryget(&c->writes))
218 return -EROFS;
219

--- 17 unchanged lines hidden (view full) ---

237
238 bch2_trans_begin(&trans);
239
240 if (fatal_signal_pending(current)) {
241 ret = -EINTR;
242 break;
243 }
244
245 ret = bch2_subvolume_get_snapshot(&trans, src_inum.subvol,
246 &src_iter.snapshot);
247 if (ret)
248 continue;
249
250 ret = bch2_subvolume_get_snapshot(&trans, dst_inum.subvol,
251 &dst_iter.snapshot);
252 if (ret)
253 continue;
254
241 dst_done = dst_iter.pos.offset - dst_start.offset;
242 src_want = POS(src_start.inode, src_start.offset + dst_done);
243 bch2_btree_iter_set_pos(&src_iter, src_want);
244
245 src_k = get_next_src(&src_iter, src_end);
246 ret = bkey_err(src_k);
247 if (ret)
248 continue;

--- 57 unchanged lines hidden (view full) ---

306
307 do {
308 struct bch_inode_unpacked inode_u;
309 struct btree_iter inode_iter = { NULL };
310
311 bch2_trans_begin(&trans);
312
313 ret2 = bch2_inode_peek(&trans, &inode_iter, &inode_u,
255 dst_done = dst_iter.pos.offset - dst_start.offset;
256 src_want = POS(src_start.inode, src_start.offset + dst_done);
257 bch2_btree_iter_set_pos(&src_iter, src_want);
258
259 src_k = get_next_src(&src_iter, src_end);
260 ret = bkey_err(src_k);
261 if (ret)
262 continue;

--- 57 unchanged lines hidden (view full) ---

320
321 do {
322 struct bch_inode_unpacked inode_u;
323 struct btree_iter inode_iter = { NULL };
324
325 bch2_trans_begin(&trans);
326
327 ret2 = bch2_inode_peek(&trans, &inode_iter, &inode_u,
314 dst_start.inode, BTREE_ITER_INTENT);
328 dst_inum, BTREE_ITER_INTENT);
315
316 if (!ret2 &&
317 inode_u.bi_size < new_i_size) {
318 inode_u.bi_size = new_i_size;
319 ret2 = bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
320 bch2_trans_commit(&trans, NULL, journal_seq, 0);
321 }
322
323 bch2_trans_iter_exit(&trans, &inode_iter);
324 } while (ret2 == -EINTR);
325
326 ret = bch2_trans_exit(&trans) ?: ret;
327 bch2_bkey_buf_exit(&new_src, c);
328 bch2_bkey_buf_exit(&new_dst, c);
329
330 percpu_ref_put(&c->writes);
331
332 return dst_done ?: ret ?: ret2;
333}
329
330 if (!ret2 &&
331 inode_u.bi_size < new_i_size) {
332 inode_u.bi_size = new_i_size;
333 ret2 = bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
334 bch2_trans_commit(&trans, NULL, journal_seq, 0);
335 }
336
337 bch2_trans_iter_exit(&trans, &inode_iter);
338 } while (ret2 == -EINTR);
339
340 ret = bch2_trans_exit(&trans) ?: ret;
341 bch2_bkey_buf_exit(&new_src, c);
342 bch2_bkey_buf_exit(&new_dst, c);
343
344 percpu_ref_put(&c->writes);
345
346 return dst_done ?: ret ?: ret2;
347}