move.c 26.8 KB
Newer Older
Kent Overstreet's avatar
Kent Overstreet committed
1 2 3
// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
4
#include "alloc_foreground.h"
5
#include "bkey_buf.h"
Kent Overstreet's avatar
Kent Overstreet committed
6 7
#include "btree_gc.h"
#include "btree_update.h"
8
#include "btree_update_interior.h"
Kent Overstreet's avatar
Kent Overstreet committed
9
#include "buckets.h"
10
#include "disk_groups.h"
Kent Overstreet's avatar
Kent Overstreet committed
11 12 13 14 15 16
#include "inode.h"
#include "io.h"
#include "journal_reclaim.h"
#include "keylist.h"
#include "move.h"
#include "replicas.h"
17
#include "subvolume.h"
Kent Overstreet's avatar
Kent Overstreet committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include "super-io.h"
#include "trace.h"

#include <linux/ioprio.h>
#include <linux/kthread.h>

#define SECTORS_IN_FLIGHT_PER_DEVICE	2048

struct moving_io {
	struct list_head	list;
	struct closure		cl;
	bool			read_completed;

	unsigned		read_sectors;
	unsigned		write_sectors;

	struct bch_read_bio	rbio;

	struct migrate_write	write;
	/* Must be last since it is variable size */
	struct bio_vec		bi_inline_vecs[0];
};

struct moving_context {
	/* Closure for waiting on all reads and writes to complete */
	struct closure		cl;

	struct bch_move_stats	*stats;

	struct list_head	reads;

	/* in flight sectors: */
	atomic_t		read_sectors;
	atomic_t		write_sectors;

	wait_queue_head_t	wait;
};

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
static int insert_snapshot_whiteouts(struct btree_trans *trans,
				     enum btree_id id,
				     struct bpos old_pos,
				     struct bpos new_pos)
{
	struct bch_fs *c = trans->c;
	struct btree_iter iter, update_iter;
	struct bkey_s_c k;
	struct snapshots_seen s;
	int ret;

	if (!btree_type_has_snapshots(id))
		return 0;

	snapshots_seen_init(&s);

	if (!bkey_cmp(old_pos, new_pos))
		return 0;

	if (!snapshot_t(c, old_pos.snapshot)->children[0])
		return 0;

	bch2_trans_iter_init(trans, &iter, id, old_pos,
			     BTREE_ITER_NOT_EXTENTS|
			     BTREE_ITER_ALL_SNAPSHOTS);
	while (1) {
next:
		k = bch2_btree_iter_prev(&iter);
		ret = bkey_err(k);
		if (ret)
			break;

		if (bkey_cmp(old_pos, k.k->p))
			break;

		if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, old_pos.snapshot)) {
			struct bkey_i *update;
			size_t i;

			for (i = 0; i < s.nr; i++)
				if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, s.d[i]))
					goto next;

			update = bch2_trans_kmalloc(trans, sizeof(struct bkey_i));

			ret = PTR_ERR_OR_ZERO(update);
			if (ret)
				break;

			bkey_init(&update->k);
			update->k.p = new_pos;
			update->k.p.snapshot = k.k->p.snapshot;

			bch2_trans_iter_init(trans, &update_iter, id, update->k.p,
					     BTREE_ITER_NOT_EXTENTS|
					     BTREE_ITER_ALL_SNAPSHOTS|
					     BTREE_ITER_INTENT);
			ret   = bch2_btree_iter_traverse(&update_iter) ?:
				bch2_trans_update(trans, &update_iter, update,
					  BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
			bch2_trans_iter_exit(trans, &update_iter);
			if (ret)
				break;

			ret = snapshots_seen_add(c, &s, k.k->p.snapshot);
			if (ret)
				break;
		}
	}
	bch2_trans_iter_exit(trans, &iter);
	kfree(s.d);

	return ret;
}

