I don't see anything recent on the -testing branch on GitHub so I applied the patch from your email and the other io_write.c patch directly to rc7.
So far it seems to work to fix this issue for me. I'll keep testing. Thanks for such a quick fix! Thank you, Carl Thompson > On 2023-12-29 10:50 AM PST Kent Overstreet <[email protected]> wrote: > ... > Fix is in the -testing branch, will be making it to the appropriate > places shortly: > > commit 05b11fb627bcd71cc19e79cdeabfa1b514bf8acf > Author: Kent Overstreet <[email protected]> > Date: Fri Dec 29 13:39:07 2023 -0500 > > bcachefs: Fix extents iteration + snapshots interaction > > peek_upto() checks against the end position and bails out before > FILTER_SNAPSHOTS checks; this is because if we end up at a different > inode number than the original search key none of the keys we see might > be visibile in the current snapshot - we might be looking at inode in a > completely different subvolume. > > But this is broken, because when we're iterating over extents we're > checking against the extent start position to decide when to bail out, > and the extent start position isn't monotonically increasing until after > we've run FILTER_SNAPSHOTS. > > Fix this by adding a simple inode number check where the old bailout > check was, and moving the main check to the correct position. > > Signed-off-by: Kent Overstreet <[email protected]> > > diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c > index 732c8bb3f803..7e5c797cfaf2 100644 > --- a/fs/bcachefs/btree_iter.c > +++ b/fs/bcachefs/btree_iter.c > @@ -2145,18 +2145,16 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct > btree_iter *iter, struct bpos e > goto out_no_locked; > > /* > - * iter->pos should be mononotically increasing, and always be > - * equal to the key we just returned - except extents can > - * straddle iter->pos: > + * We need to check against @end before FILTER_SNAPSHOTS because > + * if we get to a different inode that requested we might be > + * seeing keys for a different snapshot tree that will all be > + * filtered out. > + * > + * But we can't do the full check here, because bkey_start_pos() > + * isn't monotonically increasing before FILTER_SNAPSHOTS, and > + * that's what we check against in extents mode: > */ > - if (!(iter->flags & BTREE_ITER_IS_EXTENTS)) > - iter_pos = k.k->p; > - else > - iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k)); > - > - if (unlikely(!(iter->flags & BTREE_ITER_IS_EXTENTS) > - ? bkey_gt(iter_pos, end) > - : bkey_ge(iter_pos, end))) > + if (k.k->p.inode > end.inode) > goto end; > > if (iter->update_path && > @@ -2215,6 +2213,21 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct > btree_iter *iter, struct bpos e > continue; > } > > + /* > + * iter->pos should be mononotically increasing, and always be > + * equal to the key we just returned - except extents can > + * straddle iter->pos: > + */ > + if (!(iter->flags & BTREE_ITER_IS_EXTENTS)) > + iter_pos = k.k->p; > + else > + iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k)); > + > + if (unlikely(!(iter->flags & BTREE_ITER_IS_EXTENTS) > + ? bkey_gt(iter_pos, end) > + : bkey_ge(iter_pos, end))) > + goto end; > + > break; > }
