summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-03-17 21:35:51 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2022-04-02 16:02:55 -0400
commitb2bed1bcea83f60cfdc8331dd0059c5d37a0407b (patch)
tree7438744841e3908f233d6c0edd471bc8dbb4342e
parent8dd3fe282927d03eb712f14ed562f934e67b8550 (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.h2
-rw-r--r--fs/bcachefs/btree_update_leaf.c5
-rw-r--r--include/trace/events/bcachefs.h40
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 */