Commit 9f6bd307 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Reduce iter->trans usage

Disfavoured, and should go away.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent 84841b0d
...@@ -498,7 +498,7 @@ void bch2_btree_init_next(struct btree_trans *trans, ...@@ -498,7 +498,7 @@ void bch2_btree_init_next(struct btree_trans *trans,
bch2_btree_build_aux_trees(b); bch2_btree_build_aux_trees(b);
if (iter && reinit_iter) if (iter && reinit_iter)
bch2_btree_iter_reinit_node(iter, b); bch2_btree_iter_reinit_node(trans, iter, b);
} }
static void btree_pos_to_text(struct printbuf *out, struct bch_fs *c, static void btree_pos_to_text(struct printbuf *out, struct bch_fs *c,
......
...@@ -19,10 +19,11 @@ ...@@ -19,10 +19,11 @@
static void btree_iter_set_search_pos(struct btree_iter *, struct bpos); static void btree_iter_set_search_pos(struct btree_iter *, struct bpos);
static inline void btree_trans_sort_iters(struct btree_trans *); static inline void btree_trans_sort_iters(struct btree_trans *);
static struct btree_iter *btree_iter_child_alloc(struct btree_iter *, unsigned long); static struct btree_iter *btree_iter_child_alloc(struct btree_trans *,
struct btree_iter *, unsigned long);
static struct btree_iter *btree_trans_iter_alloc(struct btree_trans *, static struct btree_iter *btree_trans_iter_alloc(struct btree_trans *,
struct btree_iter *); struct btree_iter *);
static void btree_iter_copy(struct btree_iter *, struct btree_iter *); static void btree_iter_copy(struct btree_trans *, struct btree_iter *, struct btree_iter *);
static inline int btree_iter_cmp(const struct btree_iter *l, static inline int btree_iter_cmp(const struct btree_iter *l,
const struct btree_iter *r) const struct btree_iter *r)
...@@ -100,19 +101,21 @@ static inline bool btree_iter_pos_in_node(struct btree_iter *iter, ...@@ -100,19 +101,21 @@ static inline bool btree_iter_pos_in_node(struct btree_iter *iter,
/* Btree node locking: */ /* Btree node locking: */
void bch2_btree_node_unlock_write(struct btree *b, struct btree_iter *iter) void bch2_btree_node_unlock_write(struct btree_trans *trans,
struct btree_iter *iter, struct btree *b)
{ {
bch2_btree_node_unlock_write_inlined(b, iter); bch2_btree_node_unlock_write_inlined(trans, iter, b);
} }
void __bch2_btree_node_lock_write(struct btree *b, struct btree_iter *iter) void __bch2_btree_node_lock_write(struct btree_trans *trans,
struct btree_iter *iter, struct btree *b)
{ {
struct btree_iter *linked; struct btree_iter *linked;
unsigned readers = 0; unsigned readers = 0;
EBUG_ON(!btree_node_intent_locked(iter, b->c.level)); EBUG_ON(!btree_node_intent_locked(iter, b->c.level));
trans_for_each_iter(iter->trans, linked) trans_for_each_iter(trans, linked)
if (linked->l[b->c.level].b == b && if (linked->l[b->c.level].b == b &&
btree_node_read_locked(linked, b->c.level)) btree_node_read_locked(linked, b->c.level))
readers++; readers++;
...@@ -129,7 +132,7 @@ void __bch2_btree_node_lock_write(struct btree *b, struct btree_iter *iter) ...@@ -129,7 +132,7 @@ void __bch2_btree_node_lock_write(struct btree *b, struct btree_iter *iter)
else else
this_cpu_sub(*b->c.lock.readers, readers); this_cpu_sub(*b->c.lock.readers, readers);
btree_node_lock_type(iter->trans->c, b, SIX_LOCK_write); btree_node_lock_type(trans->c, b, SIX_LOCK_write);
if (!b->c.lock.readers) if (!b->c.lock.readers)
atomic64_add(__SIX_VAL(read_lock, readers), atomic64_add(__SIX_VAL(read_lock, readers),
...@@ -191,8 +194,9 @@ static bool bch2_btree_node_upgrade(struct btree_iter *iter, unsigned level) ...@@ -191,8 +194,9 @@ static bool bch2_btree_node_upgrade(struct btree_iter *iter, unsigned level)
return true; return true;
} }
static inline bool btree_iter_get_locks(struct btree_iter *iter, bool upgrade, static inline bool btree_iter_get_locks(struct btree_trans *trans,
unsigned long trace_ip) struct btree_iter *iter,
bool upgrade, unsigned long trace_ip)
{ {
unsigned l = iter->level; unsigned l = iter->level;
int fail_idx = -1; int fail_idx = -1;
...@@ -206,7 +210,7 @@ static inline bool btree_iter_get_locks(struct btree_iter *iter, bool upgrade, ...@@ -206,7 +210,7 @@ static inline bool btree_iter_get_locks(struct btree_iter *iter, bool upgrade,
: bch2_btree_node_relock(iter, l))) { : bch2_btree_node_relock(iter, l))) {
(upgrade (upgrade
? trace_node_upgrade_fail ? trace_node_upgrade_fail
: trace_node_relock_fail)(iter->trans->ip, trace_ip, : trace_node_relock_fail)(trans->ip, trace_ip,
btree_iter_type(iter) == BTREE_ITER_CACHED, btree_iter_type(iter) == BTREE_ITER_CACHED,
iter->btree_id, &iter->real_pos, iter->btree_id, &iter->real_pos,
l, iter->l[l].lock_seq, l, iter->l[l].lock_seq,
...@@ -237,7 +241,7 @@ static inline bool btree_iter_get_locks(struct btree_iter *iter, bool upgrade, ...@@ -237,7 +241,7 @@ static inline bool btree_iter_get_locks(struct btree_iter *iter, bool upgrade,
if (iter->uptodate == BTREE_ITER_NEED_RELOCK) if (iter->uptodate == BTREE_ITER_NEED_RELOCK)
iter->uptodate = BTREE_ITER_NEED_PEEK; iter->uptodate = BTREE_ITER_NEED_PEEK;
bch2_btree_trans_verify_locks(iter->trans); bch2_btree_trans_verify_locks(trans);
return iter->uptodate < BTREE_ITER_NEED_RELOCK; return iter->uptodate < BTREE_ITER_NEED_RELOCK;
} }
...@@ -363,11 +367,12 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos, ...@@ -363,11 +367,12 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
/* Btree iterator locking: */ /* Btree iterator locking: */
#ifdef CONFIG_BCACHEFS_DEBUG #ifdef CONFIG_BCACHEFS_DEBUG
static void bch2_btree_iter_verify_locks(struct btree_iter *iter) static void bch2_btree_iter_verify_locks(struct btree_trans *trans,
struct btree_iter *iter)
{ {
unsigned l; unsigned l;
if (!(iter->trans->iters_linked & (1ULL << iter->idx))) { if (!(trans->iters_linked & (1ULL << iter->idx))) {
BUG_ON(iter->nodes_locked); BUG_ON(iter->nodes_locked);
return; return;
} }
...@@ -387,10 +392,11 @@ void bch2_btree_trans_verify_locks(struct btree_trans *trans) ...@@ -387,10 +392,11 @@ void bch2_btree_trans_verify_locks(struct btree_trans *trans)
struct btree_iter *iter; struct btree_iter *iter;
trans_for_each_iter(trans, iter) trans_for_each_iter(trans, iter)
bch2_btree_iter_verify_locks(iter); bch2_btree_iter_verify_locks(trans, iter);
} }
#else #else
static inline void bch2_btree_iter_verify_locks(struct btree_iter *iter) {} static inline void bch2_btree_iter_verify_locks(struct btree_trans *trans,
struct btree_iter *iter) {}
#endif #endif
/* /*
...@@ -398,13 +404,14 @@ static inline void bch2_btree_iter_verify_locks(struct btree_iter *iter) {} ...@@ -398,13 +404,14 @@ static inline void bch2_btree_iter_verify_locks(struct btree_iter *iter) {}
*/ */
bool bch2_btree_iter_relock_intent(struct btree_iter *iter) bool bch2_btree_iter_relock_intent(struct btree_iter *iter)
{ {
struct btree_trans *trans = iter->trans;
unsigned l; unsigned l;
for (l = iter->level; for (l = iter->level;
l < iter->locks_want && btree_iter_node(iter, l); l < iter->locks_want && btree_iter_node(iter, l);
l++) { l++) {
if (!bch2_btree_node_relock(iter, l)) { if (!bch2_btree_node_relock(iter, l)) {
trace_node_relock_fail(iter->trans->ip, _RET_IP_, trace_node_relock_fail(trans->ip, _RET_IP_,
btree_iter_type(iter) == BTREE_ITER_CACHED, btree_iter_type(iter) == BTREE_ITER_CACHED,
iter->btree_id, &iter->real_pos, iter->btree_id, &iter->real_pos,
l, iter->l[l].lock_seq, l, iter->l[l].lock_seq,
...@@ -415,7 +422,7 @@ bool bch2_btree_iter_relock_intent(struct btree_iter *iter) ...@@ -415,7 +422,7 @@ bool bch2_btree_iter_relock_intent(struct btree_iter *iter)
? iter->l[l].b->c.lock.state.seq ? iter->l[l].b->c.lock.state.seq
: 0); : 0);
btree_iter_set_dirty(iter, BTREE_ITER_NEED_TRAVERSE); btree_iter_set_dirty(iter, BTREE_ITER_NEED_TRAVERSE);
btree_trans_restart(iter->trans); btree_trans_restart(trans);
return false; return false;
} }
} }
...@@ -424,25 +431,27 @@ bool bch2_btree_iter_relock_intent(struct btree_iter *iter) ...@@ -424,25 +431,27 @@ bool bch2_btree_iter_relock_intent(struct btree_iter *iter)
} }
__flatten __flatten
bool bch2_btree_iter_relock(struct btree_iter *iter, unsigned long trace_ip) static bool bch2_btree_iter_relock(struct btree_trans *trans,
struct btree_iter *iter, unsigned long trace_ip)
{ {
bool ret = btree_iter_get_locks(iter, false, trace_ip); bool ret = btree_iter_get_locks(trans, iter, false, trace_ip);
if (!ret) if (!ret)
btree_trans_restart(iter->trans); btree_trans_restart(trans);
return ret; return ret;
} }
bool __bch2_btree_iter_upgrade(struct btree_iter *iter, bool __bch2_btree_iter_upgrade(struct btree_iter *iter,
unsigned new_locks_want) unsigned new_locks_want)
{ {
struct btree_trans *trans = iter->trans;
struct btree_iter *linked; struct btree_iter *linked;
EBUG_ON(iter->locks_want >= new_locks_want); EBUG_ON(iter->locks_want >= new_locks_want);
iter->locks_want = new_locks_want; iter->locks_want = new_locks_want;
if (btree_iter_get_locks(iter, true, _THIS_IP_)) if (btree_iter_get_locks(trans, iter, true, _THIS_IP_))
return true; return true;
/* /*
...@@ -464,17 +473,17 @@ bool __bch2_btree_iter_upgrade(struct btree_iter *iter, ...@@ -464,17 +473,17 @@ bool __bch2_btree_iter_upgrade(struct btree_iter *iter,
* before interior nodes - now that's handled by * before interior nodes - now that's handled by
* bch2_btree_iter_traverse_all(). * bch2_btree_iter_traverse_all().
*/ */
trans_for_each_iter(iter->trans, linked) trans_for_each_iter(trans, linked)
if (linked != iter && if (linked != iter &&
btree_iter_type(linked) == btree_iter_type(iter) && btree_iter_type(linked) == btree_iter_type(iter) &&
linked->btree_id == iter->btree_id && linked->btree_id == iter->btree_id &&
linked->locks_want < new_locks_want) { linked->locks_want < new_locks_want) {
linked->locks_want = new_locks_want; linked->locks_want = new_locks_want;
btree_iter_get_locks(linked, true, _THIS_IP_); btree_iter_get_locks(trans, linked, true, _THIS_IP_);
} }
if (iter->should_be_locked) if (iter->should_be_locked)
btree_trans_restart(iter->trans); btree_trans_restart(trans);
return false; return false;
} }
...@@ -528,7 +537,7 @@ bool bch2_trans_relock(struct btree_trans *trans) ...@@ -528,7 +537,7 @@ bool bch2_trans_relock(struct btree_trans *trans)
trans_for_each_iter(trans, iter) trans_for_each_iter(trans, iter)
if (btree_iter_should_be_locked(iter) && if (btree_iter_should_be_locked(iter) &&
!bch2_btree_iter_relock(iter, _RET_IP_)) { !bch2_btree_iter_relock(trans, iter, _RET_IP_)) {
trace_trans_restart_relock(trans->ip, _RET_IP_, trace_trans_restart_relock(trans->ip, _RET_IP_,
iter->btree_id, &iter->real_pos); iter->btree_id, &iter->real_pos);
BUG_ON(!trans->restarted); BUG_ON(!trans->restarted);
...@@ -686,7 +695,7 @@ static void bch2_btree_iter_verify(struct btree_iter *iter) ...@@ -686,7 +695,7 @@ static void bch2_btree_iter_verify(struct btree_iter *iter)
bch2_btree_iter_verify_level(iter, i); bch2_btree_iter_verify_level(iter, i);
} }
bch2_btree_iter_verify_locks(iter); bch2_btree_iter_verify_locks(trans, iter);
} }
static void bch2_btree_iter_verify_entry_exit(struct btree_iter *iter) static void bch2_btree_iter_verify_entry_exit(struct btree_iter *iter)
...@@ -753,13 +762,14 @@ static void __bch2_btree_iter_fix_key_modified(struct btree_iter *iter, ...@@ -753,13 +762,14 @@ static void __bch2_btree_iter_fix_key_modified(struct btree_iter *iter,
btree_iter_set_dirty(iter, BTREE_ITER_NEED_PEEK); btree_iter_set_dirty(iter, BTREE_ITER_NEED_PEEK);
} }
void bch2_btree_iter_fix_key_modified(struct btree_iter *iter, void bch2_btree_iter_fix_key_modified(struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b, struct btree *b,
struct bkey_packed *where) struct bkey_packed *where)
{ {
struct btree_iter *linked; struct btree_iter *linked;
trans_for_each_iter_with_node(iter->trans, b, linked) { trans_for_each_iter_with_node(trans, b, linked) {
__bch2_btree_iter_fix_key_modified(linked, b, where); __bch2_btree_iter_fix_key_modified(linked, b, where);
bch2_btree_iter_verify_level(linked, b->c.level); bch2_btree_iter_verify_level(linked, b->c.level);
} }
...@@ -863,7 +873,8 @@ static void __bch2_btree_node_iter_fix(struct btree_iter *iter, ...@@ -863,7 +873,8 @@ static void __bch2_btree_node_iter_fix(struct btree_iter *iter,
btree_iter_set_dirty(iter, BTREE_ITER_NEED_PEEK); btree_iter_set_dirty(iter, BTREE_ITER_NEED_PEEK);
} }
void bch2_btree_node_iter_fix(struct btree_iter *iter, void bch2_btree_node_iter_fix(struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b, struct btree *b,
struct btree_node_iter *node_iter, struct btree_node_iter *node_iter,
struct bkey_packed *where, struct bkey_packed *where,
...@@ -881,7 +892,7 @@ void bch2_btree_node_iter_fix(struct btree_iter *iter, ...@@ -881,7 +892,7 @@ void bch2_btree_node_iter_fix(struct btree_iter *iter,
bch2_btree_node_iter_verify(node_iter, b); bch2_btree_node_iter_verify(node_iter, b);
} }
trans_for_each_iter_with_node(iter->trans, b, linked) { trans_for_each_iter_with_node(trans, b, linked) {
__bch2_btree_node_iter_fix(linked, b, __bch2_btree_node_iter_fix(linked, b,
&linked->l[b->c.level].iter, t, &linked->l[b->c.level].iter, t,
where, clobber_u64s, new_u64s); where, clobber_u64s, new_u64s);
...@@ -1055,12 +1066,13 @@ static inline void btree_iter_node_set(struct btree_iter *iter, ...@@ -1055,12 +1066,13 @@ static inline void btree_iter_node_set(struct btree_iter *iter,
* A btree node is being replaced - update the iterator to point to the new * A btree node is being replaced - update the iterator to point to the new
* node: * node:
*/ */
void bch2_btree_iter_node_replace(struct btree_iter *iter, struct btree *b) void bch2_btree_iter_node_replace(struct btree_trans *trans,
struct btree_iter *iter, struct btree *b)
{ {
enum btree_node_locked_type t; enum btree_node_locked_type t;
struct btree_iter *linked; struct btree_iter *linked;
trans_for_each_iter(iter->trans, linked) trans_for_each_iter(trans, linked)
if (btree_iter_type(linked) != BTREE_ITER_CACHED && if (btree_iter_type(linked) != BTREE_ITER_CACHED &&
btree_iter_pos_in_node(linked, b)) { btree_iter_pos_in_node(linked, b)) {
/* /*
...@@ -1080,12 +1092,13 @@ void bch2_btree_iter_node_replace(struct btree_iter *iter, struct btree *b) ...@@ -1080,12 +1092,13 @@ void bch2_btree_iter_node_replace(struct btree_iter *iter, struct btree *b)
} }
} }
void bch2_btree_iter_node_drop(struct btree_iter *iter, struct btree *b) void bch2_btree_iter_node_drop(struct btree_trans *trans,
struct btree_iter *iter, struct btree *b)
{ {
struct btree_iter *linked; struct btree_iter *linked;
unsigned level = b->c.level; unsigned level = b->c.level;
trans_for_each_iter(iter->trans, linked) trans_for_each_iter(trans, linked)
if (linked->l[level].b == b) { if (linked->l[level].b == b) {
btree_node_unlock(linked, level); btree_node_unlock(linked, level);
linked->l[level].b = BTREE_ITER_NO_NODE_DROP; linked->l[level].b = BTREE_ITER_NO_NODE_DROP;
...@@ -1096,11 +1109,12 @@ void bch2_btree_iter_node_drop(struct btree_iter *iter, struct btree *b) ...@@ -1096,11 +1109,12 @@ void bch2_btree_iter_node_drop(struct btree_iter *iter, struct btree *b)
* A btree node has been modified in such a way as to invalidate iterators - fix * A btree node has been modified in such a way as to invalidate iterators - fix
* them: * them:
*/ */
void bch2_btree_iter_reinit_node(struct btree_iter *iter, struct btree *b) void bch2_btree_iter_reinit_node(struct btree_trans *trans,
struct btree_iter *iter, struct btree *b)
{ {
struct btree_iter *linked; struct btree_iter *linked;
trans_for_each_iter_with_node(iter->trans, b, linked) trans_for_each_iter_with_node(trans, b, linked)
__btree_iter_init(linked, b->c.level); __btree_iter_init(linked, b->c.level);
} }
...@@ -1170,9 +1184,9 @@ static inline int btree_iter_lock_root(struct btree_trans *trans, ...@@ -1170,9 +1184,9 @@ static inline int btree_iter_lock_root(struct btree_trans *trans,
} }
noinline noinline
static int btree_iter_prefetch(struct btree_iter *iter) static int btree_iter_prefetch(struct btree_trans *trans, struct btree_iter *iter)
{ {
struct bch_fs *c = iter->trans->c; struct bch_fs *c = trans->c;
struct btree_iter_level *l = &iter->l[iter->level]; struct btree_iter_level *l = &iter->l[iter->level];
struct btree_node_iter node_iter = l->iter; struct btree_node_iter node_iter = l->iter;
struct bkey_packed *k; struct bkey_packed *k;
...@@ -1258,19 +1272,20 @@ static __always_inline int btree_iter_down(struct btree_trans *trans, ...@@ -1258,19 +1272,20 @@ static __always_inline int btree_iter_down(struct btree_trans *trans,
btree_node_mem_ptr_set(iter, level + 1, b); btree_node_mem_ptr_set(iter, level + 1, b);
if (iter->flags & BTREE_ITER_PREFETCH) if (iter->flags & BTREE_ITER_PREFETCH)
ret = btree_iter_prefetch(iter); ret = btree_iter_prefetch(trans, iter);
if (btree_node_read_locked(iter, level + 1)) if (btree_node_read_locked(iter, level + 1))
btree_node_unlock(iter, level + 1); btree_node_unlock(iter, level + 1);
iter->level = level; iter->level = level;
bch2_btree_iter_verify_locks(iter); bch2_btree_iter_verify_locks(trans, iter);
err: err:
bch2_bkey_buf_exit(&tmp, c); bch2_bkey_buf_exit(&tmp, c);
return ret; return ret;
} }
static int btree_iter_traverse_one(struct btree_iter *, unsigned long); static int btree_iter_traverse_one(struct btree_trans *,
struct btree_iter *, unsigned long);
static int __btree_iter_traverse_all(struct btree_trans *trans, int ret, static int __btree_iter_traverse_all(struct btree_trans *trans, int ret,
unsigned long trace_ip) unsigned long trace_ip)
...@@ -1331,7 +1346,7 @@ static int __btree_iter_traverse_all(struct btree_trans *trans, int ret, ...@@ -1331,7 +1346,7 @@ static int __btree_iter_traverse_all(struct btree_trans *trans, int ret,
EBUG_ON(!(trans->iters_linked & (1ULL << iter->idx))); EBUG_ON(!(trans->iters_linked & (1ULL << iter->idx)));
ret = btree_iter_traverse_one(iter, _THIS_IP_); ret = btree_iter_traverse_one(trans, iter, _THIS_IP_);
if (ret) if (ret)
goto retry_all; goto retry_all;
...@@ -1400,10 +1415,10 @@ static inline unsigned btree_iter_up_until_good_node(struct btree_iter *iter, ...@@ -1400,10 +1415,10 @@ static inline unsigned btree_iter_up_until_good_node(struct btree_iter *iter,
* On error, caller (peek_node()/peek_key()) must return NULL; the error is * On error, caller (peek_node()/peek_key()) must return NULL; the error is
* stashed in the iterator and returned from bch2_trans_exit(). * stashed in the iterator and returned from bch2_trans_exit().
*/ */
static int btree_iter_traverse_one(struct btree_iter *iter, static int btree_iter_traverse_one(struct btree_trans *trans,
struct btree_iter *iter,
unsigned long trace_ip) unsigned long trace_ip)
{ {
struct btree_trans *trans = iter->trans;
unsigned l, depth_want = iter->level; unsigned l, depth_want = iter->level;
int ret = 0; int ret = 0;
...@@ -1412,7 +1427,7 @@ static int btree_iter_traverse_one(struct btree_iter *iter, ...@@ -1412,7 +1427,7 @@ static int btree_iter_traverse_one(struct btree_iter *iter,
* and re-traverse the iterator without a transaction restart: * and re-traverse the iterator without a transaction restart:
*/ */
if (iter->should_be_locked) { if (iter->should_be_locked) {
ret = bch2_btree_iter_relock(iter, trace_ip) ? 0 : -EINTR; ret = bch2_btree_iter_relock(trans, iter, trace_ip) ? 0 : -EINTR;
goto out; goto out;
} }
...@@ -1488,7 +1503,7 @@ static int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter) ...@@ -1488,7 +1503,7 @@ static int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter)
int ret; int ret;
ret = bch2_trans_cond_resched(trans) ?: ret = bch2_trans_cond_resched(trans) ?:
btree_iter_traverse_one(iter, _RET_IP_); btree_iter_traverse_one(trans, iter, _RET_IP_);
if (unlikely(ret) && hweight64(trans->iters_linked) == 1) { if (unlikely(ret) && hweight64(trans->iters_linked) == 1) {
ret = __btree_iter_traverse_all(trans, ret, _RET_IP_); ret = __btree_iter_traverse_all(trans, ret, _RET_IP_);
BUG_ON(ret == -EINTR); BUG_ON(ret == -EINTR);
...@@ -1619,20 +1634,21 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter) ...@@ -1619,20 +1634,21 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_pos) static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_pos)
{ {
struct btree_trans *trans = iter->trans;
#ifdef CONFIG_BCACHEFS_DEBUG #ifdef CONFIG_BCACHEFS_DEBUG
struct bpos old_pos = iter->real_pos; struct bpos old_pos = iter->real_pos;
#endif #endif
int cmp = bpos_cmp(new_pos, iter->real_pos); int cmp = bpos_cmp(new_pos, iter->real_pos);
unsigned l = iter->level; unsigned l = iter->level;
EBUG_ON(iter->trans->restarted); EBUG_ON(trans->restarted);
if (!cmp) if (!cmp)
goto out; goto out;
iter->real_pos = new_pos; iter->real_pos = new_pos;
iter->should_be_locked = false; iter->should_be_locked = false;
iter->trans->iters_sorted = false; trans->iters_sorted = false;
if (unlikely(btree_iter_type(iter) == BTREE_ITER_CACHED)) { if (unlikely(btree_iter_type(iter) == BTREE_ITER_CACHED)) {
btree_node_unlock(iter, 0); btree_node_unlock(iter, 0);
...@@ -1666,7 +1682,7 @@ static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_p ...@@ -1666,7 +1682,7 @@ static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_p
bch2_btree_iter_verify(iter); bch2_btree_iter_verify(iter);
#ifdef CONFIG_BCACHEFS_DEBUG #ifdef CONFIG_BCACHEFS_DEBUG
trace_iter_set_search_pos(iter->trans->ip, _RET_IP_, trace_iter_set_search_pos(trans->ip, _RET_IP_,
iter->btree_id, iter->btree_id,
&old_pos, &new_pos, l); &old_pos, &new_pos, l);
#endif #endif
...@@ -1886,6 +1902,7 @@ struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *iter) ...@@ -1886,6 +1902,7 @@ struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *iter)
struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
{ {
struct btree_trans *trans = iter->trans;
struct bpos search_key; struct bpos search_key;
struct bkey_s_c k; struct bkey_s_c k;
int ret; int ret;
...@@ -1954,9 +1971,9 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) ...@@ -1954,9 +1971,9 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
if (iter->flags & BTREE_ITER_INTENT) { if (iter->flags & BTREE_ITER_INTENT) {
struct btree_iter *child = struct btree_iter *child =
btree_iter_child_alloc(iter, _THIS_IP_); btree_iter_child_alloc(trans, iter, _THIS_IP_);
btree_iter_copy(child, iter); btree_iter_copy(trans, child, iter);
k = bch2_btree_iter_peek(child); k = bch2_btree_iter_peek(child);
if (k.k && !bkey_err(k)) if (k.k && !bkey_err(k))
...@@ -2163,21 +2180,21 @@ static inline void btree_iter_list_add(struct btree_trans *trans, ...@@ -2163,21 +2180,21 @@ static inline void btree_iter_list_add(struct btree_trans *trans,
btree_trans_verify_sorted_refs(trans); btree_trans_verify_sorted_refs(trans);
} }
static void btree_iter_child_free(struct btree_iter *iter) static void btree_iter_child_free(struct btree_trans *trans, struct btree_iter *iter)
{ {
struct btree_iter *child = btree_iter_child(iter); struct btree_iter *child = btree_iter_child(trans, iter);
if (child) { if (child) {
bch2_trans_iter_free(iter->trans, child); bch2_trans_iter_free(trans, child);
iter->child_idx = U8_MAX; iter->child_idx = U8_MAX;
} }
} }
static struct btree_iter *btree_iter_child_alloc(struct btree_iter *iter, static struct btree_iter *btree_iter_child_alloc(struct btree_trans *trans,
struct btree_iter *iter,
unsigned long ip) unsigned long ip)
{ {
struct btree_trans *trans = iter->trans; struct btree_iter *child = btree_iter_child(trans, iter);
struct btree_iter *child = btree_iter_child(iter);
if (!child) { if (!child) {
child = btree_trans_iter_alloc(trans, iter); child = btree_trans_iter_alloc(trans, iter);
...@@ -2194,7 +2211,7 @@ static struct btree_iter *btree_iter_child_alloc(struct btree_iter *iter, ...@@ -2194,7 +2211,7 @@ static struct btree_iter *btree_iter_child_alloc(struct btree_iter *iter,
static inline void __bch2_trans_iter_free(struct btree_trans *trans, static inline void __bch2_trans_iter_free(struct btree_trans *trans,
unsigned idx) unsigned idx)
{ {
btree_iter_child_free(&trans->iters[idx]); btree_iter_child_free(trans, &trans->iters[idx]);
btree_iter_list_remove(trans, &trans->iters[idx]); btree_iter_list_remove(trans, &trans->iters[idx]);
...@@ -2312,12 +2329,13 @@ static struct btree_iter *btree_trans_iter_alloc(struct btree_trans *trans, ...@@ -2312,12 +2329,13 @@ static struct btree_iter *btree_trans_iter_alloc(struct btree_trans *trans,
return iter; return iter;
} }
static void btree_iter_copy(struct btree_iter *dst, struct btree_iter *src) static void btree_iter_copy(struct btree_trans *trans, struct btree_iter *dst,
struct btree_iter *src)
{ {
unsigned i, offset = offsetof(struct btree_iter, flags); unsigned i, offset = offsetof(struct btree_iter, flags);
__bch2_btree_iter_unlock(dst); __bch2_btree_iter_unlock(dst);
btree_iter_child_free(dst); btree_iter_child_free(trans, dst);
memcpy((void *) dst + offset, memcpy((void *) dst + offset,
(void *) src + offset, (void *) src + offset,
...@@ -2330,7 +2348,7 @@ static void btree_iter_copy(struct btree_iter *dst, struct btree_iter *src) ...@@ -2330,7 +2348,7 @@ static void btree_iter_copy(struct btree_iter *dst, struct btree_iter *src)
dst->flags &= ~BTREE_ITER_KEEP_UNTIL_COMMIT; dst->flags &= ~BTREE_ITER_KEEP_UNTIL_COMMIT;
dst->flags &= ~BTREE_ITER_SET_POS_AFTER_COMMIT; dst->flags &= ~BTREE_ITER_SET_POS_AFTER_COMMIT;
dst->trans->iters_sorted = false; trans->iters_sorted = false;
} }
struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans,
...@@ -2388,7 +2406,7 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, ...@@ -2388,7 +2406,7 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans,
bch2_btree_iter_init(trans, iter, btree_id); bch2_btree_iter_init(trans, iter, btree_id);
} else if (btree_iter_keep(trans, best)) { } else if (btree_iter_keep(trans, best)) {
iter = btree_trans_iter_alloc(trans, best); iter = btree_trans_iter_alloc(trans, best);
btree_iter_copy(iter, best); btree_iter_copy(trans, iter, best);
} else { } else {
iter = best; iter = best;
} }
...@@ -2411,7 +2429,7 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans, ...@@ -2411,7 +2429,7 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans,
locks_want = min(locks_want, BTREE_MAX_DEPTH); locks_want = min(locks_want, BTREE_MAX_DEPTH);
if (locks_want > iter->locks_want) { if (locks_want > iter->locks_want) {
iter->locks_want = locks_want; iter->locks_want = locks_want;
btree_iter_get_locks(iter, true, _THIS_IP_); btree_iter_get_locks(trans, iter, true, _THIS_IP_);
} }
while (iter->level != depth) { while (iter->level != depth) {
...@@ -2464,12 +2482,12 @@ struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *trans, ...@@ -2464,12 +2482,12 @@ struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *trans,
} }
struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *trans,
struct btree_iter *src) struct btree_iter *src)
{ {
struct btree_iter *iter; struct btree_iter *iter;
iter = btree_trans_iter_alloc(trans, src); iter = btree_trans_iter_alloc(trans, src);
btree_iter_copy(iter, src); btree_iter_copy(trans, iter, src);
trans->iters_live |= 1ULL << iter->idx; trans->iters_live |= 1ULL << iter->idx;
/* /*
...@@ -2647,7 +2665,7 @@ int bch2_trans_exit(struct btree_trans *trans) ...@@ -2647,7 +2665,7 @@ int bch2_trans_exit(struct btree_trans *trans)
struct btree_iter *iter; struct btree_iter *iter;
trans_for_each_iter(trans, iter) trans_for_each_iter(trans, iter)
btree_iter_child_free(iter); btree_iter_child_free(trans, iter);
} }
if (trans->iters_live) { if (trans->iters_live) {
......
...@@ -135,14 +135,13 @@ static inline void bch2_btree_trans_verify_iters(struct btree_trans *trans, ...@@ -135,14 +135,13 @@ static inline void bch2_btree_trans_verify_iters(struct btree_trans *trans,
static inline void bch2_btree_trans_verify_locks(struct btree_trans *iter) {} static inline void bch2_btree_trans_verify_locks(struct btree_trans *iter) {}
#endif #endif
void bch2_btree_iter_fix_key_modified(struct btree_iter *, struct btree *, void bch2_btree_iter_fix_key_modified(struct btree_trans *trans, struct btree_iter *,
struct bkey_packed *); struct btree *, struct bkey_packed *);
void bch2_btree_node_iter_fix(struct btree_iter *, struct btree *, void bch2_btree_node_iter_fix(struct btree_trans *trans, struct btree_iter *,
struct btree_node_iter *, struct bkey_packed *, struct btree *, struct btree_node_iter *,
unsigned, unsigned); struct bkey_packed *, unsigned, unsigned);
bool bch2_btree_iter_relock_intent(struct btree_iter *); bool bch2_btree_iter_relock_intent(struct btree_iter *);
bool bch2_btree_iter_relock(struct btree_iter *, unsigned long);
bool bch2_trans_relock(struct btree_trans *); bool bch2_trans_relock(struct btree_trans *);
void bch2_trans_unlock(struct btree_trans *); void bch2_trans_unlock(struct btree_trans *);
...@@ -179,10 +178,13 @@ static inline void bch2_btree_iter_downgrade(struct btree_iter *iter) ...@@ -179,10 +178,13 @@ static inline void bch2_btree_iter_downgrade(struct btree_iter *iter)
void bch2_trans_downgrade(struct btree_trans *); void bch2_trans_downgrade(struct btree_trans *);
void bch2_btree_iter_node_replace(struct btree_iter *, struct btree *); void bch2_btree_iter_node_replace(struct btree_trans *trans,
void bch2_btree_iter_node_drop(struct btree_iter *, struct btree *); struct btree_iter *, struct btree *);
void bch2_btree_iter_node_drop(struct btree_trans *,
struct btree_iter *, struct btree *);
void bch2_btree_iter_reinit_node(struct btree_iter *, struct btree *); void bch2_btree_iter_reinit_node(struct btree_trans *,
struct btree_iter *, struct btree *);
int __must_check bch2_btree_iter_traverse(struct btree_iter *); int __must_check bch2_btree_iter_traverse(struct btree_iter *);
...@@ -226,9 +228,10 @@ static inline struct btree_iter *idx_to_btree_iter(struct btree_trans *trans, un ...@@ -226,9 +228,10 @@ static inline struct btree_iter *idx_to_btree_iter(struct btree_trans *trans, un
return idx != U8_MAX ? trans->iters + idx : NULL; return idx != U8_MAX ? trans->iters + idx : NULL;
} }
static inline struct btree_iter *btree_iter_child(struct btree_iter *iter) static inline struct btree_iter *btree_iter_child(struct btree_trans *trans,
struct btree_iter *iter)
{ {
return idx_to_btree_iter(iter->trans, iter->child_idx); return idx_to_btree_iter(trans, iter->child_idx);
} }
/* /*
...@@ -319,7 +322,7 @@ bch2_trans_get_iter(struct btree_trans *trans, enum btree_id btree_id, ...@@ -319,7 +322,7 @@ bch2_trans_get_iter(struct btree_trans *trans, enum btree_id btree_id,
} }
struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *, struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *,
struct btree_iter *); struct btree_iter *);
static inline struct btree_iter * static inline struct btree_iter *
bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *src) bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *src)
{ {
......
...@@ -238,7 +238,7 @@ static int btree_key_cache_fill(struct btree_trans *trans, ...@@ -238,7 +238,7 @@ static int btree_key_cache_fill(struct btree_trans *trans,
* XXX: not allowed to be holding read locks when we take a write lock, * XXX: not allowed to be holding read locks when we take a write lock,
* currently * currently
*/ */
bch2_btree_node_lock_write(ck_iter->l[0].b, ck_iter); bch2_btree_node_lock_write(trans, ck_iter, ck_iter->l[0].b);
if (new_k) { if (new_k) {
kfree(ck->k); kfree(ck->k);
ck->u64s = new_u64s; ck->u64s = new_u64s;
...@@ -247,7 +247,7 @@ static int btree_key_cache_fill(struct btree_trans *trans, ...@@ -247,7 +247,7 @@ static int btree_key_cache_fill(struct btree_trans *trans,
bkey_reassemble(ck->k, k); bkey_reassemble(ck->k, k);
ck->valid = true; ck->valid = true;
bch2_btree_node_unlock_write(ck_iter->l[0].b, ck_iter); bch2_btree_node_unlock_write(trans, ck_iter, ck_iter->l[0].b);
/* We're not likely to need this iterator again: */ /* We're not likely to need this iterator again: */
set_btree_iter_dontneed(trans, iter); set_btree_iter_dontneed(trans, iter);
......
...@@ -207,30 +207,35 @@ static inline bool bch2_btree_node_relock(struct btree_iter *iter, ...@@ -207,30 +207,35 @@ static inline bool bch2_btree_node_relock(struct btree_iter *iter,
* succeed: * succeed:
*/ */
static inline void static inline void
bch2_btree_node_unlock_write_inlined(struct btree *b, struct btree_iter *iter) bch2_btree_node_unlock_write_inlined(struct btree_trans *trans, struct btree_iter *iter,
struct btree *b)
{ {
struct btree_iter *linked; struct btree_iter *linked;
EBUG_ON(iter->l[b->c.level].b != b); EBUG_ON(iter->l[b->c.level].b != b);
EBUG_ON(iter->l[b->c.level].lock_seq + 1 != b->c.lock.state.seq); EBUG_ON(iter->l[b->c.level].lock_seq + 1 != b->c.lock.state.seq);
trans_for_each_iter_with_node(iter->trans, b, linked) trans_for_each_iter_with_node(trans, b, linked)
linked->l[b->c.level].lock_seq += 2; linked->l[b->c.level].lock_seq += 2;
six_unlock_write(&b->c.lock); six_unlock_write(&b->c.lock);
} }
void bch2_btree_node_unlock_write(struct btree *, struct btree_iter *); void bch2_btree_node_unlock_write(struct btree_trans *,
struct btree_iter *, struct btree *);
void __bch2_btree_node_lock_write(struct btree *, struct btree_iter *); void __bch2_btree_node_lock_write(struct btree_trans *,
struct btree_iter *, struct btree *);
static inline void bch2_btree_node_lock_write(struct btree *b, struct btree_iter *iter) static inline void bch2_btree_node_lock_write(struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b)
{ {
EBUG_ON(iter->l[b->c.level].b != b); EBUG_ON(iter->l[b->c.level].b != b);
EBUG_ON(iter->l[b->c.level].lock_seq != b->c.lock.state.seq); EBUG_ON(iter->l[b->c.level].lock_seq != b->c.lock.state.seq);
if (unlikely(!six_trylock_write(&b->c.lock))) if (unlikely(!six_trylock_write(&b->c.lock)))
__bch2_btree_node_lock_write(b, iter); __bch2_btree_node_lock_write(trans, iter, b);
} }
#endif /* _BCACHEFS_BTREE_LOCKING_H */ #endif /* _BCACHEFS_BTREE_LOCKING_H */
......
...@@ -10,8 +10,9 @@ struct btree; ...@@ -10,8 +10,9 @@ struct btree;
void bch2_btree_node_lock_for_insert(struct btree_trans *, struct btree_iter *, void bch2_btree_node_lock_for_insert(struct btree_trans *, struct btree_iter *,
struct btree *); struct btree *);
bool bch2_btree_bset_insert_key(struct btree_iter *, struct btree *, bool bch2_btree_bset_insert_key(struct btree_trans *, struct btree_iter *,
struct btree_node_iter *, struct bkey_i *); struct btree *, struct btree_node_iter *,
struct bkey_i *);
void bch2_btree_add_journal_pin(struct bch_fs *, struct btree *, u64); void bch2_btree_add_journal_pin(struct bch_fs *, struct btree *, u64);
enum btree_insert_flags { enum btree_insert_flags {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
static void bch2_btree_insert_node(struct btree_update *, struct btree_trans *, static void bch2_btree_insert_node(struct btree_update *, struct btree_trans *,
struct btree_iter *, struct btree *, struct btree_iter *, struct btree *,
struct keylist *, unsigned); struct keylist *, unsigned);
static void bch2_btree_update_add_new_node(struct btree_update *, struct btree *);
/* Debug code: */ /* Debug code: */
...@@ -159,27 +160,14 @@ static void __btree_node_free(struct bch_fs *c, struct btree *b) ...@@ -159,27 +160,14 @@ static void __btree_node_free(struct bch_fs *c, struct btree *b)
mutex_unlock(&c->btree_cache.lock); mutex_unlock(&c->btree_cache.lock);
} }
void bch2_btree_node_free_never_inserted(struct bch_fs *c, struct btree *b) static void bch2_btree_node_free_inmem(struct btree_trans *trans,
{ struct btree_iter *iter,
struct open_buckets ob = b->ob; struct btree *b)
b->ob.nr = 0;
clear_btree_node_dirty(c, b);
btree_node_lock_type(c, b, SIX_LOCK_write);
__btree_node_free(c, b);
six_unlock_write(&b->c.lock);
bch2_open_buckets_put(c, &ob);
}
void bch2_btree_node_free_inmem(struct bch_fs *c, struct btree *b,
struct btree_iter *iter)
{ {
struct bch_fs *c = trans->c;
struct btree_iter *linked; struct btree_iter *linked;
trans_for_each_iter(iter->trans, linked) trans_for_each_iter(trans, linked)
BUG_ON(linked->l[b->c.level].b == b); BUG_ON(linked->l[b->c.level].b == b);
six_lock_write(&b->c.lock, NULL, NULL); six_lock_write(&b->c.lock, NULL, NULL);
...@@ -773,7 +761,7 @@ static void btree_update_updated_root(struct btree_update *as, struct btree *b) ...@@ -773,7 +761,7 @@ static void btree_update_updated_root(struct btree_update *as, struct btree *b)
* And it adds @b to the list of @as's new nodes, so that we can update sector * And it adds @b to the list of @as's new nodes, so that we can update sector
* counts in bch2_btree_update_nodes_written: * counts in bch2_btree_update_nodes_written:
*/ */
void bch2_btree_update_add_new_node(struct btree_update *as, struct btree *b) static void bch2_btree_update_add_new_node(struct btree_update *as, struct btree *b)
{ {
struct bch_fs *c = as->c; struct bch_fs *c = as->c;
...@@ -827,7 +815,7 @@ static void btree_update_drop_new_node(struct bch_fs *c, struct btree *b) ...@@ -827,7 +815,7 @@ static void btree_update_drop_new_node(struct bch_fs *c, struct btree *b)
closure_put(&as->cl); closure_put(&as->cl);
} }
void bch2_btree_update_get_open_buckets(struct btree_update *as, struct btree *b) static void bch2_btree_update_get_open_buckets(struct btree_update *as, struct btree *b)
{ {
while (b->ob.nr) while (b->ob.nr)
as->open_buckets[as->nr_open_buckets++] = as->open_buckets[as->nr_open_buckets++] =
...@@ -839,7 +827,7 @@ void bch2_btree_update_get_open_buckets(struct btree_update *as, struct btree *b ...@@ -839,7 +827,7 @@ void bch2_btree_update_get_open_buckets(struct btree_update *as, struct btree *b
* nodes and thus outstanding btree_updates - redirect @b's * nodes and thus outstanding btree_updates - redirect @b's
* btree_updates to point to this btree_update: * btree_updates to point to this btree_update:
*/ */
void bch2_btree_interior_update_will_free_node(struct btree_update *as, static void bch2_btree_interior_update_will_free_node(struct btree_update *as,
struct btree *b) struct btree *b)
{ {
struct bch_fs *c = as->c; struct bch_fs *c = as->c;
...@@ -911,7 +899,7 @@ void bch2_btree_interior_update_will_free_node(struct btree_update *as, ...@@ -911,7 +899,7 @@ void bch2_btree_interior_update_will_free_node(struct btree_update *as,
as->nr_old_nodes++; as->nr_old_nodes++;
} }
void bch2_btree_update_done(struct btree_update *as) static void bch2_btree_update_done(struct btree_update *as)
{ {
BUG_ON(as->mode == BTREE_INTERIOR_NO_UPDATE); BUG_ON(as->mode == BTREE_INTERIOR_NO_UPDATE);
...@@ -925,11 +913,10 @@ void bch2_btree_update_done(struct btree_update *as) ...@@ -925,11 +913,10 @@ void bch2_btree_update_done(struct btree_update *as)
as->c->btree_interior_update_worker); as->c->btree_interior_update_worker);
} }
struct btree_update * static struct btree_update *
bch2_btree_update_start(struct btree_iter *iter, unsigned level, bch2_btree_update_start(struct btree_trans *trans, struct btree_iter *iter,
unsigned nr_nodes, unsigned flags) unsigned level, unsigned nr_nodes, unsigned flags)
{ {
struct btree_trans *trans = iter->trans;
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct btree_update *as; struct btree_update *as;
struct closure cl; struct closure cl;
...@@ -1092,8 +1079,10 @@ static void bch2_btree_set_root_inmem(struct bch_fs *c, struct btree *b) ...@@ -1092,8 +1079,10 @@ static void bch2_btree_set_root_inmem(struct bch_fs *c, struct btree *b)
* is nothing new to be done. This just guarantees that there is a * is nothing new to be done. This just guarantees that there is a
* journal write. * journal write.
*/ */
static void bch2_btree_set_root(struct btree_update *as, struct btree *b, static void bch2_btree_set_root(struct btree_update *as,
struct btree_iter *iter) struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b)
{ {
struct bch_fs *c = as->c; struct bch_fs *c = as->c;
struct btree *old; struct btree *old;
...@@ -1108,7 +1097,7 @@ static void bch2_btree_set_root(struct btree_update *as, struct btree *b, ...@@ -1108,7 +1097,7 @@ static void bch2_btree_set_root(struct btree_update *as, struct btree *b,
* Ensure no one is using the old root while we switch to the * Ensure no one is using the old root while we switch to the
* new root: * new root:
*/ */
bch2_btree_node_lock_write(old, iter); bch2_btree_node_lock_write(trans, iter, old);
bch2_btree_set_root_inmem(c, b); bch2_btree_set_root_inmem(c, b);
...@@ -1121,15 +1110,17 @@ static void bch2_btree_set_root(struct btree_update *as, struct btree *b, ...@@ -1121,15 +1110,17 @@ static void bch2_btree_set_root(struct btree_update *as, struct btree *b,
* an intent lock on the new root, and any updates that would * an intent lock on the new root, and any updates that would
* depend on the new root would have to update the new root. * depend on the new root would have to update the new root.
*/ */
bch2_btree_node_unlock_write(old, iter); bch2_btree_node_unlock_write(trans, iter, old);
} }
/* Interior node updates: */ /* Interior node updates: */
static void bch2_insert_fixup_btree_ptr(struct btree_update *as, struct btree *b, static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
struct btree_trans *trans,
struct btree_iter *iter, struct btree_iter *iter,
struct bkey_i *insert, struct btree *b,
struct btree_node_iter *node_iter) struct btree_node_iter *node_iter,
struct bkey_i *insert)
{ {
struct bch_fs *c = as->c; struct bch_fs *c = as->c;
struct bkey_packed *k; struct bkey_packed *k;
...@@ -1161,15 +1152,18 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as, struct btree *b ...@@ -1161,15 +1152,18 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as, struct btree *b
bkey_iter_pos_cmp(b, k, &insert->k.p) < 0) bkey_iter_pos_cmp(b, k, &insert->k.p) < 0)
bch2_btree_node_iter_advance(node_iter, b); bch2_btree_node_iter_advance(node_iter, b);
bch2_btree_bset_insert_key(iter, b, node_iter, insert); bch2_btree_bset_insert_key(trans, iter, b, node_iter, insert);
set_btree_node_dirty(c, b); set_btree_node_dirty(c, b);
set_btree_node_need_write(b); set_btree_node_need_write(b);
} }
static void static void
__bch2_btree_insert_keys_interior(struct btree_update *as, struct btree *b, __bch2_btree_insert_keys_interior(struct btree_update *as,
struct btree_iter *iter, struct keylist *keys, struct btree_trans *trans,
struct btree_node_iter node_iter) struct btree_iter *iter,
struct btree *b,
struct btree_node_iter node_iter,
struct keylist *keys)
{ {
struct bkey_i *insert = bch2_keylist_front(keys); struct bkey_i *insert = bch2_keylist_front(keys);
struct bkey_packed *k; struct bkey_packed *k;
...@@ -1181,8 +1175,8 @@ __bch2_btree_insert_keys_interior(struct btree_update *as, struct btree *b, ...@@ -1181,8 +1175,8 @@ __bch2_btree_insert_keys_interior(struct btree_update *as, struct btree *b,
; ;
while (!bch2_keylist_empty(keys)) { while (!bch2_keylist_empty(keys)) {
bch2_insert_fixup_btree_ptr(as, b, iter, bch2_insert_fixup_btree_ptr(as, trans, iter, b,
bch2_keylist_front(keys), &node_iter); &node_iter, bch2_keylist_front(keys));
bch2_keylist_pop_front(keys); bch2_keylist_pop_front(keys);
} }
} }
...@@ -1308,8 +1302,10 @@ static struct btree *__btree_split_node(struct btree_update *as, ...@@ -1308,8 +1302,10 @@ static struct btree *__btree_split_node(struct btree_update *as,
* nodes that were coalesced, and thus in the middle of a child node post * nodes that were coalesced, and thus in the middle of a child node post
* coalescing: * coalescing:
*/ */
static void btree_split_insert_keys(struct btree_update *as, struct btree *b, static void btree_split_insert_keys(struct btree_update *as,
struct btree_trans *trans,
struct btree_iter *iter, struct btree_iter *iter,
struct btree *b,
struct keylist *keys) struct keylist *keys)
{ {
struct btree_node_iter node_iter; struct btree_node_iter node_iter;
...@@ -1319,7 +1315,7 @@ static void btree_split_insert_keys(struct btree_update *as, struct btree *b, ...@@ -1319,7 +1315,7 @@ static void btree_split_insert_keys(struct btree_update *as, struct btree *b,
bch2_btree_node_iter_init(&node_iter, b, &k->k.p); bch2_btree_node_iter_init(&node_iter, b, &k->k.p);
__bch2_btree_insert_keys_interior(as, b, iter, keys, node_iter); __bch2_btree_insert_keys_interior(as, trans, iter, b, node_iter, keys);
/* /*
* We can't tolerate whiteouts here - with whiteouts there can be * We can't tolerate whiteouts here - with whiteouts there can be
...@@ -1368,7 +1364,7 @@ static void btree_split(struct btree_update *as, ...@@ -1368,7 +1364,7 @@ static void btree_split(struct btree_update *as,
bch2_btree_update_add_new_node(as, n1); bch2_btree_update_add_new_node(as, n1);
if (keys) if (keys)
btree_split_insert_keys(as, n1, iter, keys); btree_split_insert_keys(as, trans, iter, n1, keys);
if (bset_u64s(&n1->set[0]) > BTREE_SPLIT_THRESHOLD(c)) { if (bset_u64s(&n1->set[0]) > BTREE_SPLIT_THRESHOLD(c)) {
trace_btree_split(c, b); trace_btree_split(c, b);
...@@ -1398,7 +1394,7 @@ static void btree_split(struct btree_update *as, ...@@ -1398,7 +1394,7 @@ static void btree_split(struct btree_update *as,
n3->sib_u64s[0] = U16_MAX; n3->sib_u64s[0] = U16_MAX;
n3->sib_u64s[1] = U16_MAX; n3->sib_u64s[1] = U16_MAX;
btree_split_insert_keys(as, n3, iter, &as->parent_keys); btree_split_insert_keys(as, trans, iter, n3, &as->parent_keys);
bch2_btree_node_write(c, n3, SIX_LOCK_intent); bch2_btree_node_write(c, n3, SIX_LOCK_intent);
} }
...@@ -1420,10 +1416,10 @@ static void btree_split(struct btree_update *as, ...@@ -1420,10 +1416,10 @@ static void btree_split(struct btree_update *as,
/* Split a non root node */ /* Split a non root node */
bch2_btree_insert_node(as, trans, iter, parent, &as->parent_keys, flags); bch2_btree_insert_node(as, trans, iter, parent, &as->parent_keys, flags);
} else if (n3) { } else if (n3) {
bch2_btree_set_root(as, n3, iter); bch2_btree_set_root(as, trans, iter, n3);
} else { } else {
/* Root filled up but didn't need to be split */ /* Root filled up but didn't need to be split */
bch2_btree_set_root(as, n1, iter); bch2_btree_set_root(as, trans, iter, n1);
} }
bch2_btree_update_get_open_buckets(as, n1); bch2_btree_update_get_open_buckets(as, n1);
...@@ -1435,12 +1431,12 @@ static void btree_split(struct btree_update *as, ...@@ -1435,12 +1431,12 @@ static void btree_split(struct btree_update *as,
/* Successful split, update the iterator to point to the new nodes: */ /* Successful split, update the iterator to point to the new nodes: */
six_lock_increment(&b->c.lock, SIX_LOCK_intent); six_lock_increment(&b->c.lock, SIX_LOCK_intent);
bch2_btree_iter_node_drop(iter, b); bch2_btree_iter_node_drop(trans, iter, b);
if (n3) if (n3)
bch2_btree_iter_node_replace(iter, n3); bch2_btree_iter_node_replace(trans, iter, n3);
if (n2) if (n2)
bch2_btree_iter_node_replace(iter, n2); bch2_btree_iter_node_replace(trans, iter, n2);
bch2_btree_iter_node_replace(iter, n1); bch2_btree_iter_node_replace(trans, iter, n1);
/* /*
* The old node must be freed (in memory) _before_ unlocking the new * The old node must be freed (in memory) _before_ unlocking the new
...@@ -1448,7 +1444,7 @@ static void btree_split(struct btree_update *as, ...@@ -1448,7 +1444,7 @@ static void btree_split(struct btree_update *as,
* node after another thread has locked and updated the new node, thus * node after another thread has locked and updated the new node, thus
* seeing stale data: * seeing stale data:
*/ */
bch2_btree_node_free_inmem(c, b, iter); bch2_btree_node_free_inmem(trans, iter, b);
if (n3) if (n3)
six_unlock_intent(&n3->c.lock); six_unlock_intent(&n3->c.lock);
...@@ -1463,19 +1459,23 @@ static void btree_split(struct btree_update *as, ...@@ -1463,19 +1459,23 @@ static void btree_split(struct btree_update *as,
} }
static void static void
bch2_btree_insert_keys_interior(struct btree_update *as, struct btree *b, bch2_btree_insert_keys_interior(struct btree_update *as,
struct btree_iter *iter, struct keylist *keys) struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b,
struct keylist *keys)
{ {
struct btree_iter *linked; struct btree_iter *linked;
__bch2_btree_insert_keys_interior(as, b, iter, keys, iter->l[b->c.level].iter); __bch2_btree_insert_keys_interior(as, trans, iter, b,
iter->l[b->c.level].iter, keys);
btree_update_updated_node(as, b); btree_update_updated_node(as, b);
trans_for_each_iter_with_node(iter->trans, b, linked) trans_for_each_iter_with_node(trans, b, linked)
bch2_btree_node_iter_peek(&linked->l[b->c.level].iter, b); bch2_btree_node_iter_peek(&linked->l[b->c.level].iter, b);
bch2_btree_trans_verify_iters(iter->trans, b); bch2_btree_trans_verify_iters(trans, b);
} }
/** /**
...@@ -1509,13 +1509,13 @@ static void bch2_btree_insert_node(struct btree_update *as, ...@@ -1509,13 +1509,13 @@ static void bch2_btree_insert_node(struct btree_update *as,
bch2_btree_node_lock_for_insert(trans, iter, b); bch2_btree_node_lock_for_insert(trans, iter, b);
if (!bch2_btree_node_insert_fits(c, b, bch2_keylist_u64s(keys))) { if (!bch2_btree_node_insert_fits(c, b, bch2_keylist_u64s(keys))) {
bch2_btree_node_unlock_write(b, iter); bch2_btree_node_unlock_write(trans, iter, b);
goto split; goto split;
} }
btree_node_interior_verify(c, b); btree_node_interior_verify(c, b);
bch2_btree_insert_keys_interior(as, b, iter, keys); bch2_btree_insert_keys_interior(as, trans, iter, b, keys);
live_u64s_added = (int) b->nr.live_u64s - old_live_u64s; live_u64s_added = (int) b->nr.live_u64s - old_live_u64s;
u64s_added = (int) le16_to_cpu(btree_bset_last(b)->u64s) - old_u64s; u64s_added = (int) le16_to_cpu(btree_bset_last(b)->u64s) - old_u64s;
...@@ -1527,9 +1527,9 @@ static void bch2_btree_insert_node(struct btree_update *as, ...@@ -1527,9 +1527,9 @@ static void bch2_btree_insert_node(struct btree_update *as,
if (u64s_added > live_u64s_added && if (u64s_added > live_u64s_added &&
bch2_maybe_compact_whiteouts(c, b)) bch2_maybe_compact_whiteouts(c, b))
bch2_btree_iter_reinit_node(iter, b); bch2_btree_iter_reinit_node(trans, iter, b);
bch2_btree_node_unlock_write(b, iter); bch2_btree_node_unlock_write(trans, iter, b);
btree_node_interior_verify(c, b); btree_node_interior_verify(c, b);
return; return;
...@@ -1547,7 +1547,7 @@ int bch2_btree_split_leaf(struct btree_trans *trans, ...@@ -1547,7 +1547,7 @@ int bch2_btree_split_leaf(struct btree_trans *trans,
unsigned l; unsigned l;
int ret = 0; int ret = 0;
as = bch2_btree_update_start(iter, iter->level, as = bch2_btree_update_start(trans, iter, iter->level,
btree_update_reserve_required(c, b), flags); btree_update_reserve_required(c, b), flags);
if (IS_ERR(as)) if (IS_ERR(as))
return PTR_ERR(as); return PTR_ERR(as);
...@@ -1660,7 +1660,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans, ...@@ -1660,7 +1660,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
goto out; goto out;
parent = btree_node_parent(iter, b); parent = btree_node_parent(iter, b);
as = bch2_btree_update_start(iter, level, as = bch2_btree_update_start(trans, iter, level,
btree_update_reserve_required(c, parent) + 1, btree_update_reserve_required(c, parent) + 1,
flags| flags|
BTREE_INSERT_NOFAIL| BTREE_INSERT_NOFAIL|
...@@ -1702,15 +1702,15 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans, ...@@ -1702,15 +1702,15 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
six_lock_increment(&b->c.lock, SIX_LOCK_intent); six_lock_increment(&b->c.lock, SIX_LOCK_intent);
six_lock_increment(&m->c.lock, SIX_LOCK_intent); six_lock_increment(&m->c.lock, SIX_LOCK_intent);
bch2_btree_iter_node_drop(iter, b); bch2_btree_iter_node_drop(trans, iter, b);
bch2_btree_iter_node_drop(iter, m); bch2_btree_iter_node_drop(trans, iter, m);
bch2_btree_iter_node_replace(iter, n); bch2_btree_iter_node_replace(trans, iter, n);
bch2_btree_trans_verify_iters(trans, n); bch2_btree_trans_verify_iters(trans, n);
bch2_btree_node_free_inmem(c, b, iter); bch2_btree_node_free_inmem(trans, iter, b);
bch2_btree_node_free_inmem(c, m, iter); bch2_btree_node_free_inmem(trans, iter, m);
six_unlock_intent(&n->c.lock); six_unlock_intent(&n->c.lock);
...@@ -1762,7 +1762,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans, ...@@ -1762,7 +1762,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
goto out; goto out;
parent = btree_node_parent(iter, b); parent = btree_node_parent(iter, b);
as = bch2_btree_update_start(iter, b->c.level, as = bch2_btree_update_start(trans, iter, b->c.level,
(parent (parent
? btree_update_reserve_required(c, parent) ? btree_update_reserve_required(c, parent)
: 0) + 1, : 0) + 1,
...@@ -1792,15 +1792,15 @@ int bch2_btree_node_rewrite(struct btree_trans *trans, ...@@ -1792,15 +1792,15 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
bch2_btree_insert_node(as, trans, iter, parent, bch2_btree_insert_node(as, trans, iter, parent,
&as->parent_keys, flags); &as->parent_keys, flags);
} else { } else {
bch2_btree_set_root(as, n, iter); bch2_btree_set_root(as, trans, iter, n);
} }
bch2_btree_update_get_open_buckets(as, n); bch2_btree_update_get_open_buckets(as, n);
six_lock_increment(&b->c.lock, SIX_LOCK_intent); six_lock_increment(&b->c.lock, SIX_LOCK_intent);
bch2_btree_iter_node_drop(iter, b); bch2_btree_iter_node_drop(trans, iter, b);
bch2_btree_iter_node_replace(iter, n); bch2_btree_iter_node_replace(trans, iter, n);
bch2_btree_node_free_inmem(c, b, iter); bch2_btree_node_free_inmem(trans, iter, b);
six_unlock_intent(&n->c.lock); six_unlock_intent(&n->c.lock);
bch2_btree_update_done(as); bch2_btree_update_done(as);
...@@ -1931,7 +1931,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans, ...@@ -1931,7 +1931,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans,
if (ret) if (ret)
goto err; goto err;
bch2_btree_node_lock_write(b, iter); bch2_btree_node_lock_write(trans, iter, b);
if (new_hash) { if (new_hash) {
mutex_lock(&c->btree_cache.lock); mutex_lock(&c->btree_cache.lock);
...@@ -1946,7 +1946,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans, ...@@ -1946,7 +1946,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans,
bkey_copy(&b->key, new_key); bkey_copy(&b->key, new_key);
} }
bch2_btree_node_unlock_write(b, iter); bch2_btree_node_unlock_write(trans, iter, b);
out: out:
bch2_trans_iter_put(trans, iter2); bch2_trans_iter_put(trans, iter2);
return ret; return ret;
......
...@@ -113,24 +113,10 @@ struct btree_update { ...@@ -113,24 +113,10 @@ struct btree_update {
u64 inline_keys[BKEY_BTREE_PTR_U64s_MAX * 3]; u64 inline_keys[BKEY_BTREE_PTR_U64s_MAX * 3];
}; };
void bch2_btree_node_free_inmem(struct bch_fs *, struct btree *,
struct btree_iter *);
void bch2_btree_node_free_never_inserted(struct bch_fs *, struct btree *);
void bch2_btree_update_get_open_buckets(struct btree_update *, struct btree *);
struct btree *__bch2_btree_node_alloc_replacement(struct btree_update *, struct btree *__bch2_btree_node_alloc_replacement(struct btree_update *,
struct btree *, struct btree *,
struct bkey_format); struct bkey_format);
void bch2_btree_update_done(struct btree_update *);
struct btree_update *
bch2_btree_update_start(struct btree_iter *, unsigned, unsigned, unsigned);
void bch2_btree_interior_update_will_free_node(struct btree_update *,
struct btree *);
void bch2_btree_update_add_new_node(struct btree_update *, struct btree *);
int bch2_btree_split_leaf(struct btree_trans *, struct btree_iter *, unsigned); int bch2_btree_split_leaf(struct btree_trans *, struct btree_iter *, unsigned);
int __bch2_foreground_maybe_merge(struct btree_trans *, struct btree_iter *, int __bch2_foreground_maybe_merge(struct btree_trans *, struct btree_iter *,
......
...@@ -42,14 +42,14 @@ inline void bch2_btree_node_lock_for_insert(struct btree_trans *trans, ...@@ -42,14 +42,14 @@ inline void bch2_btree_node_lock_for_insert(struct btree_trans *trans,
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
bch2_btree_node_lock_write(b, iter); bch2_btree_node_lock_write(trans, iter, b);
if (btree_iter_type(iter) == BTREE_ITER_CACHED) if (btree_iter_type(iter) == BTREE_ITER_CACHED)
return; return;
if (unlikely(btree_node_just_written(b)) && if (unlikely(btree_node_just_written(b)) &&
bch2_btree_post_write_cleanup(c, b)) bch2_btree_post_write_cleanup(c, b))
bch2_btree_iter_reinit_node(iter, b); bch2_btree_iter_reinit_node(trans, iter, b);
/* /*
* If the last bset has been written, or if it's gotten too big - start * If the last bset has been written, or if it's gotten too big - start
...@@ -62,7 +62,8 @@ inline void bch2_btree_node_lock_for_insert(struct btree_trans *trans, ...@@ -62,7 +62,8 @@ inline void bch2_btree_node_lock_for_insert(struct btree_trans *trans,
/* Inserting into a given leaf node (last stage of insert): */ /* Inserting into a given leaf node (last stage of insert): */
/* Handle overwrites and do insert, for non extents: */ /* Handle overwrites and do insert, for non extents: */
bool bch2_btree_bset_insert_key(struct btree_iter *iter, bool bch2_btree_bset_insert_key(struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b, struct btree *b,
struct btree_node_iter *node_iter, struct btree_node_iter *node_iter,
struct bkey_i *insert) struct bkey_i *insert)
...@@ -76,7 +77,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter, ...@@ -76,7 +77,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
EBUG_ON(bpos_cmp(insert->k.p, b->data->min_key) < 0); EBUG_ON(bpos_cmp(insert->k.p, b->data->min_key) < 0);
EBUG_ON(bpos_cmp(insert->k.p, b->data->max_key) > 0); EBUG_ON(bpos_cmp(insert->k.p, b->data->max_key) > 0);
EBUG_ON(insert->k.u64s > EBUG_ON(insert->k.u64s >
bch_btree_keys_u64s_remaining(iter->trans->c, b)); bch_btree_keys_u64s_remaining(trans->c, b));
EBUG_ON(iter->flags & BTREE_ITER_IS_EXTENTS); EBUG_ON(iter->flags & BTREE_ITER_IS_EXTENTS);
k = bch2_btree_node_iter_peek_all(node_iter, b); k = bch2_btree_node_iter_peek_all(node_iter, b);
...@@ -96,7 +97,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter, ...@@ -96,7 +97,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
k->type = KEY_TYPE_deleted; k->type = KEY_TYPE_deleted;
if (k->needs_whiteout) if (k->needs_whiteout)
push_whiteout(iter->trans->c, b, insert->k.p); push_whiteout(trans->c, b, insert->k.p);
k->needs_whiteout = false; k->needs_whiteout = false;
if (k >= btree_bset_last(b)->start) { if (k >= btree_bset_last(b)->start) {
...@@ -104,7 +105,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter, ...@@ -104,7 +105,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
bch2_bset_delete(b, k, clobber_u64s); bch2_bset_delete(b, k, clobber_u64s);
goto fix_iter; goto fix_iter;
} else { } else {
bch2_btree_iter_fix_key_modified(iter, b, k); bch2_btree_iter_fix_key_modified(trans, iter, b, k);
} }
return true; return true;
...@@ -122,7 +123,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter, ...@@ -122,7 +123,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
clobber_u64s = k->u64s; clobber_u64s = k->u64s;
goto overwrite; goto overwrite;
} else { } else {
bch2_btree_iter_fix_key_modified(iter, b, k); bch2_btree_iter_fix_key_modified(trans, iter, b, k);
} }
} }
...@@ -132,7 +133,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter, ...@@ -132,7 +133,7 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
new_u64s = k->u64s; new_u64s = k->u64s;
fix_iter: fix_iter:
if (clobber_u64s != new_u64s) if (clobber_u64s != new_u64s)
bch2_btree_node_iter_fix(iter, b, node_iter, k, bch2_btree_node_iter_fix(trans, iter, b, node_iter, k,
clobber_u64s, new_u64s); clobber_u64s, new_u64s);
return true; return true;
} }
...@@ -190,7 +191,7 @@ static bool btree_insert_key_leaf(struct btree_trans *trans, ...@@ -190,7 +191,7 @@ static bool btree_insert_key_leaf(struct btree_trans *trans,
EBUG_ON(!iter->level && EBUG_ON(!iter->level &&
!test_bit(BCH_FS_BTREE_INTERIOR_REPLAY_DONE, &c->flags)); !test_bit(BCH_FS_BTREE_INTERIOR_REPLAY_DONE, &c->flags));
if (unlikely(!bch2_btree_bset_insert_key(iter, b, if (unlikely(!bch2_btree_bset_insert_key(trans, iter, b,
&iter_l(iter)->iter, insert))) &iter_l(iter)->iter, insert)))
return false; return false;
...@@ -212,7 +213,7 @@ static bool btree_insert_key_leaf(struct btree_trans *trans, ...@@ -212,7 +213,7 @@ static bool btree_insert_key_leaf(struct btree_trans *trans,
if (u64s_added > live_u64s_added && if (u64s_added > live_u64s_added &&
bch2_maybe_compact_whiteouts(c, b)) bch2_maybe_compact_whiteouts(c, b))
bch2_btree_iter_reinit_node(iter, b); bch2_btree_iter_reinit_node(trans, iter, b);
trace_btree_insert_key(c, b, insert); trace_btree_insert_key(c, b, insert);
return true; return true;
...@@ -610,8 +611,8 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans, ...@@ -610,8 +611,8 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
trans_for_each_update(trans, i) trans_for_each_update(trans, i)
if (!same_leaf_as_prev(trans, i)) if (!same_leaf_as_prev(trans, i))
bch2_btree_node_unlock_write_inlined(iter_l(i->iter)->b, bch2_btree_node_unlock_write_inlined(trans, i->iter,
i->iter); iter_l(i->iter)->b);
if (!ret && trans->journal_pin) if (!ret && trans->journal_pin)
bch2_journal_pin_add(&c->journal, trans->journal_res.seq, bch2_journal_pin_add(&c->journal, trans->journal_res.seq,
...@@ -1178,7 +1179,7 @@ int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id, ...@@ -1178,7 +1179,7 @@ int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id,
bch2_key_resize(&delete.k, max_sectors); bch2_key_resize(&delete.k, max_sectors);
bch2_cut_back(end, &delete); bch2_cut_back(end, &delete);
ret = bch2_extent_trim_atomic(&delete, iter); ret = bch2_extent_trim_atomic(trans, iter, &delete);
if (ret) if (ret)
break; break;
} }
......
...@@ -552,19 +552,19 @@ static int __ec_stripe_mem_alloc(struct bch_fs *c, size_t idx, gfp_t gfp) ...@@ -552,19 +552,19 @@ static int __ec_stripe_mem_alloc(struct bch_fs *c, size_t idx, gfp_t gfp)
return 0; return 0;
} }
static int ec_stripe_mem_alloc(struct bch_fs *c, static int ec_stripe_mem_alloc(struct btree_trans *trans,
struct btree_iter *iter) struct btree_iter *iter)
{ {
size_t idx = iter->pos.offset; size_t idx = iter->pos.offset;
int ret = 0; int ret = 0;
if (!__ec_stripe_mem_alloc(c, idx, GFP_NOWAIT|__GFP_NOWARN)) if (!__ec_stripe_mem_alloc(trans->c, idx, GFP_NOWAIT|__GFP_NOWARN))
return ret; return ret;
bch2_trans_unlock(iter->trans); bch2_trans_unlock(trans);
ret = -EINTR; ret = -EINTR;
if (!__ec_stripe_mem_alloc(c, idx, GFP_KERNEL)) if (!__ec_stripe_mem_alloc(trans->c, idx, GFP_KERNEL))
return ret; return ret;
return -ENOMEM; return -ENOMEM;
...@@ -735,7 +735,7 @@ static int ec_stripe_bkey_insert(struct bch_fs *c, ...@@ -735,7 +735,7 @@ static int ec_stripe_bkey_insert(struct bch_fs *c,
found_slot: found_slot:
start_pos = iter->pos; start_pos = iter->pos;
ret = ec_stripe_mem_alloc(c, iter); ret = ec_stripe_mem_alloc(&trans, iter);
if (ret) if (ret)
goto err; goto err;
......
...@@ -94,11 +94,11 @@ static int count_iters_for_insert(struct btree_trans *trans, ...@@ -94,11 +94,11 @@ static int count_iters_for_insert(struct btree_trans *trans,
#define EXTENT_ITERS_MAX (BTREE_ITER_MAX / 3) #define EXTENT_ITERS_MAX (BTREE_ITER_MAX / 3)
int bch2_extent_atomic_end(struct btree_iter *iter, int bch2_extent_atomic_end(struct btree_trans *trans,
struct btree_iter *iter,
struct bkey_i *insert, struct bkey_i *insert,
struct bpos *end) struct bpos *end)
{ {
struct btree_trans *trans = iter->trans;
struct btree_iter *copy; struct btree_iter *copy;
struct bkey_s_c k; struct bkey_s_c k;
unsigned nr_iters = 0; unsigned nr_iters = 0;
...@@ -153,27 +153,17 @@ int bch2_extent_atomic_end(struct btree_iter *iter, ...@@ -153,27 +153,17 @@ int bch2_extent_atomic_end(struct btree_iter *iter,
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
int bch2_extent_trim_atomic(struct bkey_i *k, struct btree_iter *iter) int bch2_extent_trim_atomic(struct btree_trans *trans,
struct btree_iter *iter,
struct bkey_i *k)
{ {
struct bpos end; struct bpos end;
int ret; int ret;
ret = bch2_extent_atomic_end(iter, k, &end); ret = bch2_extent_atomic_end(trans, iter, k, &end);
if (ret) if (ret)
return ret; return ret;
bch2_cut_back(end, k); bch2_cut_back(end, k);
return 0; return 0;
} }
int bch2_extent_is_atomic(struct bkey_i *k, struct btree_iter *iter)
{
struct bpos end;
int ret;
ret = bch2_extent_atomic_end(iter, k, &end);
if (ret)
return ret;
return !bkey_cmp(end, k->k.p);
}
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
#include "bcachefs.h" #include "bcachefs.h"
int bch2_extent_atomic_end(struct btree_iter *, struct bkey_i *, int bch2_extent_atomic_end(struct btree_trans *, struct btree_iter *,
struct bpos *); struct bkey_i *, struct bpos *);
int bch2_extent_trim_atomic(struct bkey_i *, struct btree_iter *); int bch2_extent_trim_atomic(struct btree_trans *, struct btree_iter *,
int bch2_extent_is_atomic(struct bkey_i *, struct btree_iter *); struct bkey_i *);
#endif /* _BCACHEFS_EXTENT_UPDATE_H */ #endif /* _BCACHEFS_EXTENT_UPDATE_H */
...@@ -2576,7 +2576,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode, ...@@ -2576,7 +2576,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
copy.k->k.p.offset += shift >> 9; copy.k->k.p.offset += shift >> 9;
bch2_btree_iter_set_pos(dst, bkey_start_pos(&copy.k->k)); bch2_btree_iter_set_pos(dst, bkey_start_pos(&copy.k->k));
ret = bch2_extent_atomic_end(dst, copy.k, &atomic_end); ret = bch2_extent_atomic_end(&trans, dst, copy.k, &atomic_end);
if (ret) if (ret)
continue; continue;
......
...@@ -280,7 +280,7 @@ int bch2_extent_update(struct btree_trans *trans, ...@@ -280,7 +280,7 @@ int bch2_extent_update(struct btree_trans *trans,
s64 i_sectors_delta = 0, disk_sectors_delta = 0; s64 i_sectors_delta = 0, disk_sectors_delta = 0;
int ret; int ret;
ret = bch2_extent_trim_atomic(k, iter); ret = bch2_extent_trim_atomic(trans, iter, k);
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment