@@ -130,22 +130,45 @@ struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *c, enum btree_id btree
130130 return bch2_journal_keys_peek_upto (c , btree_id , level , pos , pos , & idx );
131131}
132132
133+ static void journal_iter_verify (struct journal_iter * iter )
134+ {
135+ struct journal_keys * keys = iter -> keys ;
136+ size_t gap_size = keys -> size - keys -> nr ;
137+
138+ BUG_ON (iter -> idx >= keys -> gap &&
139+ iter -> idx < keys -> gap + gap_size );
140+
141+ if (iter -> idx < keys -> size ) {
142+ struct journal_key * k = keys -> data + iter -> idx ;
143+
144+ int cmp = cmp_int (k -> btree_id , iter -> btree_id ) ?:
145+ cmp_int (k -> level , iter -> level );
146+ BUG_ON (cmp < 0 );
147+ }
148+ }
149+
133150static void journal_iters_fix (struct bch_fs * c )
134151{
135152 struct journal_keys * keys = & c -> journal_keys ;
136153 /* The key we just inserted is immediately before the gap: */
137154 size_t gap_end = keys -> gap + (keys -> size - keys -> nr );
138- struct btree_and_journal_iter * iter ;
155+ struct journal_key * new_key = & keys -> data [keys -> gap - 1 ];
156+ struct journal_iter * iter ;
139157
140158 /*
141159 * If an iterator points one after the key we just inserted, decrement
142160 * the iterator so it points at the key we just inserted - if the
143161 * decrement was unnecessary, bch2_btree_and_journal_iter_peek() will
144162 * handle that:
145163 */
146- list_for_each_entry (iter , & c -> journal_iters , journal .list )
147- if (iter -> journal .idx == gap_end )
148- iter -> journal .idx = keys -> gap - 1 ;
164+ list_for_each_entry (iter , & c -> journal_iters , list ) {
165+ journal_iter_verify (iter );
166+ if (iter -> idx == gap_end &&
167+ new_key -> btree_id == iter -> btree_id &&
168+ new_key -> level == iter -> level )
169+ iter -> idx = keys -> gap - 1 ;
170+ journal_iter_verify (iter );
171+ }
149172}
150173
151174static void journal_iters_move_gap (struct bch_fs * c , size_t old_gap , size_t new_gap )
@@ -192,7 +215,12 @@ int bch2_journal_key_insert_take(struct bch_fs *c, enum btree_id id,
192215 if (idx > keys -> gap )
193216 idx -= keys -> size - keys -> nr ;
194217
218+ size_t old_gap = keys -> gap ;
219+
195220 if (keys -> nr == keys -> size ) {
221+ journal_iters_move_gap (c , old_gap , keys -> size );
222+ old_gap = keys -> size ;
223+
196224 struct journal_keys new_keys = {
197225 .nr = keys -> nr ,
198226 .size = max_t (size_t , keys -> size , 8 ) * 2 ,
@@ -216,7 +244,7 @@ int bch2_journal_key_insert_take(struct bch_fs *c, enum btree_id id,
216244 keys -> gap = keys -> nr ;
217245 }
218246
219- journal_iters_move_gap (c , keys -> gap , idx );
247+ journal_iters_move_gap (c , old_gap , idx );
220248
221249 move_gap (keys , idx );
222250
@@ -301,16 +329,21 @@ static void bch2_journal_iter_advance(struct journal_iter *iter)
301329
302330static struct bkey_s_c bch2_journal_iter_peek (struct journal_iter * iter )
303331{
304- struct journal_key * k = iter -> keys -> data + iter -> idx ;
332+ journal_iter_verify (iter );
333+
334+ while (iter -> idx < iter -> keys -> size ) {
335+ struct journal_key * k = iter -> keys -> data + iter -> idx ;
336+
337+ int cmp = cmp_int (k -> btree_id , iter -> btree_id ) ?:
338+ cmp_int (k -> level , iter -> level );
339+ if (cmp > 0 )
340+ break ;
341+ BUG_ON (cmp );
305342
306- while (k < iter -> keys -> data + iter -> keys -> size &&
307- k -> btree_id == iter -> btree_id &&
308- k -> level == iter -> level ) {
309343 if (!k -> overwritten )
310344 return bkey_i_to_s_c (k -> k );
311345
312346 bch2_journal_iter_advance (iter );
313- k = iter -> keys -> data + iter -> idx ;
314347 }
315348
316349 return bkey_s_c_null ;
@@ -330,6 +363,8 @@ static void bch2_journal_iter_init(struct bch_fs *c,
330363 iter -> level = level ;
331364 iter -> keys = & c -> journal_keys ;
332365 iter -> idx = bch2_journal_key_search (& c -> journal_keys , id , level , pos );
366+
367+ journal_iter_verify (iter );
333368}
334369
335370static struct bkey_s_c bch2_journal_iter_peek_btree (struct btree_and_journal_iter * iter )
0 commit comments