brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · ddc187f Raw
175 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Code for moving data off a device.4 */5 6#include "bcachefs.h"7#include "bkey_buf.h"8#include "btree_update.h"9#include "btree_update_interior.h"10#include "buckets.h"11#include "errcode.h"12#include "extents.h"13#include "io_write.h"14#include "journal.h"15#include "keylist.h"16#include "migrate.h"17#include "move.h"18#include "replicas.h"19#include "super-io.h"20 21static int drop_dev_ptrs(struct bch_fs *c, struct bkey_s k,22			 unsigned dev_idx, int flags, bool metadata)23{24	unsigned replicas = metadata ? c->opts.metadata_replicas : c->opts.data_replicas;25	unsigned lost = metadata ? BCH_FORCE_IF_METADATA_LOST : BCH_FORCE_IF_DATA_LOST;26	unsigned degraded = metadata ? BCH_FORCE_IF_METADATA_DEGRADED : BCH_FORCE_IF_DATA_DEGRADED;27	unsigned nr_good;28 29	bch2_bkey_drop_device(k, dev_idx);30 31	nr_good = bch2_bkey_durability(c, k.s_c);32	if ((!nr_good && !(flags & lost)) ||33	    (nr_good < replicas && !(flags & degraded)))34		return -BCH_ERR_remove_would_lose_data;35 36	return 0;37}38 39static int bch2_dev_usrdata_drop_key(struct btree_trans *trans,40				     struct btree_iter *iter,41				     struct bkey_s_c k,42				     unsigned dev_idx,43				     int flags)44{45	struct bch_fs *c = trans->c;46	struct bkey_i *n;47	int ret;48 49	if (!bch2_bkey_has_device_c(k, dev_idx))50		return 0;51 52	n = bch2_bkey_make_mut(trans, iter, &k, BTREE_UPDATE_internal_snapshot_node);53	ret = PTR_ERR_OR_ZERO(n);54	if (ret)55		return ret;56 57	ret = drop_dev_ptrs(c, bkey_i_to_s(n), dev_idx, flags, false);58	if (ret)59		return ret;60 61	/*62	 * If the new extent no longer has any pointers, bch2_extent_normalize()63	 * will do the appropriate thing with it (turning it into a64	 * KEY_TYPE_error key, or just a discard if it was a cached extent)65	 */66	bch2_extent_normalize(c, bkey_i_to_s(n));67 68	/*69	 * Since we're not inserting through an extent iterator70	 * (BTREE_ITER_all_snapshots iterators aren't extent iterators),71	 * we aren't using the extent overwrite path to delete, we're72	 * just using the normal key deletion path:73	 */74	if (bkey_deleted(&n->k))75		n->k.size = 0;76	return 0;77}78 79static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)80{81	struct btree_trans *trans = bch2_trans_get(c);82	enum btree_id id;83	int ret = 0;84 85	for (id = 0; id < BTREE_ID_NR; id++) {86		if (!btree_type_has_ptrs(id))87			continue;88 89		ret = for_each_btree_key_commit(trans, iter, id, POS_MIN,90				BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k,91				NULL, NULL, BCH_TRANS_COMMIT_no_enospc,92			bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags));93		if (ret)94			break;95	}96 97	bch2_trans_put(trans);98 99	return ret;100}101 102static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)103{104	struct btree_trans *trans;105	struct btree_iter iter;106	struct closure cl;107	struct btree *b;108	struct bkey_buf k;109	unsigned id;110	int ret;111 112	/* don't handle this yet: */113	if (flags & BCH_FORCE_IF_METADATA_LOST)114		return -BCH_ERR_remove_with_metadata_missing_unimplemented;115 116	trans = bch2_trans_get(c);117	bch2_bkey_buf_init(&k);118	closure_init_stack(&cl);119 120	for (id = 0; id < BTREE_ID_NR; id++) {121		bch2_trans_node_iter_init(trans, &iter, id, POS_MIN, 0, 0,122					  BTREE_ITER_prefetch);123retry:124		ret = 0;125		while (bch2_trans_begin(trans),126		       (b = bch2_btree_iter_peek_node(&iter)) &&127		       !(ret = PTR_ERR_OR_ZERO(b))) {128			if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx))129				goto next;130 131			bch2_bkey_buf_copy(&k, c, &b->key);132 133			ret = drop_dev_ptrs(c, bkey_i_to_s(k.k),134					    dev_idx, flags, true);135			if (ret)136				break;137 138			ret = bch2_btree_node_update_key(trans, &iter, b, k.k, 0, false);139			if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) {140				ret = 0;141				continue;142			}143 144			bch_err_msg(c, ret, "updating btree node key");145			if (ret)146				break;147next:148			bch2_btree_iter_next_node(&iter);149		}150		if (bch2_err_matches(ret, BCH_ERR_transaction_restart))151			goto retry;152 153		bch2_trans_iter_exit(trans, &iter);154 155		if (ret)156			goto err;157	}158 159	bch2_btree_interior_updates_flush(c);160	ret = 0;161err:162	bch2_bkey_buf_exit(&k, c);163	bch2_trans_put(trans);164 165	BUG_ON(bch2_err_matches(ret, BCH_ERR_transaction_restart));166 167	return ret;168}169 170int bch2_dev_data_drop(struct bch_fs *c, unsigned dev_idx, int flags)171{172	return bch2_dev_usrdata_drop(c, dev_idx, flags) ?:173		bch2_dev_metadata_drop(c, dev_idx, flags);174}175