Commit 3d495595 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix bch2_btree_iter_peek_prev()

This makes bch2_btree_iter_peek_prev() and bch2_btree_iter_prev()
consistent with peek() and next(), w.r.t. iter->pos.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 434094be
...@@ -1519,13 +1519,27 @@ void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos new_pos) ...@@ -1519,13 +1519,27 @@ void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos new_pos)
static inline bool bch2_btree_iter_advance_pos(struct btree_iter *iter) static inline bool bch2_btree_iter_advance_pos(struct btree_iter *iter)
{ {
if (unlikely(!bkey_cmp(iter->k.p, POS_MAX))) struct bpos pos = iter->k.p;
if (unlikely(!bkey_cmp(pos, POS_MAX)))
return false;
if (!(iter->flags & BTREE_ITER_IS_EXTENTS))
pos = bkey_successor(pos);
bch2_btree_iter_set_pos(iter, pos);
return true;
}
static inline bool bch2_btree_iter_rewind_pos(struct btree_iter *iter)
{
struct bpos pos = bkey_start_pos(&iter->k);
if (unlikely(!bkey_cmp(pos, POS_MIN)))
return false; return false;
bch2_btree_iter_set_pos(iter, if (!(iter->flags & BTREE_ITER_IS_EXTENTS))
(iter->flags & BTREE_ITER_IS_EXTENTS) pos = bkey_predecessor(pos);
? iter->k.p bch2_btree_iter_set_pos(iter, pos);
: bkey_successor(iter->k.p));
return true; return true;
} }
...@@ -1619,8 +1633,7 @@ struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter) ...@@ -1619,8 +1633,7 @@ struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter)
* iter->pos should always be equal to the key we just * iter->pos should always be equal to the key we just
* returned - except extents can straddle iter->pos: * returned - except extents can straddle iter->pos:
*/ */
if (!(iter->flags & BTREE_ITER_IS_EXTENTS) || if (bkey_cmp(bkey_start_pos(k.k), iter->pos) > 0)
bkey_cmp(bkey_start_pos(k.k), iter->pos) > 0)
iter->pos = bkey_start_pos(k.k); iter->pos = bkey_start_pos(k.k);
iter->uptodate = BTREE_ITER_UPTODATE; iter->uptodate = BTREE_ITER_UPTODATE;
...@@ -1743,7 +1756,10 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -1743,7 +1756,10 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
return bkey_s_c_err(ret); return bkey_s_c_err(ret);
k = __btree_iter_peek(iter, l); k = __btree_iter_peek(iter, l);
if (!k.k || bkey_cmp(bkey_start_pos(k.k), pos) > 0) if (!k.k ||
((iter->flags & BTREE_ITER_IS_EXTENTS)
? bkey_cmp(bkey_start_pos(k.k), pos) >= 0
: bkey_cmp(bkey_start_pos(k.k), pos) > 0))
k = __btree_iter_prev(iter, l); k = __btree_iter_prev(iter, l);
if (likely(k.k)) if (likely(k.k))
...@@ -1754,8 +1770,13 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -1754,8 +1770,13 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
} }
EBUG_ON(bkey_cmp(bkey_start_pos(k.k), pos) > 0); EBUG_ON(bkey_cmp(bkey_start_pos(k.k), pos) > 0);
iter->pos = bkey_start_pos(k.k);
/* Extents can straddle iter->pos: */
if (bkey_cmp(k.k->p, pos) < 0)
iter->pos = k.k->p;
iter->uptodate = BTREE_ITER_UPTODATE; iter->uptodate = BTREE_ITER_UPTODATE;
bch2_btree_iter_verify_level(iter, 0);
return k; return k;
} }
...@@ -1765,16 +1786,9 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -1765,16 +1786,9 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
*/ */
struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *iter) struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *iter)
{ {
struct bpos pos = bkey_start_pos(&iter->k); if (!bch2_btree_iter_rewind_pos(iter))
EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
bch2_btree_iter_checks(iter);
if (unlikely(!bkey_cmp(pos, POS_MIN)))
return bkey_s_c_null; return bkey_s_c_null;
bch2_btree_iter_set_pos(iter, bkey_predecessor(pos));
return bch2_btree_iter_peek_prev(iter); return bch2_btree_iter_peek_prev(iter);
} }
......
...@@ -2454,7 +2454,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2454,7 +2454,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
struct address_space *mapping = inode->v.i_mapping; struct address_space *mapping = inode->v.i_mapping;
struct bkey_buf copy; struct bkey_buf copy;
struct btree_trans trans; struct btree_trans trans;
struct btree_iter *src, *dst; struct btree_iter *src, *dst, *del;
loff_t shift, new_size; loff_t shift, new_size;
u64 src_start; u64 src_start;
int ret; int ret;
...@@ -2524,6 +2524,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2524,6 +2524,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
POS(inode->v.i_ino, src_start >> 9), POS(inode->v.i_ino, src_start >> 9),
BTREE_ITER_INTENT); BTREE_ITER_INTENT);
dst = bch2_trans_copy_iter(&trans, src); dst = bch2_trans_copy_iter(&trans, src);
del = bch2_trans_copy_iter(&trans, src);
while (1) { while (1) {
struct disk_reservation disk_res = struct disk_reservation disk_res =
...@@ -2544,8 +2545,6 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2544,8 +2545,6 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
if (!k.k || k.k->p.inode != inode->v.i_ino) if (!k.k || k.k->p.inode != inode->v.i_ino)
break; break;
BUG_ON(bkey_cmp(src->pos, bkey_start_pos(k.k)));
if (insert && if (insert &&
bkey_cmp(k.k->p, POS(inode->v.i_ino, offset >> 9)) <= 0) bkey_cmp(k.k->p, POS(inode->v.i_ino, offset >> 9)) <= 0)
break; break;
...@@ -2577,6 +2576,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2577,6 +2576,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
delete.k.p = copy.k->k.p; delete.k.p = copy.k->k.p;
delete.k.size = copy.k->k.size; delete.k.size = copy.k->k.size;
delete.k.p.offset -= shift >> 9; delete.k.p.offset -= shift >> 9;
bch2_btree_iter_set_pos(del, bkey_start_pos(&delete.k));
next_pos = insert ? bkey_start_pos(&delete.k) : delete.k.p; next_pos = insert ? bkey_start_pos(&delete.k) : delete.k.p;
...@@ -2597,9 +2597,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2597,9 +2597,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
BUG_ON(ret); BUG_ON(ret);
} }
bch2_btree_iter_set_pos(src, bkey_start_pos(&delete.k)); ret = bch2_trans_update(&trans, del, &delete, trigger_flags) ?:
ret = bch2_trans_update(&trans, src, &delete, trigger_flags) ?:
bch2_trans_update(&trans, dst, copy.k, trigger_flags) ?: bch2_trans_update(&trans, dst, copy.k, trigger_flags) ?:
bch2_trans_commit(&trans, &disk_res, bch2_trans_commit(&trans, &disk_res,
&inode->ei_journal_seq, &inode->ei_journal_seq,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment