diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-03-17 21:35:51 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-02 16:02:55 -0400 |
commit | b2bed1bcea83f60cfdc8331dd0059c5d37a0407b (patch) | |
tree | 7438744841e3908f233d6c0edd471bc8dbb4342e | |
parent | 8dd3fe282927d03eb712f14ed562f934e67b8550 (diff) |
bcachefs: Fix large key cache keys
Previously, we'd go into an infinite loop when attempting to cache a
bkey in the key cache larger than 128 u64s - since we were only using a
u8 for the size field, it'd get rounded up to 256 then truncated to 0.
Oops.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/btree_types.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 5 | ||||
-rw-r--r-- | include/trace/events/bcachefs.h | 40 |
3 files changed, 41 insertions, 6 deletions
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 788b9811148f..993f04f52149 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -326,7 +326,7 @@ struct bkey_cached { struct btree_bkey_cached_common c; unsigned long flags; - u8 u64s; + u16 u64s; bool valid; u32 btree_trans_barrier_seq; struct bkey_cached_key key; diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index fec09f00c4e3..8d185c7c10ef 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -349,7 +349,7 @@ btree_key_can_insert_cached(struct btree_trans *trans, { struct bch_fs *c = trans->c; struct bkey_cached *ck = (void *) path->l[0].b; - unsigned new_u64s; + unsigned old_u64s = ck->u64s, new_u64s; struct bkey_i *new_k; EBUG_ON(path->level); @@ -383,7 +383,8 @@ btree_key_can_insert_cached(struct btree_trans *trans, * transaction restart: */ trace_trans_restart_key_cache_key_realloced(trans->fn, _RET_IP_, - path->btree_id, &path->pos); + path->btree_id, &path->pos, + old_u64s, new_u64s); /* * Not using btree_trans_restart() because we can't unlock here, we have * write locks held: diff --git a/include/trace/events/bcachefs.h b/include/trace/events/bcachefs.h index 0fd2fc11b86b..08de7e617247 100644 --- a/include/trace/events/bcachefs.h +++ b/include/trace/events/bcachefs.h @@ -943,12 +943,46 @@ TRACE_EVENT(trans_restart_mem_realloced, __entry->bytes) ); -DEFINE_EVENT(transaction_restart_iter, trans_restart_key_cache_key_realloced, +TRACE_EVENT(trans_restart_key_cache_key_realloced, TP_PROTO(const char *trans_fn, unsigned long caller_ip, enum btree_id btree_id, - struct bpos *pos), - TP_ARGS(trans_fn, caller_ip, btree_id, pos) + struct bpos *pos, + unsigned old_u64s, + unsigned new_u64s), + TP_ARGS(trans_fn, caller_ip, btree_id, pos, old_u64s, new_u64s), + + TP_STRUCT__entry( + __array(char, trans_fn, 24 ) + __field(unsigned long, caller_ip ) + __field(enum btree_id, btree_id ) + __field(u64, inode ) + __field(u64, offset ) + __field(u32, snapshot ) + __field(u32, old_u64s ) + __field(u32, new_u64s ) + ), + + TP_fast_assign( + strncpy(__entry->trans_fn, trans_fn, sizeof(__entry->trans_fn)); + __entry->caller_ip = caller_ip; + __entry->btree_id = btree_id; + __entry->inode = pos->inode; + __entry->offset = pos->offset; + __entry->snapshot = pos->snapshot; + __entry->old_u64s = old_u64s; + __entry->new_u64s = new_u64s; + ), + + TP_printk("%s %pS btree %s pos %llu:%llu:%u old_u64s %u new_u64s %u", + __entry->trans_fn, + (void *) __entry->caller_ip, + bch2_btree_ids[__entry->btree_id], + __entry->inode, + __entry->offset, + __entry->snapshot, + __entry->old_u64s, + __entry->new_u64s) ); #endif /* _TRACE_BCACHE_H */ |