summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-05-25 23:37:06 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:10:02 -0400
commitfc0ee376bb5b08844198fba13fb809102afd0b29 (patch)
tree30660fa3bae2e4b4fb72d7c835837d4f01800c55 /fs
parentdb32bb9a5fd6bd7c7031b4b9d6c9a5e27b651e5d (diff)
downloadlinux-stable-fc0ee376bb5b08844198fba13fb809102afd0b29.tar.gz
linux-stable-fc0ee376bb5b08844198fba13fb809102afd0b29.tar.bz2
linux-stable-fc0ee376bb5b08844198fba13fb809102afd0b29.zip
bcachefs: Don't reuse reflink btree keyspace
We've been seeing difficult to debug "missing indirect extent" bugs, that fsck doesn't seem to find. One possibility is that there was a missing indirect extent, but then a new indirect extent was created at the location of the previous indirect extent. This patch eliminates that possibility by always creating new indirect extents right after the last one, at the end of the reflink btree. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/bcachefs.h1
-rw-r--r--fs/bcachefs/reflink.c20
2 files changed, 4 insertions, 17 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 39fd15447753..0dfa42e297e0 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -963,7 +963,6 @@ struct bch_fs {
struct bio_set ec_bioset;
/* REFLINK */
- u64 reflink_hint;
reflink_gc_table reflink_gc_table;
size_t reflink_gc_nr;
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
index 9430899a5a31..26f0275ff0af 100644
--- a/fs/bcachefs/reflink.c
+++ b/fs/bcachefs/reflink.c
@@ -167,24 +167,13 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
if (orig->k.type == KEY_TYPE_inline_data)
bch2_check_set_feature(c, BCH_FEATURE_reflink_inline_data);
- for_each_btree_key_norestart(trans, reflink_iter, BTREE_ID_reflink,
- POS(0, c->reflink_hint),
- BTREE_ITER_SLOTS, k, ret) {
- if (reflink_iter.pos.inode) {
- bch2_btree_iter_set_pos(&reflink_iter, POS_MIN);
- continue;
- }
-
- if (bkey_deleted(k.k) && orig->k.size <= k.k->size)
- break;
- }
-
+ bch2_trans_iter_init(trans, &reflink_iter, BTREE_ID_reflink, POS_MAX,
+ BTREE_ITER_INTENT);
+ k = bch2_btree_iter_peek_prev(&reflink_iter);
+ ret = bkey_err(k);
if (ret)
goto err;
- /* rewind iter to start of hole, if necessary: */
- bch2_btree_iter_set_pos_to_extent_start(&reflink_iter);
-
r_v = bch2_trans_kmalloc(trans, sizeof(__le64) + bkey_bytes(&orig->k));
ret = PTR_ERR_OR_ZERO(r_v);
if (ret)
@@ -226,7 +215,6 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
ret = bch2_trans_update(trans, extent_iter, &r_p->k_i,
BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
err:
- c->reflink_hint = reflink_iter.pos.offset;
bch2_trans_iter_exit(trans, &reflink_iter);
return ret;