Skip to content

Commit 1f8aede

Browse files
author
Kent Overstreet
committed
bcachefs: fix bch2_journal_keys_peek_prev_min() underflow
Signed-off-by: Kent Overstreet <[email protected]>
1 parent f5109c2 commit 1f8aede

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

fs/bcachefs/btree_journal_iter.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,15 @@ struct bkey_i *bch2_journal_keys_peek_prev_min(struct bch_fs *c, enum btree_id b
137137
struct journal_key *k;
138138

139139
BUG_ON(*idx > keys->nr);
140+
141+
if (!keys->nr)
142+
return NULL;
140143
search:
141144
if (!*idx)
142145
*idx = __bch2_journal_key_search(keys, btree_id, level, pos);
143146

144147
while (*idx < keys->nr &&
145-
__journal_key_cmp(btree_id, level, end_pos, idx_to_key(keys, *idx - 1)) >= 0) {
148+
__journal_key_cmp(btree_id, level, end_pos, idx_to_key(keys, *idx)) >= 0) {
146149
(*idx)++;
147150
iters++;
148151
if (iters == 10) {
@@ -151,18 +154,23 @@ struct bkey_i *bch2_journal_keys_peek_prev_min(struct bch_fs *c, enum btree_id b
151154
}
152155
}
153156

157+
if (*idx == keys->nr)
158+
--(*idx);
159+
154160
struct bkey_i *ret = NULL;
155161
rcu_read_lock(); /* for overwritten_ranges */
156162

157-
while ((k = *idx < keys->nr ? idx_to_key(keys, *idx) : NULL)) {
163+
while (true) {
164+
k = idx_to_key(keys, *idx);
158165
if (__journal_key_cmp(btree_id, level, end_pos, k) > 0)
159166
break;
160167

161168
if (k->overwritten) {
162169
if (k->overwritten_range)
163-
*idx = rcu_dereference(k->overwritten_range)->start - 1;
164-
else
165-
*idx -= 1;
170+
*idx = rcu_dereference(k->overwritten_range)->start;
171+
if (!*idx)
172+
break;
173+
--(*idx);
166174
continue;
167175
}
168176

@@ -171,6 +179,8 @@ struct bkey_i *bch2_journal_keys_peek_prev_min(struct bch_fs *c, enum btree_id b
171179
break;
172180
}
173181

182+
if (!*idx)
183+
break;
174184
--(*idx);
175185
iters++;
176186
if (iters == 10) {

0 commit comments

Comments
 (0)