Skip to content

Commit bc6fce7

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_btree_node_write_trans()
Avoiding screwing up path->lock_seq. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 4bd06f0 commit bc6fce7

File tree

5 files changed

+55
-20
lines changed

5 files changed

+55
-20
lines changed

fs/bcachefs/btree_io.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,8 @@ void bch2_btree_init_next(struct btree_trans *trans, struct btree *b)
489489
if (b->nsets == MAX_BSETS &&
490490
!btree_node_write_in_flight(b) &&
491491
should_compact_all(c, b)) {
492-
bch2_btree_node_write(c, b, SIX_LOCK_write,
493-
BTREE_WRITE_init_next_bset);
492+
bch2_btree_node_write_trans(trans, b, SIX_LOCK_write,
493+
BTREE_WRITE_init_next_bset);
494494
reinit_iter = true;
495495
}
496496

@@ -2345,6 +2345,34 @@ void bch2_btree_node_write(struct bch_fs *c, struct btree *b,
23452345
}
23462346
}
23472347

2348+
void bch2_btree_node_write_trans(struct btree_trans *trans, struct btree *b,
2349+
enum six_lock_type lock_type_held,
2350+
unsigned flags)
2351+
{
2352+
struct bch_fs *c = trans->c;
2353+
2354+
if (lock_type_held == SIX_LOCK_intent ||
2355+
(lock_type_held == SIX_LOCK_read &&
2356+
six_lock_tryupgrade(&b->c.lock))) {
2357+
__bch2_btree_node_write(c, b, flags);
2358+
2359+
/* don't cycle lock unnecessarily: */
2360+
if (btree_node_just_written(b) &&
2361+
six_trylock_write(&b->c.lock)) {
2362+
bch2_btree_post_write_cleanup(c, b);
2363+
__bch2_btree_node_unlock_write(trans, b);
2364+
}
2365+
2366+
if (lock_type_held == SIX_LOCK_read)
2367+
six_lock_downgrade(&b->c.lock);
2368+
} else {
2369+
__bch2_btree_node_write(c, b, flags);
2370+
if (lock_type_held == SIX_LOCK_write &&
2371+
btree_node_just_written(b))
2372+
bch2_btree_post_write_cleanup(c, b);
2373+
}
2374+
}
2375+
23482376
static bool __bch2_btree_flush_all(struct bch_fs *c, unsigned flag)
23492377
{
23502378
struct bucket_table *tbl;

fs/bcachefs/btree_io.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,13 @@ enum btree_write_flags {
144144
void __bch2_btree_node_write(struct bch_fs *, struct btree *, unsigned);
145145
void bch2_btree_node_write(struct bch_fs *, struct btree *,
146146
enum six_lock_type, unsigned);
147+
void bch2_btree_node_write_trans(struct btree_trans *, struct btree *,
148+
enum six_lock_type, unsigned);
147149

148-
static inline void btree_node_write_if_need(struct bch_fs *c, struct btree *b,
150+
static inline void btree_node_write_if_need(struct btree_trans *trans, struct btree *b,
149151
enum six_lock_type lock_held)
150152
{
151-
bch2_btree_node_write(c, b, lock_held, BTREE_WRITE_ONLY_IF_NEED);
153+
bch2_btree_node_write_trans(trans, b, lock_held, BTREE_WRITE_ONLY_IF_NEED);
152154
}
153155

154156
bool bch2_btree_flush_all_reads(struct bch_fs *);

fs/bcachefs/btree_locking.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,22 +163,27 @@ static inline void __bch2_btree_path_unlock(struct btree_trans *trans,
163163
* succeed:
164164
*/
165165
static inline void
166-
bch2_btree_node_unlock_write_inlined(struct btree_trans *trans, struct btree_path *path,
167-
struct btree *b)
166+
__bch2_btree_node_unlock_write(struct btree_trans *trans, struct btree *b)
168167
{
169168
struct btree_path *linked;
170169
unsigned i;
171170

171+
trans_for_each_path_with_node(trans, b, linked, i)
172+
linked->l[b->c.level].lock_seq++;
173+
174+
six_unlock_write(&b->c.lock);
175+
}
176+
177+
static inline void
178+
bch2_btree_node_unlock_write_inlined(struct btree_trans *trans, struct btree_path *path,
179+
struct btree *b)
180+
{
172181
EBUG_ON(path->l[b->c.level].b != b);
173182
EBUG_ON(path->l[b->c.level].lock_seq != six_lock_seq(&b->c.lock));
174183
EBUG_ON(btree_node_locked_type(path, b->c.level) != SIX_LOCK_write);
175184

176185
mark_btree_node_locked_noreset(path, b->c.level, BTREE_NODE_INTENT_LOCKED);
177-
178-
trans_for_each_path_with_node(trans, b, linked, i)
179-
linked->l[b->c.level].lock_seq++;
180-
181-
six_unlock_write(&b->c.lock);
186+
__bch2_btree_node_unlock_write(trans, b);
182187
}
183188

184189
void bch2_btree_node_unlock_write(struct btree_trans *,

fs/bcachefs/btree_trans_commit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
249249
new |= 1 << BTREE_NODE_need_write;
250250
} while (!try_cmpxchg(&b->flags, &old, new));
251251

252-
btree_node_write_if_need(c, b, SIX_LOCK_read);
252+
btree_node_write_if_need(trans, b, SIX_LOCK_read);
253253
six_unlock_read(&b->c.lock);
254254

255255
bch2_trans_put(trans);

fs/bcachefs/btree_update_interior.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ static void btree_update_nodes_written(struct btree_update *as)
803803
mark_btree_node_locked_noreset(path, b->c.level, BTREE_NODE_INTENT_LOCKED);
804804
six_unlock_write(&b->c.lock);
805805

806-
btree_node_write_if_need(c, b, SIX_LOCK_intent);
806+
btree_node_write_if_need(trans, b, SIX_LOCK_intent);
807807
btree_node_unlock(trans, path, b->c.level);
808808
bch2_path_put(trans, path_idx, true);
809809
}
@@ -824,7 +824,7 @@ static void btree_update_nodes_written(struct btree_update *as)
824824
b = as->new_nodes[i];
825825

826826
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
827-
btree_node_write_if_need(c, b, SIX_LOCK_read);
827+
btree_node_write_if_need(trans, b, SIX_LOCK_read);
828828
six_unlock_read(&b->c.lock);
829829
}
830830

@@ -1709,14 +1709,14 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
17091709

17101710
if (n3) {
17111711
bch2_btree_update_get_open_buckets(as, n3);
1712-
bch2_btree_node_write(c, n3, SIX_LOCK_intent, 0);
1712+
bch2_btree_node_write_trans(trans, n3, SIX_LOCK_intent, 0);
17131713
}
17141714
if (n2) {
17151715
bch2_btree_update_get_open_buckets(as, n2);
1716-
bch2_btree_node_write(c, n2, SIX_LOCK_intent, 0);
1716+
bch2_btree_node_write_trans(trans, n2, SIX_LOCK_intent, 0);
17171717
}
17181718
bch2_btree_update_get_open_buckets(as, n1);
1719-
bch2_btree_node_write(c, n1, SIX_LOCK_intent, 0);
1719+
bch2_btree_node_write_trans(trans, n1, SIX_LOCK_intent, 0);
17201720

17211721
/*
17221722
* The old node must be freed (in memory) _before_ unlocking the new
@@ -1911,7 +1911,7 @@ static void __btree_increase_depth(struct btree_update *as, struct btree_trans *
19111911
BUG_ON(ret);
19121912

19131913
bch2_btree_update_get_open_buckets(as, n);
1914-
bch2_btree_node_write(c, n, SIX_LOCK_intent, 0);
1914+
bch2_btree_node_write_trans(trans, n, SIX_LOCK_intent, 0);
19151915
bch2_trans_node_add(trans, path, n);
19161916
six_unlock_intent(&n->c.lock);
19171917

@@ -2104,7 +2104,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
21042104
bch2_trans_verify_paths(trans);
21052105

21062106
bch2_btree_update_get_open_buckets(as, n);
2107-
bch2_btree_node_write(c, n, SIX_LOCK_intent, 0);
2107+
bch2_btree_node_write_trans(trans, n, SIX_LOCK_intent, 0);
21082108

21092109
bch2_btree_node_free_inmem(trans, trans->paths + path, b);
21102110
bch2_btree_node_free_inmem(trans, trans->paths + sib_path, m);
@@ -2181,7 +2181,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
21812181
bch2_btree_interior_update_will_free_node(as, b);
21822182

21832183
bch2_btree_update_get_open_buckets(as, n);
2184-
bch2_btree_node_write(c, n, SIX_LOCK_intent, 0);
2184+
bch2_btree_node_write_trans(trans, n, SIX_LOCK_intent, 0);
21852185

21862186
bch2_btree_node_free_inmem(trans, btree_iter_path(trans, iter), b);
21872187

0 commit comments

Comments
 (0)