131
int bch2_migrate_index_update(struct bch_write_op *op)
Kent Overstreet's avatar
Kent Overstreet committed
132 133
{
	struct bch_fs *c = op->c;
134
	struct btree_trans trans;
Kent Overstreet's avatar
Kent Overstreet committed
135
	struct btree_iter iter;
Kent Overstreet's avatar
Kent Overstreet committed
136 137 138
	struct migrate_write *m =
		container_of(op, struct migrate_write, op);
	struct keylist *keys = &op->insert_keys;
139
	struct bkey_buf _new, _insert;
Kent Overstreet's avatar
Kent Overstreet committed
140 141
	int ret = 0;

142 143 144 145
	bch2_bkey_buf_init(&_new);
	bch2_bkey_buf_init(&_insert);
	bch2_bkey_buf_realloc(&_insert, c, U8_MAX);

146
	bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
147

Kent Overstreet's avatar
Kent Overstreet committed
148 149 150
	bch2_trans_iter_init(&trans, &iter, m->btree_id,
			     bkey_start_pos(&bch2_keylist_front(keys)->k),
			     BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
Kent Overstreet's avatar
Kent Overstreet committed
151 152

	while (1) {
153
		struct bkey_s_c k;
Kent Overstreet's avatar
Kent Overstreet committed
154
		struct bkey_i *insert;
155
		struct bkey_i_extent *new;
156 157
		const union bch_extent_entry *entry;
		struct extent_ptr_decoded p;
158
		struct bpos next_pos;
Kent Overstreet's avatar
Kent Overstreet committed
159
		bool did_work = false;
160 161
		bool extending = false, should_check_enospc;
		s64 i_sectors_delta = 0, disk_sectors_delta = 0;
Kent Overstreet's avatar
Kent Overstreet committed
162

163
		bch2_trans_begin(&trans);
164

Kent Overstreet's avatar
Kent Overstreet committed
165
		k = bch2_btree_iter_peek_slot(&iter);
166
		ret = bkey_err(k);
167 168
		if (ret)
			goto err;
169 170

		new = bkey_i_to_extent(bch2_keylist_front(keys));
Kent Overstreet's avatar
Kent Overstreet committed
171 172

		if (bversion_cmp(k.k->version, new->k.version) ||
173
		    !bch2_bkey_matches_ptr(c, k, m->ptr, m->offset))
Kent Overstreet's avatar
Kent Overstreet committed
174 175
			goto nomatch;

176 177
		bkey_reassemble(_insert.k, k);
		insert = _insert.k;
Kent Overstreet's avatar
Kent Overstreet committed
178

179 180
		bch2_bkey_buf_copy(&_new, c, bch2_keylist_front(keys));
		new = bkey_i_to_extent(_new.k);
Kent Overstreet's avatar
Kent Overstreet committed
181
		bch2_cut_front(iter.pos, &new->k_i);
Kent Overstreet's avatar
Kent Overstreet committed
182

Kent Overstreet's avatar
Kent Overstreet committed
183
		bch2_cut_front(iter.pos,	insert);
184 185
		bch2_cut_back(new->k.p,		insert);
		bch2_cut_back(insert->k.p,	&new->k_i);
Kent Overstreet's avatar
Kent Overstreet committed
186

187 188 189 190 191 192 193 194 195 196 197 198 199
		if (m->data_cmd == DATA_REWRITE) {
			struct bch_extent_ptr *new_ptr, *old_ptr = (void *)
				bch2_bkey_has_device(bkey_i_to_s_c(insert),
						     m->data_opts.rewrite_dev);
			if (!old_ptr)
				goto nomatch;

			if (old_ptr->cached)
				extent_for_each_ptr(extent_i_to_s(new), new_ptr)
					new_ptr->cached = true;

			bch2_bkey_drop_ptr(bkey_i_to_s(insert), old_ptr);
		}
Kent Overstreet's avatar
Kent Overstreet committed
200

201
		extent_for_each_ptr_decode(extent_i_to_s(new), p, entry) {
Kent Overstreet's avatar
Kent Overstreet committed
202
			if (bch2_bkey_has_device(bkey_i_to_s_c(insert), p.ptr.dev)) {
Kent Overstreet's avatar
Kent Overstreet committed
203 204 205 206 207 208 209 210
				/*
				 * raced with another move op? extent already
				 * has a pointer to the device we just wrote
				 * data to
				 */
				continue;
			}

Kent Overstreet's avatar
Kent Overstreet committed
211
			bch2_extent_ptr_decoded_append(insert, &p);
Kent Overstreet's avatar
Kent Overstreet committed
212 213 214 215 216 217
			did_work = true;
		}

		if (!did_work)
			goto nomatch;

Kent Overstreet's avatar
Kent Overstreet committed
218
		bch2_bkey_narrow_crcs(insert,
Kent Overstreet's avatar
Kent Overstreet committed
219
				(struct bch_extent_crc_unpacked) { 0 });
Kent Overstreet's avatar
Kent Overstreet committed
220 221 222 223
		bch2_extent_normalize(c, bkey_i_to_s(insert));
		bch2_bkey_mark_replicas_cached(c, bkey_i_to_s(insert),
					       op->opts.background_target,
					       op->opts.data_replicas);
Kent Overstreet's avatar
Kent Overstreet committed
224

Kent Overstreet's avatar
Kent Overstreet committed
225
		ret = bch2_sum_sector_overwrites(&trans, &iter, insert,
226 227 228 229 230 231
						 &extending,
						 &should_check_enospc,
						 &i_sectors_delta,
						 &disk_sectors_delta);
		if (ret)
			goto err;
232

233
		if (disk_sectors_delta > (s64) op->res.sectors) {
Kent Overstreet's avatar
Kent Overstreet committed
234
			ret = bch2_disk_reservation_add(c, &op->res,
235 236 237
						disk_sectors_delta - op->res.sectors,
						!should_check_enospc
						? BCH_DISK_RESERVATION_NOFAIL : 0);
Kent Overstreet's avatar
Kent Overstreet committed
238 239 240 241
			if (ret)
				goto out;
		}

242 243
		next_pos = insert->k.p;

244 245 246 247
		ret   = insert_snapshot_whiteouts(&trans, m->btree_id,
						  k.k->p, insert->k.p) ?:
			bch2_trans_update(&trans, &iter, insert,
				BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?:
248
			bch2_trans_commit(&trans, &op->res,
249
				op_journal_seq(op),
Kent Overstreet's avatar
Kent Overstreet committed
250
				BTREE_INSERT_NOFAIL|
251
				m->data_opts.btree_insert_flags);
252
		if (!ret) {
Kent Overstreet's avatar
Kent Overstreet committed
253
			bch2_btree_iter_set_pos(&iter, next_pos);
Kent Overstreet's avatar
Kent Overstreet committed
254
			atomic_long_inc(&c->extent_migrate_done);
255 256
		}
err:
Kent Overstreet's avatar
Kent Overstreet committed
257 258 259 260 261
		if (ret == -EINTR)
			ret = 0;
		if (ret)
			break;
next:
Kent Overstreet's avatar
Kent Overstreet committed
262
		while (bkey_cmp(iter.pos, bch2_keylist_front(keys)->k.p) >= 0) {
Kent Overstreet's avatar
Kent Overstreet committed
263 264 265 266 267 268
			bch2_keylist_pop_front(keys);
			if (bch2_keylist_empty(keys))
				goto out;
		}
		continue;
nomatch:
269
		if (m->ctxt) {
Kent Overstreet's avatar
Kent Overstreet committed
270
			BUG_ON(k.k->p.offset <= iter.pos.offset);
271
			atomic64_inc(&m->ctxt->stats->keys_raced);
Kent Overstreet's avatar
Kent Overstreet committed
272
			atomic64_add(k.k->p.offset - iter.pos.offset,
Kent Overstreet's avatar
Kent Overstreet committed
273
				     &m->ctxt->stats->sectors_raced);
274
		}
Kent Overstreet's avatar
Kent Overstreet committed
275 276
		atomic_long_inc(&c->extent_migrate_raced);
		trace_move_race(&new->k);
Kent Overstreet's avatar
Kent Overstreet committed
277
		bch2_btree_iter_advance(&iter);
Kent Overstreet's avatar
Kent Overstreet committed
278 279 280
		goto next;
	}
out:
Kent Overstreet's avatar
Kent Overstreet committed
281
	bch2_trans_iter_exit(&trans, &iter);
282
	bch2_trans_exit(&trans);
283 284
	bch2_bkey_buf_exit(&_insert, c);
	bch2_bkey_buf_exit(&_new, c);
285
	BUG_ON(ret == -EINTR);
Kent Overstreet's avatar
Kent Overstreet committed
286 287 288 289 290 291 292 293 294
	return ret;
}

void bch2_migrate_read_done(struct migrate_write *m, struct bch_read_bio *rbio)
{
	/* write bio must own pages: */
	BUG_ON(!m->op.wbio.bio.bi_vcnt);

	m->ptr		= rbio->pick.ptr;
295
	m->offset	= rbio->data_pos.offset - rbio->pick.crc.offset;
Kent Overstreet's avatar
Kent Overstreet committed
296
	m->op.devs_have	= rbio->devs_have;
297
	m->op.pos	= rbio->data_pos;
Kent Overstreet's avatar
Kent Overstreet committed
298 299 300 301 302 303 304 305 306 307 308 309 310
	m->op.version	= rbio->version;
	m->op.crc	= rbio->pick.crc;
	m->op.wbio.bio.bi_iter.bi_size = m->op.crc.compressed_size << 9;

	if (m->data_cmd == DATA_REWRITE)
		bch2_dev_list_drop_dev(&m->op.devs_have, m->data_opts.rewrite_dev);
}

int bch2_migrate_write_init(struct bch_fs *c, struct migrate_write *m,
			    struct write_point_specifier wp,
			    struct bch_io_opts io_opts,
			    enum data_cmd data_cmd,
			    struct data_opts data_opts,
Kent Overstreet's avatar
Kent Overstreet committed
311
			    enum btree_id btree_id,
Kent Overstreet's avatar
Kent Overstreet committed
312 313
			    struct bkey_s_c k)
{
314 315
	struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
	const union bch_extent_entry *entry;
316
	struct bch_extent_crc_unpacked crc;
317
	struct extent_ptr_decoded p;
Kent Overstreet's avatar
Kent Overstreet committed
318 319
	int ret;

Kent Overstreet's avatar
Kent Overstreet committed
320
	m->btree_id	= btree_id;
Kent Overstreet's avatar
Kent Overstreet committed
321 322 323 324 325
	m->data_cmd	= data_cmd;
	m->data_opts	= data_opts;
	m->nr_ptrs_reserved = 0;

	bch2_write_op_init(&m->op, c, io_opts);
326 327 328 329 330 331 332 333

	if (!bch2_bkey_is_incompressible(k))
		m->op.compression_type =
			bch2_compression_opt_to_type[io_opts.background_compression ?:
						     io_opts.compression];
	else
		m->op.incompressible = true;

Kent Overstreet's avatar
Kent Overstreet committed
334 335 336
	m->op.target	= data_opts.target,
	m->op.write_point = wp;

337 338 339 340 341 342 343 344 345 346 347 348
	/*
	 * op->csum_type is normally initialized from the fs/file's current
	 * options - but if an extent is encrypted, we require that it stays
	 * encrypted:
	 */
	bkey_for_each_crc(k.k, ptrs, crc, entry)
		if (bch2_csum_type_is_encryption(crc.csum_type)) {
			m->op.nonce	= crc.nonce + crc.offset;
			m->op.csum_type = crc.csum_type;
			break;
		}

349
	if (m->data_opts.btree_insert_flags & BTREE_INSERT_USE_RESERVE) {
Kent Overstreet's avatar
Kent Overstreet committed
350
		m->op.alloc_reserve = RESERVE_MOVINGGC;
351
		m->op.flags |= BCH_WRITE_ALLOC_NOWAIT;
352 353 354 355
	} else {
		/* XXX: this should probably be passed in */
		m->op.flags |= BCH_WRITE_ONLY_SPECIFIED_DEVS;
	}
Kent Overstreet's avatar
Kent Overstreet committed
356

357
	m->op.flags |= BCH_WRITE_PAGES_STABLE|
Kent Overstreet's avatar
Kent Overstreet committed
358
		BCH_WRITE_PAGES_OWNED|
359
		BCH_WRITE_DATA_ENCODED|
360 361
		BCH_WRITE_FROM_INTERNAL|
		BCH_WRITE_MOVE;
Kent Overstreet's avatar
Kent Overstreet committed
362

363 364
	m->op.nr_replicas	= data_opts.nr_replicas;
	m->op.nr_replicas_required = data_opts.nr_replicas;
Kent Overstreet's avatar
Kent Overstreet committed
365 366 367

	switch (data_cmd) {
	case DATA_ADD_REPLICAS: {
368 369 370 371 372 373
		/*
		 * DATA_ADD_REPLICAS is used for moving data to a different
		 * device in the background, and due to compression the new copy
		 * might take up more space than the old copy:
		 */
#if 0
Kent Overstreet's avatar
Kent Overstreet committed
374
		int nr = (int) io_opts.data_replicas -
375
			bch2_bkey_nr_ptrs_allocated(k);
376 377
#endif
		int nr = (int) io_opts.data_replicas;
Kent Overstreet's avatar
Kent Overstreet committed
378 379 380 381 382 383 384 385 386 387 388

		if (nr > 0) {
			m->op.nr_replicas = m->nr_ptrs_reserved = nr;

			ret = bch2_disk_reservation_get(c, &m->op.res,
					k.k->size, m->op.nr_replicas, 0);
			if (ret)
				return ret;
		}
		break;
	}
389 390 391
	case DATA_REWRITE: {
		unsigned compressed_sectors = 0;

Kent Overstreet's avatar
Kent Overstreet committed
392
		bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
393 394 395
			if (p.ptr.dev == data_opts.rewrite_dev &&
			    !p.ptr.cached &&
			    crc_is_compressed(p.crc))
396 397 398 399
				compressed_sectors += p.crc.compressed_size;

		if (compressed_sectors) {
			ret = bch2_disk_reservation_add(c, &m->op.res,
400
					k.k->size * m->op.nr_replicas,
401 402 403 404
					BCH_DISK_RESERVATION_NOFAIL);
			if (ret)
				return ret;
		}
Kent Overstreet's avatar
Kent Overstreet committed
405
		break;
406
	}
Kent Overstreet's avatar
Kent Overstreet committed
407 408 409 410 411 412 413 414 415 416 417
	case DATA_PROMOTE:
		m->op.flags	|= BCH_WRITE_ALLOC_NOWAIT;
		m->op.flags	|= BCH_WRITE_CACHED;
		break;
	default:
		BUG();
	}

	return 0;
}

418
static void move_free(struct moving_io *io)
Kent Overstreet's avatar
Kent Overstreet committed
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
{
	struct moving_context *ctxt = io->write.ctxt;
	struct bvec_iter_all iter;
	struct bio_vec *bv;

	bch2_disk_reservation_put(io->write.op.c, &io->write.op.res);

	bio_for_each_segment_all(bv, &io->write.op.wbio.bio, iter)
		if (bv->bv_page)
			__free_page(bv->bv_page);

	wake_up(&ctxt->wait);

	kfree(io);
}

435
static void move_write_done(struct bch_write_op *op)
Kent Overstreet's avatar
Kent Overstreet committed
436
{
437 438
	struct moving_io *io = container_of(op, struct moving_io, write.op);
	struct moving_context *ctxt = io->write.ctxt;
Kent Overstreet's avatar
Kent Overstreet committed
439 440

	atomic_sub(io->write_sectors, &io->write.ctxt->write_sectors);
441 442
	move_free(io);
	closure_put(&ctxt->cl);
Kent Overstreet's avatar
Kent Overstreet committed
443 444
}

445
static void move_write(struct moving_io *io)
Kent Overstreet's avatar
Kent Overstreet committed
446 447
{
	if (unlikely(io->rbio.bio.bi_status || io->rbio.hole)) {
448
		move_free(io);
Kent Overstreet's avatar
Kent Overstreet committed
449 450 451
		return;
	}

452
	closure_get(&io->write.ctxt->cl);
Kent Overstreet's avatar
Kent Overstreet committed
453
	atomic_add(io->write_sectors, &io->write.ctxt->write_sectors);
454 455 456

	bch2_migrate_read_done(&io->write, &io->rbio);
	closure_call(&io->write.op.cl, bch2_write, NULL, NULL);
Kent Overstreet's avatar
Kent Overstreet committed
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
}

static inline struct moving_io *next_pending_write(struct moving_context *ctxt)
{
	struct moving_io *io =
		list_first_entry_or_null(&ctxt->reads, struct moving_io, list);

	return io && io->read_completed ? io : NULL;
}

static void move_read_endio(struct bio *bio)
{
	struct moving_io *io = container_of(bio, struct moving_io, rbio.bio);
	struct moving_context *ctxt = io->write.ctxt;

	atomic_sub(io->read_sectors, &ctxt->read_sectors);
	io->read_completed = true;

	if (next_pending_write(ctxt))
		wake_up(&ctxt->wait);

	closure_put(&ctxt->cl);
}

static void do_pending_writes(struct moving_context *ctxt)
{
	struct moving_io *io;

	while ((io = next_pending_write(ctxt))) {
		list_del(&io->list);
487
		move_write(io);
Kent Overstreet's avatar
Kent Overstreet committed
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
	}
}

#define move_ctxt_wait_event(_ctxt, _cond)			\
do {								\
	do_pending_writes(_ctxt);				\
								\
	if (_cond)						\
		break;						\
	__wait_event((_ctxt)->wait,				\
		     next_pending_write(_ctxt) || (_cond));	\
} while (1)

static void bch2_move_ctxt_wait_for_io(struct moving_context *ctxt)
{
	unsigned sectors_pending = atomic_read(&ctxt->write_sectors);

	move_ctxt_wait_event(ctxt,
		!atomic_read(&ctxt->write_sectors) ||
		atomic_read(&ctxt->write_sectors) != sectors_pending);
}

510
static int bch2_move_extent(struct btree_trans *trans,
Kent Overstreet's avatar
Kent Overstreet committed
511 512 513
			    struct moving_context *ctxt,
			    struct write_point_specifier wp,
			    struct bch_io_opts io_opts,
Kent Overstreet's avatar
Kent Overstreet committed
514
			    enum btree_id btree_id,
515
			    struct bkey_s_c k,
Kent Overstreet's avatar
Kent Overstreet committed
516 517 518
			    enum data_cmd data_cmd,
			    struct data_opts data_opts)
{
519
	struct bch_fs *c = trans->c;
520
	struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
Kent Overstreet's avatar
Kent Overstreet committed
521
	struct moving_io *io;
522 523
	const union bch_extent_entry *entry;
	struct extent_ptr_decoded p;
524
	unsigned sectors = k.k->size, pages;
Kent Overstreet's avatar
Kent Overstreet committed
525 526 527 528 529 530 531 532 533 534 535
	int ret = -ENOMEM;

	move_ctxt_wait_event(ctxt,
		atomic_read(&ctxt->write_sectors) <
		SECTORS_IN_FLIGHT_PER_DEVICE);

	move_ctxt_wait_event(ctxt,
		atomic_read(&ctxt->read_sectors) <
		SECTORS_IN_FLIGHT_PER_DEVICE);

	/* write path might have to decompress data: */
536
	bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
537
		sectors = max_t(unsigned, sectors, p.crc.uncompressed_size);
Kent Overstreet's avatar
Kent Overstreet committed
538 539 540 541 542 543 544 545

	pages = DIV_ROUND_UP(sectors, PAGE_SECTORS);
	io = kzalloc(sizeof(struct moving_io) +
		     sizeof(struct bio_vec) * pages, GFP_KERNEL);
	if (!io)
		goto err;

	io->write.ctxt		= ctxt;
546 547
	io->read_sectors	= k.k->size;
	io->write_sectors	= k.k->size;
Kent Overstreet's avatar
Kent Overstreet committed
548 549 550 551 552 553 554 555 556

	bio_init(&io->write.op.wbio.bio, NULL, io->bi_inline_vecs, pages, 0);
	bio_set_prio(&io->write.op.wbio.bio,
		     IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0));

	if (bch2_bio_alloc_pages(&io->write.op.wbio.bio, sectors << 9,
				 GFP_KERNEL))
		goto err_free;

557 558
	io->rbio.c		= c;
	io->rbio.opts		= io_opts;
Kent Overstreet's avatar
Kent Overstreet committed
559 560 561 562 563 564
	bio_init(&io->rbio.bio, NULL, io->bi_inline_vecs, pages, 0);
	io->rbio.bio.bi_vcnt = pages;
	bio_set_prio(&io->rbio.bio, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0));
	io->rbio.bio.bi_iter.bi_size = sectors << 9;

	io->rbio.bio.bi_opf		= REQ_OP_READ;
565
	io->rbio.bio.bi_iter.bi_sector	= bkey_start_offset(k.k);
Kent Overstreet's avatar
Kent Overstreet committed
566 567 568
	io->rbio.bio.bi_end_io		= move_read_endio;

	ret = bch2_migrate_write_init(c, &io->write, wp, io_opts,
Kent Overstreet's avatar
Kent Overstreet committed
569
				      data_cmd, data_opts, btree_id, k);
Kent Overstreet's avatar
Kent Overstreet committed
570 571 572
	if (ret)
		goto err_free_pages;

573 574
	io->write.op.end_io = move_write_done;

Kent Overstreet's avatar
Kent Overstreet committed
575
	atomic64_inc(&ctxt->stats->keys_moved);
576
	atomic64_add(k.k->size, &ctxt->stats->sectors_moved);
Kent Overstreet's avatar
Kent Overstreet committed
577

578
	trace_move_extent(k.k);
Kent Overstreet's avatar
Kent Overstreet committed
579 580 581 582 583 584 585 586 587

	atomic_add(io->read_sectors, &ctxt->read_sectors);
	list_add_tail(&io->list, &ctxt->reads);

	/*
	 * dropped by move_read_endio() - guards against use after free of
	 * ctxt when doing wakeup
	 */
	closure_get(&ctxt->cl);
588 589 590
	bch2_read_extent(trans, &io->rbio,
			 bkey_start_pos(k.k),
			 btree_id, k, 0,
Kent Overstreet's avatar
Kent Overstreet committed
591 592 593 594 595 596 597 598
			 BCH_READ_NODECODE|
			 BCH_READ_LAST_FRAGMENT);
	return 0;
err_free_pages:
	bio_free_pages(&io->write.op.wbio.bio);
err_free:
	kfree(io);
err:
599
	trace_move_alloc_fail(k.k);
Kent Overstreet's avatar
Kent Overstreet committed
600 601 602
	return ret;
}

