summaryrefslogtreecommitdiff
path: root/libbcachefs/move.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-11-18 18:21:11 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2022-11-18 18:21:11 -0500
commitc1f55a60c41ca5ab8ed7a0893c3d29f8006da82a (patch)
tree6aed1a472dc723feb6447e5495bc8452e21219f5 /libbcachefs/move.c
parente4716b10ed0210a13efdd3252c12199da3d52aad (diff)
Update bcachefs sources to 6406e05835 bcachefs: Nocow support
Diffstat (limited to 'libbcachefs/move.c')
-rw-r--r--libbcachefs/move.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/libbcachefs/move.c b/libbcachefs/move.c
index 1d11cf0d..700f847c 100644
--- a/libbcachefs/move.c
+++ b/libbcachefs/move.c
@@ -261,6 +261,12 @@ static int bch2_move_extent(struct btree_trans *trans,
if (!percpu_ref_tryget_live(&c->writes))
return -EROFS;
+ /*
+ * Before memory allocations & taking nocow locks in
+ * bch2_data_update_init():
+ */
+ bch2_trans_unlock(trans);
+
/* write path might have to decompress data: */
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
sectors = max_t(unsigned, sectors, p.crc.uncompressed_size);
@@ -296,7 +302,7 @@ static int bch2_move_extent(struct btree_trans *trans,
ret = bch2_data_update_init(c, &io->write, ctxt->wp, io_opts,
data_opts, btree_id, k);
- if (ret)
+ if (ret && ret != -BCH_ERR_unwritten_extent_update)
goto err_free_pages;
io->write.ctxt = ctxt;
@@ -304,6 +310,15 @@ static int bch2_move_extent(struct btree_trans *trans,
atomic64_inc(&ctxt->stats->keys_moved);
atomic64_add(k.k->size, &ctxt->stats->sectors_moved);
+
+ if (ret == -BCH_ERR_unwritten_extent_update) {
+ bch2_update_unwritten_extent(trans, &io->write);
+ move_free(io);
+ return 0;
+ }
+
+ BUG_ON(ret);
+
this_cpu_add(c->counters[BCH_COUNTER_io_move], k.k->size);
this_cpu_add(c->counters[BCH_COUNTER_move_extent_read], k.k->size);
trace_move_extent_read(k.k);
@@ -499,6 +514,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
*/
bch2_bkey_buf_reassemble(&sk, c, k);
k = bkey_i_to_s_c(sk.k);
+ bch2_trans_unlock(&trans);
ret2 = bch2_move_extent(&trans, &iter, ctxt, io_opts,
btree_id, k, data_opts);
@@ -573,6 +589,9 @@ static int verify_bucket_evacuated(struct btree_trans *trans, struct bpos bucket
struct bch_fs *c = trans->c;
struct btree_iter iter;
struct bkey_s_c k;
+ struct printbuf buf = PRINTBUF;
+ struct bch_backpointer bp;
+ u64 bp_offset = 0;
int ret;
bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
@@ -586,24 +605,53 @@ again:
if (a.v->gen == gen &&
a.v->dirty_sectors) {
- struct printbuf buf = PRINTBUF;
-
if (a.v->data_type == BCH_DATA_btree) {
bch2_trans_unlock(trans);
if (bch2_btree_interior_updates_flush(c))
goto again;
+ goto failed_to_evacuate;
}
-
- prt_str(&buf, "failed to evacuate bucket ");
- bch2_bkey_val_to_text(&buf, c, k);
-
- bch_err(c, "%s", buf.buf);
- printbuf_exit(&buf);
}
}
bch2_trans_iter_exit(trans, &iter);
return ret;
+failed_to_evacuate:
+ bch2_trans_iter_exit(trans, &iter);
+
+ prt_printf(&buf, bch2_log_msg(c, "failed to evacuate bucket "));
+ bch2_bkey_val_to_text(&buf, c, k);
+
+ while (1) {
+ bch2_trans_begin(trans);
+
+ ret = bch2_get_next_backpointer(trans, bucket, gen,
+ &bp_offset, &bp,
+ BTREE_ITER_CACHED);
+ if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
+ continue;
+ if (ret)
+ break;
+ if (bp_offset == U64_MAX)
+ break;
+
+ k = bch2_backpointer_get_key(trans, &iter,
+ bucket, bp_offset, bp);
+ ret = bkey_err(k);
+ if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
+ continue;
+ if (ret)
+ break;
+ if (!k.k)
+ continue;
+ prt_newline(&buf);
+ bch2_bkey_val_to_text(&buf, c, k);
+ bch2_trans_iter_exit(trans, &iter);
+ }
+
+ bch2_print_string_as_lines(KERN_ERR, buf.buf);
+ printbuf_exit(&buf);
+ return 0;
}
int __bch2_evacuate_bucket(struct moving_context *ctxt,