Loading fs/bcachefs/btree_iter.c +12 −12 Original line number Diff line number Diff line Loading @@ -1010,9 +1010,9 @@ static int bch2_btree_path_traverse_all(struct btree_trans *trans) * the same position: */ if (trans->paths[idx].uptodate) { __btree_path_get(&trans->paths[idx], false); __btree_path_get(trans, &trans->paths[idx], false); ret = bch2_btree_path_traverse_one(trans, idx, 0, _THIS_IP_); __btree_path_put(&trans->paths[idx], false); __btree_path_put(trans, &trans->paths[idx], false); if (bch2_err_matches(ret, BCH_ERR_transaction_restart) || bch2_err_matches(ret, ENOMEM)) Loading Loading @@ -1225,7 +1225,7 @@ static btree_path_idx_t btree_path_clone(struct btree_trans *trans, btree_path_i { btree_path_idx_t new = btree_path_alloc(trans, src); btree_path_copy(trans, trans->paths + new, trans->paths + src); __btree_path_get(trans->paths + new, intent); __btree_path_get(trans, trans->paths + new, intent); #ifdef TRACK_PATH_ALLOCATED trans->paths[new].ip_allocated = ip; #endif Loading @@ -1236,7 +1236,7 @@ __flatten btree_path_idx_t __bch2_btree_path_make_mut(struct btree_trans *trans, btree_path_idx_t path, bool intent, unsigned long ip) { __btree_path_put(trans->paths + path, intent); __btree_path_put(trans, trans->paths + path, intent); path = btree_path_clone(trans, path, intent, ip); trans->paths[path].preserve = false; return path; Loading Loading @@ -1361,7 +1361,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in { struct btree_path *path = trans->paths + path_idx, *dup; if (!__btree_path_put(path, intent)) if (!__btree_path_put(trans, path, intent)) return; dup = path->preserve Loading Loading @@ -1392,7 +1392,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in static void bch2_path_put_nokeep(struct btree_trans *trans, btree_path_idx_t path, bool intent) { if (!__btree_path_put(trans->paths + path, intent)) if (!__btree_path_put(trans, trans->paths + path, intent)) return; __bch2_path_free(trans, path); Loading Loading @@ -1716,14 +1716,14 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans, trans->paths[path_pos].cached == cached && trans->paths[path_pos].btree_id == btree_id && trans->paths[path_pos].level == level) { __btree_path_get(trans->paths + path_pos, intent); __btree_path_get(trans, trans->paths + path_pos, intent); path_idx = bch2_btree_path_set_pos(trans, path_pos, pos, intent, ip); path = trans->paths + path_idx; } else { path_idx = btree_path_alloc(trans, path_pos); path = trans->paths + path_idx; __btree_path_get(path, intent); __btree_path_get(trans, path, intent); path->pos = pos; path->btree_id = btree_id; path->cached = cached; Loading Loading @@ -2326,7 +2326,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e * advance, same as on exit for iter->path, but only up * to snapshot */ __btree_path_get(trans->paths + iter->path, iter->flags & BTREE_ITER_intent); __btree_path_get(trans, trans->paths + iter->path, iter->flags & BTREE_ITER_intent); iter->update_path = iter->path; iter->update_path = bch2_btree_path_set_pos(trans, Loading Loading @@ -2911,9 +2911,9 @@ void bch2_trans_copy_iter(struct btree_iter *dst, struct btree_iter *src) dst->ip_allocated = _RET_IP_; #endif if (src->path) __btree_path_get(trans->paths + src->path, src->flags & BTREE_ITER_intent); __btree_path_get(trans, trans->paths + src->path, src->flags & BTREE_ITER_intent); if (src->update_path) __btree_path_get(trans->paths + src->update_path, src->flags & BTREE_ITER_intent); __btree_path_get(trans, trans->paths + src->update_path, src->flags & BTREE_ITER_intent); dst->key_cache_path = 0; } Loading Loading @@ -3237,7 +3237,7 @@ void bch2_trans_put(struct btree_trans *trans) bch2_trans_unlock(trans); trans_for_each_update(trans, i) __btree_path_put(trans->paths + i->path, true); __btree_path_put(trans, trans->paths + i->path, true); trans->nr_updates = 0; check_btree_paths_leaked(trans); Loading fs/bcachefs/btree_iter.h +18 −8 Original line number Diff line number Diff line Loading @@ -6,6 +6,12 @@ #include "btree_types.h" #include "trace.h" void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *); void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *, btree_path_idx_t); void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *); void bch2_dump_trans_updates(struct btree_trans *); void bch2_dump_trans_paths_updates(struct btree_trans *); static inline int __bkey_err(const struct bkey *k) { return PTR_ERR_OR_ZERO(k); Loading @@ -13,16 +19,26 @@ static inline int __bkey_err(const struct bkey *k) #define bkey_err(_k) __bkey_err((_k).k) static inline void __btree_path_get(struct btree_path *path, bool intent) static inline void __btree_path_get(struct btree_trans *trans, struct btree_path *path, bool intent) { unsigned idx = path - trans->paths; EBUG_ON(!test_bit(idx, trans->paths_allocated)); if (unlikely(path->ref == U8_MAX)) { bch2_dump_trans_paths_updates(trans); panic("path %u refcount overflow\n", idx); } path->ref++; path->intent_ref += intent; } static inline bool __btree_path_put(struct btree_path *path, bool intent) static inline bool __btree_path_put(struct btree_trans *trans, struct btree_path *path, bool intent) { EBUG_ON(!test_bit(path - trans->paths, trans->paths_allocated)); EBUG_ON(!path->ref); EBUG_ON(!path->intent_ref && intent); path->intent_ref -= intent; return --path->ref == 0; } Loading Loading @@ -894,12 +910,6 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans, _ret; \ }) void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *); void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *, btree_path_idx_t); void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *); void bch2_dump_trans_updates(struct btree_trans *); void bch2_dump_trans_paths_updates(struct btree_trans *); struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned); void bch2_trans_put(struct btree_trans *); Loading fs/bcachefs/btree_update.c +1 −1 Original line number Diff line number Diff line Loading @@ -449,7 +449,7 @@ bch2_trans_update_by_path(struct btree_trans *trans, btree_path_idx_t path_idx, } } __btree_path_get(trans->paths + i->path, true); __btree_path_get(trans, trans->paths + i->path, true); /* * If a key is present in the key cache, it must also exist in the Loading Loading
fs/bcachefs/btree_iter.c +12 −12 Original line number Diff line number Diff line Loading @@ -1010,9 +1010,9 @@ static int bch2_btree_path_traverse_all(struct btree_trans *trans) * the same position: */ if (trans->paths[idx].uptodate) { __btree_path_get(&trans->paths[idx], false); __btree_path_get(trans, &trans->paths[idx], false); ret = bch2_btree_path_traverse_one(trans, idx, 0, _THIS_IP_); __btree_path_put(&trans->paths[idx], false); __btree_path_put(trans, &trans->paths[idx], false); if (bch2_err_matches(ret, BCH_ERR_transaction_restart) || bch2_err_matches(ret, ENOMEM)) Loading Loading @@ -1225,7 +1225,7 @@ static btree_path_idx_t btree_path_clone(struct btree_trans *trans, btree_path_i { btree_path_idx_t new = btree_path_alloc(trans, src); btree_path_copy(trans, trans->paths + new, trans->paths + src); __btree_path_get(trans->paths + new, intent); __btree_path_get(trans, trans->paths + new, intent); #ifdef TRACK_PATH_ALLOCATED trans->paths[new].ip_allocated = ip; #endif Loading @@ -1236,7 +1236,7 @@ __flatten btree_path_idx_t __bch2_btree_path_make_mut(struct btree_trans *trans, btree_path_idx_t path, bool intent, unsigned long ip) { __btree_path_put(trans->paths + path, intent); __btree_path_put(trans, trans->paths + path, intent); path = btree_path_clone(trans, path, intent, ip); trans->paths[path].preserve = false; return path; Loading Loading @@ -1361,7 +1361,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in { struct btree_path *path = trans->paths + path_idx, *dup; if (!__btree_path_put(path, intent)) if (!__btree_path_put(trans, path, intent)) return; dup = path->preserve Loading Loading @@ -1392,7 +1392,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in static void bch2_path_put_nokeep(struct btree_trans *trans, btree_path_idx_t path, bool intent) { if (!__btree_path_put(trans->paths + path, intent)) if (!__btree_path_put(trans, trans->paths + path, intent)) return; __bch2_path_free(trans, path); Loading Loading @@ -1716,14 +1716,14 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans, trans->paths[path_pos].cached == cached && trans->paths[path_pos].btree_id == btree_id && trans->paths[path_pos].level == level) { __btree_path_get(trans->paths + path_pos, intent); __btree_path_get(trans, trans->paths + path_pos, intent); path_idx = bch2_btree_path_set_pos(trans, path_pos, pos, intent, ip); path = trans->paths + path_idx; } else { path_idx = btree_path_alloc(trans, path_pos); path = trans->paths + path_idx; __btree_path_get(path, intent); __btree_path_get(trans, path, intent); path->pos = pos; path->btree_id = btree_id; path->cached = cached; Loading Loading @@ -2326,7 +2326,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e * advance, same as on exit for iter->path, but only up * to snapshot */ __btree_path_get(trans->paths + iter->path, iter->flags & BTREE_ITER_intent); __btree_path_get(trans, trans->paths + iter->path, iter->flags & BTREE_ITER_intent); iter->update_path = iter->path; iter->update_path = bch2_btree_path_set_pos(trans, Loading Loading @@ -2911,9 +2911,9 @@ void bch2_trans_copy_iter(struct btree_iter *dst, struct btree_iter *src) dst->ip_allocated = _RET_IP_; #endif if (src->path) __btree_path_get(trans->paths + src->path, src->flags & BTREE_ITER_intent); __btree_path_get(trans, trans->paths + src->path, src->flags & BTREE_ITER_intent); if (src->update_path) __btree_path_get(trans->paths + src->update_path, src->flags & BTREE_ITER_intent); __btree_path_get(trans, trans->paths + src->update_path, src->flags & BTREE_ITER_intent); dst->key_cache_path = 0; } Loading Loading @@ -3237,7 +3237,7 @@ void bch2_trans_put(struct btree_trans *trans) bch2_trans_unlock(trans); trans_for_each_update(trans, i) __btree_path_put(trans->paths + i->path, true); __btree_path_put(trans, trans->paths + i->path, true); trans->nr_updates = 0; check_btree_paths_leaked(trans); Loading
fs/bcachefs/btree_iter.h +18 −8 Original line number Diff line number Diff line Loading @@ -6,6 +6,12 @@ #include "btree_types.h" #include "trace.h" void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *); void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *, btree_path_idx_t); void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *); void bch2_dump_trans_updates(struct btree_trans *); void bch2_dump_trans_paths_updates(struct btree_trans *); static inline int __bkey_err(const struct bkey *k) { return PTR_ERR_OR_ZERO(k); Loading @@ -13,16 +19,26 @@ static inline int __bkey_err(const struct bkey *k) #define bkey_err(_k) __bkey_err((_k).k) static inline void __btree_path_get(struct btree_path *path, bool intent) static inline void __btree_path_get(struct btree_trans *trans, struct btree_path *path, bool intent) { unsigned idx = path - trans->paths; EBUG_ON(!test_bit(idx, trans->paths_allocated)); if (unlikely(path->ref == U8_MAX)) { bch2_dump_trans_paths_updates(trans); panic("path %u refcount overflow\n", idx); } path->ref++; path->intent_ref += intent; } static inline bool __btree_path_put(struct btree_path *path, bool intent) static inline bool __btree_path_put(struct btree_trans *trans, struct btree_path *path, bool intent) { EBUG_ON(!test_bit(path - trans->paths, trans->paths_allocated)); EBUG_ON(!path->ref); EBUG_ON(!path->intent_ref && intent); path->intent_ref -= intent; return --path->ref == 0; } Loading Loading @@ -894,12 +910,6 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans, _ret; \ }) void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *); void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *, btree_path_idx_t); void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *); void bch2_dump_trans_updates(struct btree_trans *); void bch2_dump_trans_paths_updates(struct btree_trans *); struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned); void bch2_trans_put(struct btree_trans *); Loading
fs/bcachefs/btree_update.c +1 −1 Original line number Diff line number Diff line Loading @@ -449,7 +449,7 @@ bch2_trans_update_by_path(struct btree_trans *trans, btree_path_idx_t path_idx, } } __btree_path_get(trans->paths + i->path, true); __btree_path_get(trans, trans->paths + i->path, true); /* * If a key is present in the key cache, it must also exist in the Loading