603 604 605
static int lookup_inode(struct btree_trans *trans, struct bpos pos,
			struct bch_inode_unpacked *inode)
{
Kent Overstreet's avatar
Kent Overstreet committed
606
	struct btree_iter iter;
607 608 609
	struct bkey_s_c k;
	int ret;

Kent Overstreet's avatar
Kent Overstreet committed
610 611 612
	bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes, pos,
			     BTREE_ITER_ALL_SNAPSHOTS);
	k = bch2_btree_iter_peek(&iter);
613 614 615 616
	ret = bkey_err(k);
	if (ret)
		goto err;

617 618 619 620 621
	if (!k.k || bkey_cmp(k.k->p, pos)) {
		ret = -ENOENT;
		goto err;
	}

622 623 624 625 626 627 628 629
	ret = k.k->type == KEY_TYPE_inode ? 0 : -EIO;
	if (ret)
		goto err;

	ret = bch2_inode_unpack(bkey_s_c_to_inode(k), inode);
	if (ret)
		goto err;
err:
Kent Overstreet's avatar
Kent Overstreet committed
630
	bch2_trans_iter_exit(trans, &iter);
631 632 633
	return ret;
}

Kent Overstreet's avatar
Kent Overstreet committed
634 635 636 637 638 639 640 641 642
static int __bch2_move_data(struct bch_fs *c,
		struct moving_context *ctxt,
		struct bch_ratelimit *rate,
		struct write_point_specifier wp,
		struct bpos start,
		struct bpos end,
		move_pred_fn pred, void *arg,
		struct bch_move_stats *stats,
		enum btree_id btree_id)
