diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 757e5650f33c..525afe3509ec 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -2020,6 +2020,13 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, unsigned flags) { struct btree_iter *iter, *best = NULL; + struct bpos real_pos, pos_min = POS_MIN; + + if ((flags & BTREE_ITER_TYPE) != BTREE_ITER_NODES && + btree_node_type_is_extents(btree_id) && + !(flags & BTREE_ITER_NOT_EXTENTS) && + !(flags & BTREE_ITER_ALL_SNAPSHOTS)) + flags |= BTREE_ITER_IS_EXTENTS; if ((flags & BTREE_ITER_TYPE) != BTREE_ITER_NODES && !btree_type_has_snapshots(btree_id)) @@ -2029,6 +2036,12 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, pos.snapshot = btree_type_has_snapshots(btree_id) ? U32_MAX : 0; + real_pos = pos; + + if ((flags & BTREE_ITER_IS_EXTENTS) && + bkey_cmp(pos, POS_MAX)) + real_pos = bpos_nosnap_successor(pos); + trans_for_each_iter(trans, iter) { if (btree_iter_type(iter) != (flags & BTREE_ITER_TYPE)) continue; @@ -2037,8 +2050,8 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, continue; if (best) { - int cmp = bkey_cmp(bpos_diff(best->real_pos, pos), - bpos_diff(iter->real_pos, pos)); + int cmp = bkey_cmp(bpos_diff(best->real_pos, real_pos), + bpos_diff(iter->real_pos, real_pos)); if (cmp < 0 || ((cmp == 0 && btree_iter_keep(trans, iter)))) @@ -2048,6 +2061,13 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, best = iter; } + trace_trans_get_iter(_RET_IP_, trans->ip, + btree_id, + &real_pos, locks_want, + best ? &best->real_pos : &pos_min, + best ? best->locks_want : 0, + best ? best->uptodate : BTREE_ITER_NEED_TRAVERSE); + if (!best) { iter = btree_trans_iter_alloc(trans); bch2_btree_iter_init(trans, iter, btree_id); @@ -2061,12 +2081,6 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, trans->iters_live |= 1ULL << iter->idx; trans->iters_touched |= 1ULL << iter->idx; - if ((flags & BTREE_ITER_TYPE) != BTREE_ITER_NODES && - btree_node_type_is_extents(btree_id) && - !(flags & BTREE_ITER_NOT_EXTENTS) && - !(flags & BTREE_ITER_ALL_SNAPSHOTS)) - flags |= BTREE_ITER_IS_EXTENTS; - iter->flags = flags; iter->snapshot = pos.snapshot; @@ -2098,7 +2112,7 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, iter->min_depth = depth; bch2_btree_iter_set_pos(iter, pos); - btree_iter_set_search_pos(iter, btree_iter_search_key(iter)); + btree_iter_set_search_pos(iter, real_pos); return iter; } diff --git a/fs/bcachefs/trace.h b/fs/bcachefs/trace.h index c6d98f4c50e7..7e518f7618d4 100644 --- a/fs/bcachefs/trace.h +++ b/fs/bcachefs/trace.h @@ -528,6 +528,62 @@ TRACE_EVENT(copygc, __entry->buckets_moved, __entry->buckets_not_moved) ); +TRACE_EVENT(trans_get_iter, + TP_PROTO(unsigned long caller, unsigned long ip, + enum btree_id btree_id, + struct bpos *pos_want, + unsigned locks_want, + struct bpos *pos_found, + unsigned locks_found, + unsigned uptodate), + TP_ARGS(caller, ip, btree_id, + pos_want, locks_want, + pos_found, locks_found, + uptodate), + + TP_STRUCT__entry( + __field(unsigned long, caller ) + __field(unsigned long, ip ) + __field(u8, btree_id ) + __field(u8, uptodate ) + __field(u8, locks_want ) + __field(u8, locks_found ) + __field(u64, pos_want_inode ) + __field(u64, pos_want_offset ) + __field(u32, pos_want_snapshot ) + __field(u64, pos_found_inode ) + __field(u64, pos_found_offset ) + __field(u32, pos_found_snapshot ) + ), + + TP_fast_assign( + __entry->caller = caller; + __entry->ip = ip; + __entry->btree_id = btree_id; + __entry->uptodate = uptodate; + __entry->pos_want_inode = pos_want->inode; + __entry->pos_want_offset = pos_want->offset; + __entry->pos_want_snapshot = pos_want->snapshot; + __entry->pos_found_inode = pos_found->inode; + __entry->pos_found_offset = pos_found->offset; + __entry->pos_found_snapshot = pos_found->snapshot; + ), + + TP_printk("%ps %pS btree %u uptodate %u want %llu:%llu:%u locks %u found %llu:%llu:%u locks %u", + (void *) __entry->caller, + (void *) __entry->ip, + __entry->btree_id, + __entry->uptodate, + __entry->pos_want_inode, + __entry->pos_want_offset, + __entry->pos_want_snapshot, + __entry->locks_want, + __entry->pos_found_inode, + __entry->pos_found_offset, + __entry->pos_found_snapshot, + __entry->locks_found) +); + TRACE_EVENT(transaction_restart_ip, TP_PROTO(unsigned long caller, unsigned long ip), TP_ARGS(caller, ip),