Skip to content

Commit 72c0d9c

Browse files
author
Kent Overstreet
committed
bcachefs: Fix range in bch2_lookup_indirect_extent() error path
Before calling bch2_indirect_extent_missing_error(), we have to calculate the missing range, which is the intersection of the reflink pointer and the non-indirect-extent we found. The calculation didn't take into account that the returned extent may span the iter position, leading to an infinite loop when we (unnecessarily) resized the extent we were returning to one that didn't extend past the offset we were looking up. Signed-off-by: Kent Overstreet <[email protected]>
1 parent abcb6bd commit 72c0d9c

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

fs/bcachefs/reflink.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ void bch2_reflink_p_to_text(struct printbuf *out, struct bch_fs *c,
6464
REFLINK_P_IDX(p.v),
6565
le32_to_cpu(p.v->front_pad),
6666
le32_to_cpu(p.v->back_pad));
67+
68+
if (REFLINK_P_ERROR(p.v))
69+
prt_str(out, " error");
6770
}
6871

6972
bool bch2_reflink_p_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r)
@@ -269,13 +272,12 @@ struct bkey_s_c bch2_lookup_indirect_extent(struct btree_trans *trans,
269272
return k;
270273

271274
if (unlikely(!bkey_extent_is_reflink_data(k.k))) {
272-
unsigned size = min((u64) k.k->size,
273-
REFLINK_P_IDX(p.v) + p.k->size + le32_to_cpu(p.v->back_pad) -
274-
reflink_offset);
275-
bch2_key_resize(&iter->k, size);
275+
u64 missing_end = min(k.k->p.offset,
276+
REFLINK_P_IDX(p.v) + p.k->size + le32_to_cpu(p.v->back_pad));
277+
BUG_ON(reflink_offset == missing_end);
276278

277279
int ret = bch2_indirect_extent_missing_error(trans, p, reflink_offset,
278-
k.k->p.offset, should_commit);
280+
missing_end, should_commit);
279281
if (ret) {
280282
bch2_trans_iter_exit(trans, iter);
281283
return bkey_s_c_err(ret);

0 commit comments

Comments
 (0)