Kent Overstreet's avatar
Kent Overstreet committed
643 644 645
{
	bool kthread = (current->flags & PF_KTHREAD) != 0;
	struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
646
	struct bkey_buf sk;
647
	struct btree_trans trans;
Kent Overstreet's avatar
Kent Overstreet committed
648
	struct btree_iter iter;
Kent Overstreet's avatar
Kent Overstreet committed
649 650 651
	struct bkey_s_c k;
	struct data_opts data_opts;
	enum data_cmd data_cmd;
652
	u64 delay, cur_inum = U64_MAX;
Kent Overstreet's avatar
Kent Overstreet committed
653 654
	int ret = 0, ret2;

655
	bch2_bkey_buf_init(&sk);
656
	bch2_trans_init(&trans, c, 0, 0);
657

658
	stats->data_type = BCH_DATA_user;
Kent Overstreet's avatar
Kent Overstreet committed
659
	stats->btree_id	= btree_id;
660
	stats->pos	= start;
661

Kent Overstreet's avatar
Kent Overstreet committed
662
	bch2_trans_iter_init(&trans, &iter, btree_id, start,
663 664
			     BTREE_ITER_PREFETCH|
			     BTREE_ITER_ALL_SNAPSHOTS);
Kent Overstreet's avatar
Kent Overstreet committed
665 666 667 668

	if (rate)
		bch2_ratelimit_reset(rate);

669 670 671 672 673
	while (1) {
		do {
			delay = rate ? bch2_ratelimit_delay(rate) : 0;

			if (delay) {
674
				bch2_trans_unlock(&trans);
675 676 677 678 679 680 681 682 683 684 685 686
				set_current_state(TASK_INTERRUPTIBLE);
			}

			if (kthread && (ret = kthread_should_stop())) {
				__set_current_state(TASK_RUNNING);
				goto out;
			}

			if (delay)
				schedule_timeout(delay);

			if (unlikely(freezing(current))) {
687
				bch2_trans_unlock(&trans);
Kent Overstreet's avatar
Kent Overstreet committed
688
				move_ctxt_wait_event(ctxt, list_empty(&ctxt->reads));
689 690 691
				try_to_freeze();
			}
		} while (delay);
692

693 694
		bch2_trans_begin(&trans);

Kent Overstreet's avatar
Kent Overstreet committed
695
		k = bch2_btree_iter_peek(&iter);
696

Kent Overstreet's avatar
Kent Overstreet committed
697
		stats->pos = iter.pos;
698

Kent Overstreet's avatar
Kent Overstreet committed
699 700
		if (!k.k)
			break;
701
		ret = bkey_err(k);
Kent Overstreet's avatar
Kent Overstreet committed
702 703 704 705 706
		if (ret)
			break;
		if (bkey_cmp(bkey_start_pos(k.k), end) >= 0)
			break;

707
		if (!bkey_extent_is_direct_data(k.k))
Kent Overstreet's avatar
Kent Overstreet committed
708 709
			goto next_nondata;

710
		if (btree_id == BTREE_ID_extents &&
711
		    cur_inum != k.k->p.inode) {
Kent Overstreet's avatar
Kent Overstreet committed
712 713 714
			struct bch_inode_unpacked inode;

			io_opts = bch2_opts_to_inode_opts(c->opts);
715 716 717 718 719 720 721 722

			ret = lookup_inode(&trans,
					SPOS(0, k.k->p.inode, k.k->p.snapshot),
					&inode);
			if (ret == -EINTR)
				continue;

			if (!ret)
Kent Overstreet's avatar
Kent Overstreet committed
723
				bch2_io_opts_apply(&io_opts, bch2_inode_opts_get(&inode));
724

Kent Overstreet's avatar
Kent Overstreet committed
725 726 727
			cur_inum = k.k->p.inode;
		}

728
		switch ((data_cmd = pred(c, arg, k, &io_opts, &data_opts))) {
Kent Overstreet's avatar
Kent Overstreet committed
729 730 731 732 733 734 735 736 737 738 739 740 741
		case DATA_SKIP:
			goto next;
		case DATA_SCRUB:
			BUG();
		case DATA_ADD_REPLICAS:
		case DATA_REWRITE:
		case DATA_PROMOTE:
			break;
		default:
			BUG();
		}

		/* unlock before doing IO: */
742
		bch2_bkey_buf_reassemble(&sk, c, k);
Kent Overstreet's avatar
Kent Overstreet committed
743
		k = bkey_i_to_s_c(sk.k);
744
		bch2_trans_unlock(&trans);
Kent Overstreet's avatar
Kent Overstreet committed
745

746
		ret2 = bch2_move_extent(&trans, ctxt, wp, io_opts, btree_id, k,
Kent Overstreet's avatar
Kent Overstreet committed
747 748
					data_cmd, data_opts);
		if (ret2) {
749
			if (ret2 == -EINTR) {
750
				bch2_trans_begin(&trans);
751 752 753
				continue;
			}

Kent Overstreet's avatar
Kent Overstreet committed
754 755
			if (ret2 == -ENOMEM) {
				/* memory allocation failure, wait for some IO to finish */
Kent Overstreet's avatar
Kent Overstreet committed
756
				bch2_move_ctxt_wait_for_io(ctxt);
Kent Overstreet's avatar
Kent Overstreet committed
757 758 759 760 761 762 763 764 765 766
				continue;
			}

			/* XXX signal failure */
			goto next;
		}

		if (rate)
			bch2_ratelimit_increment(rate, k.k->size);
next:
767
		atomic64_add(k.k->size * bch2_bkey_nr_ptrs_allocated(k),
Kent Overstreet's avatar
Kent Overstreet committed
768 769
			     &stats->sectors_seen);
next_nondata:
Kent Overstreet's avatar
Kent Overstreet committed
770
		bch2_btree_iter_advance(&iter);
771
		bch2_trans_cond_resched(&trans);
Kent Overstreet's avatar
Kent Overstreet committed
772
	}
773
out:
774

Kent Overstreet's avatar
Kent Overstreet committed
775
	bch2_trans_iter_exit(&trans, &iter);
Kent Overstreet's avatar
Kent Overstreet committed
776
	ret = bch2_trans_exit(&trans) ?: ret;
777
	bch2_bkey_buf_exit(&sk, c);
Kent Overstreet's avatar
Kent Overstreet committed
778 779 780 781

	return ret;
}

782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
inline void bch_move_stats_init(struct bch_move_stats *stats, char *name)
{
	memset(stats, 0, sizeof(*stats));

	scnprintf(stats->name, sizeof(stats->name),
			"%s", name);
}

static inline void progress_list_add(struct bch_fs *c,
				     struct bch_move_stats *stats)
{
	mutex_lock(&c->data_progress_lock);
	list_add(&stats->list, &c->data_progress_list);
	mutex_unlock(&c->data_progress_lock);
}

static inline void progress_list_del(struct bch_fs *c,
				     struct bch_move_stats *stats)
{
	mutex_lock(&c->data_progress_lock);
	list_del(&stats->list);
	mutex_unlock(&c->data_progress_lock);
}

Kent Overstreet's avatar
Kent Overstreet committed
806
int bch2_move_data(struct bch_fs *c,
807 808
		   enum btree_id start_btree_id, struct bpos start_pos,
		   enum btree_id end_btree_id,   struct bpos end_pos,
Kent Overstreet's avatar
Kent Overstreet committed
809 810 811 812 813 814
		   struct bch_ratelimit *rate,
		   struct write_point_specifier wp,
		   move_pred_fn pred, void *arg,
		   struct bch_move_stats *stats)
{
	struct moving_context ctxt = { .stats = stats };
815
	enum btree_id id;
Kent Overstreet's avatar
Kent Overstreet committed
816 817
	int ret;

818
	progress_list_add(c, stats);
Kent Overstreet's avatar
Kent Overstreet committed
819 820 821 822
	closure_init_stack(&ctxt.cl);
	INIT_LIST_HEAD(&ctxt.reads);
	init_waitqueue_head(&ctxt.wait);

823
	stats->data_type = BCH_DATA_user;
Kent Overstreet's avatar
Kent Overstreet committed
824

825 826 827 828 829
	for (id = start_btree_id;
	     id <= min_t(unsigned, end_btree_id, BTREE_ID_NR - 1);
	     id++) {
		stats->btree_id = id;

830 831
		if (id != BTREE_ID_extents &&
		    id != BTREE_ID_reflink)
832 833 834 835 836 837 838 839 840 841
			continue;

		ret = __bch2_move_data(c, &ctxt, rate, wp,
				       id == start_btree_id ? start_pos : POS_MIN,
				       id == end_btree_id   ? end_pos   : POS_MAX,
				       pred, arg, stats, id);
		if (ret)
			break;
	}

Kent Overstreet's avatar
Kent Overstreet committed
842 843 844 845 846 847 848 849 850 851

	move_ctxt_wait_event(&ctxt, list_empty(&ctxt.reads));
	closure_sync(&ctxt.cl);

	EBUG_ON(atomic_read(&ctxt.write_sectors));

	trace_move_data(c,
			atomic64_read(&stats->sectors_moved),
			atomic64_read(&stats->keys_moved));

852
	progress_list_del(c, stats);
Kent Overstreet's avatar
Kent Overstreet committed
853 854 855
	return ret;
}

856 857 858 859
typedef enum data_cmd (*move_btree_pred)(struct bch_fs *, void *,
					 struct btree *, struct bch_io_opts *,
					 struct data_opts *);

Kent Overstreet's avatar
Kent Overstreet committed
860
static int bch2_move_btree(struct bch_fs *c,
861 862 863
			   enum btree_id start_btree_id, struct bpos start_pos,
			   enum btree_id end_btree_id,   struct bpos end_pos,
			   move_btree_pred pred, void *arg,
Kent Overstreet's avatar
Kent Overstreet committed
864 865
			   struct bch_move_stats *stats)
{
866
	bool kthread = (current->flags & PF_KTHREAD) != 0;
Kent Overstreet's avatar
Kent Overstreet committed
867
	struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
868
	struct btree_trans trans;
Kent Overstreet's avatar
Kent Overstreet committed
869
	struct btree_iter iter;
Kent Overstreet's avatar
Kent Overstreet committed
870
	struct btree *b;
871
	enum btree_id id;
Kent Overstreet's avatar
Kent Overstreet committed
872 873 874 875
	struct data_opts data_opts;
	enum data_cmd cmd;
	int ret = 0;

876
	bch2_trans_init(&trans, c, 0, 0);
877
	progress_list_add(c, stats);
878

879
	stats->data_type = BCH_DATA_btree;
Kent Overstreet's avatar
Kent Overstreet committed
880

881 882 883
	for (id = start_btree_id;
	     id <= min_t(unsigned, end_btree_id, BTREE_ID_NR - 1);
	     id++) {
884 885
		stats->btree_id = id;

886 887 888 889 890
		bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
					  BTREE_ITER_PREFETCH);

		while (bch2_trans_begin(&trans),
		       (b = bch2_btree_iter_peek_node(&iter))) {
891
			if (kthread && kthread_should_stop())
892
				break;
893 894

			if ((cmp_int(id, end_btree_id) ?:
895
			     bpos_cmp(b->key.k.p, end_pos)) > 0)
896 897
				break;

Kent Overstreet's avatar
Kent Overstreet committed
898
			stats->pos = iter.pos;
899

900
			switch ((cmd = pred(c, arg, b, &io_opts, &data_opts))) {
Kent Overstreet's avatar
Kent Overstreet committed
901 902 903 904 905 906 907 908 909 910 911
			case DATA_SKIP:
				goto next;
			case DATA_SCRUB:
				BUG();
			case DATA_ADD_REPLICAS:
			case DATA_REWRITE:
				break;
			default:
				BUG();
			}

Kent Overstreet's avatar
Kent Overstreet committed
912
			ret = bch2_btree_node_rewrite(&trans, &iter,
Kent Overstreet's avatar
Kent Overstreet committed
913 914
					b->data->keys.seq, 0) ?: ret;
next:
915
			bch2_trans_cond_resched(&trans);
916
			bch2_btree_iter_next_node(&iter);
Kent Overstreet's avatar
Kent Overstreet committed
917
		}
Kent Overstreet's avatar
Kent Overstreet committed
918
		bch2_trans_iter_exit(&trans, &iter);
Kent Overstreet's avatar
Kent Overstreet committed
919

920 921
		if (kthread && kthread_should_stop())
			break;
Kent Overstreet's avatar
Kent Overstreet committed
922
	}
923

924 925
	bch2_trans_exit(&trans);

926 927 928
	if (ret)
		bch_err(c, "error %i in bch2_move_btree", ret);

929
	progress_list_del(c, stats);
Kent Overstreet's avatar
Kent Overstreet committed
930 931 932 933 934
	return ret;
}

#if 0
static enum data_cmd scrub_pred(struct bch_fs *c, void *arg,
935
				struct bkey_s_c k,
Kent Overstreet's avatar
Kent Overstreet committed
936 937 938 939 940 941 942 943
				struct bch_io_opts *io_opts,
				struct data_opts *data_opts)
{
	return DATA_SCRUB;
}
#endif

static enum data_cmd rereplicate_pred(struct bch_fs *c, void *arg,
944
				      struct bkey_s_c k,
Kent Overstreet's avatar
Kent Overstreet committed
945 946 947
				      struct bch_io_opts *io_opts,
				      struct data_opts *data_opts)
{
948
	unsigned nr_good = bch2_bkey_durability(c, k);
949 950 951
	unsigned replicas = bkey_is_btree_ptr(k.k)
		? c->opts.metadata_replicas
		: io_opts->data_replicas;
Kent Overstreet's avatar
Kent Overstreet committed
952 953 954 955 956

	if (!nr_good || nr_good >= replicas)
		return DATA_SKIP;

	data_opts->target		= 0;
957
	data_opts->nr_replicas		= 1;
958
	data_opts->btree_insert_flags	= 0;
Kent Overstreet's avatar
Kent Overstreet committed
959 960 961 962
	return DATA_ADD_REPLICAS;
}

static enum data_cmd migrate_pred(struct bch_fs *c, void *arg,
963
				  struct bkey_s_c k,
Kent Overstreet's avatar
Kent Overstreet committed
964 965 966 967 968
				  struct bch_io_opts *io_opts,
				  struct data_opts *data_opts)
{
	struct bch_ioctl_data *op = arg;

969
	if (!bch2_bkey_has_device(k, op->migrate.dev))
Kent Overstreet's avatar
Kent Overstreet committed
970 971 972
		return DATA_SKIP;

	data_opts->target		= 0;
973
	data_opts->nr_replicas		= 1;
Kent Overstreet's avatar
Kent Overstreet committed
974 975 976 977 978
	data_opts->btree_insert_flags	= 0;
	data_opts->rewrite_dev		= op->migrate.dev;
	return DATA_REWRITE;
}

979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
static enum data_cmd rereplicate_btree_pred(struct bch_fs *c, void *arg,
					    struct btree *b,
					    struct bch_io_opts *io_opts,
					    struct data_opts *data_opts)
{
	return rereplicate_pred(c, arg, bkey_i_to_s_c(&b->key), io_opts, data_opts);
}

static enum data_cmd migrate_btree_pred(struct bch_fs *c, void *arg,
					struct btree *b,
					struct bch_io_opts *io_opts,
					struct data_opts *data_opts)
{
	return migrate_pred(c, arg, bkey_i_to_s_c(&b->key), io_opts, data_opts);
}

995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
static bool bformat_needs_redo(struct bkey_format *f)
{
	unsigned i;

	for (i = 0; i < f->nr_fields; i++) {
		unsigned unpacked_bits = bch2_bkey_format_current.bits_per_field[i];
		u64 unpacked_mask = ~((~0ULL << 1) << (unpacked_bits - 1));
		u64 field_offset = le64_to_cpu(f->field_offset[i]);

		if (f->bits_per_field[i] > unpacked_bits)
			return true;

		if ((f->bits_per_field[i] == unpacked_bits) && field_offset)
			return true;

		if (((field_offset + ((1ULL << f->bits_per_field[i]) - 1)) &
		     unpacked_mask) <
		    field_offset)
			return true;
	}

	return false;
}

1019 1020 1021 1022 1023 1024
static enum data_cmd rewrite_old_nodes_pred(struct bch_fs *c, void *arg,
					    struct btree *b,
					    struct bch_io_opts *io_opts,
					    struct data_opts *data_opts)
{
	if (b->version_ondisk != c->sb.version ||
1025 1026
	    btree_node_need_rewrite(b) ||
	    bformat_needs_redo(&b->format)) {
1027 1028 1029 1030 1031 1032 1033 1034 1035
		data_opts->target		= 0;
		data_opts->nr_replicas		= 1;
		data_opts->btree_insert_flags	= 0;
		return DATA_REWRITE;
	}

	return DATA_SKIP;
}

1036 1037 1038 1039 1040 1041
int bch2_scan_old_btree_nodes(struct bch_fs *c, struct bch_move_stats *stats)
{
	int ret;

	ret = bch2_move_btree(c,
			      0,		POS_MIN,
1042
			      BTREE_ID_NR,	SPOS_MAX,
1043 1044 1045
			      rewrite_old_nodes_pred, c, stats);
	if (!ret) {
		mutex_lock(&c->sb_lock);
1046 1047
		c->disk_sb.sb->compat[0] |= cpu_to_le64(1ULL << BCH_COMPAT_extents_above_btree_updates_done);
		c->disk_sb.sb->compat[0] |= cpu_to_le64(1ULL << BCH_COMPAT_bformat_overflow_done);
1048 1049 1050 1051 1052 1053 1054 1055
		c->disk_sb.sb->version_min = c->disk_sb.sb->version;
		bch2_write_super(c);
		mutex_unlock(&c->sb_lock);
	}

	return ret;
}

Kent Overstreet's avatar
Kent Overstreet committed
1056 1057 1058 1059 1060 1061 1062 1063
int bch2_data_job(struct bch_fs *c,
		  struct bch_move_stats *stats,
		  struct bch_ioctl_data op)
{
	int ret = 0;

	switch (op.op) {
	case BCH_DATA_OP_REREPLICATE:
1064
		bch_move_stats_init(stats, "rereplicate");
1065
		stats->data_type = BCH_DATA_journal;
Kent Overstreet's avatar
Kent Overstreet committed
1066 1067
		ret = bch2_journal_flush_device_pins(&c->journal, -1);

1068 1069 1070 1071
		ret = bch2_move_btree(c,
				      op.start_btree,	op.start_pos,
				      op.end_btree,	op.end_pos,
				      rereplicate_btree_pred, c, stats) ?: ret;
1072

1073 1074
		closure_wait_event(&c->btree_interior_update_wait,
				   !bch2_btree_interior_updates_nr_pending(c));
1075

1076
		ret = bch2_replicas_gc2(c) ?: ret;
Kent Overstreet's avatar
Kent Overstreet committed
1077

1078 1079 1080 1081
		ret = bch2_move_data(c,
				     op.start_btree,	op.start_pos,
				     op.end_btree,	op.end_pos,
				     NULL, writepoint_hashed((unsigned long) current),
Kent Overstreet's avatar
Kent Overstreet committed
1082
				     rereplicate_pred, c, stats) ?: ret;
1083
		ret = bch2_replicas_gc2(c) ?: ret;
Kent Overstreet's avatar
Kent Overstreet committed
1084 1085 1086 1087 1088
		break;
	case BCH_DATA_OP_MIGRATE:
		if (op.migrate.dev >= c->sb.nr_devices)
			return -EINVAL;

1089
		bch_move_stats_init(stats, "migrate");
1090
		stats->data_type = BCH_DATA_journal;
Kent Overstreet's avatar
Kent Overstreet committed
1091 1092
		ret = bch2_journal_flush_device_pins(&c->journal, op.migrate.dev);

1093 1094 1095 1096
		ret = bch2_move_btree(c,
				      op.start_btree,	op.start_pos,
				      op.end_btree,	op.end_pos,
				      migrate_btree_pred, &op, stats) ?: ret;
1097
		ret = bch2_replicas_gc2(c) ?: ret;
Kent Overstreet's avatar
Kent Overstreet committed
1098

1099 1100 1101 1102
		ret = bch2_move_data(c,
				     op.start_btree,	op.start_pos,
				     op.end_btree,	op.end_pos,
				     NULL, writepoint_hashed((unsigned long) current),
Kent Overstreet's avatar
Kent Overstreet committed
1103
				     migrate_pred, &op, stats) ?: ret;
1104
		ret = bch2_replicas_gc2(c) ?: ret;
Kent Overstreet's avatar
Kent Overstreet committed
1105
		break;
1106
	case BCH_DATA_OP_REWRITE_OLD_NODES:
1107
		bch_move_stats_init(stats, "rewrite_old_nodes");
1108
		ret = bch2_scan_old_btree_nodes(c, stats);
1109
		break;
Kent Overstreet's avatar
Kent Overstreet committed
1110 1111 1112 1113 1114 1115
	default:
		ret = -EINVAL;
	}

	return ret;
}