summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_io.c')
-rw-r--r--libbcachefs/btree_io.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/libbcachefs/btree_io.c b/libbcachefs/btree_io.c
index 3f87e91e..fb76b29e 100644
--- a/libbcachefs/btree_io.c
+++ b/libbcachefs/btree_io.c
@@ -1425,6 +1425,19 @@ err:
void bch2_btree_complete_write(struct bch_fs *c, struct btree *b,
struct btree_write *w)
{
+ unsigned long old, new, v = READ_ONCE(b->will_make_reachable);
+
+ do {
+ old = new = v;
+ if (!(old & 1))
+ break;
+
+ new &= ~1UL;
+ } while ((v = cmpxchg(&b->will_make_reachable, old, new)) != old);
+
+ if (old & 1)
+ closure_put(&((struct btree_update *) new)->cl);
+
bch2_journal_pin_drop(&c->journal, &w->journal);
closure_wake_up(&w->wait);
}
@@ -1441,7 +1454,6 @@ static void bch2_btree_node_write_error(struct bch_fs *c,
struct btree_write_bio *wbio)
{
struct btree *b = wbio->wbio.bio.bi_private;
- struct closure *cl = wbio->cl;
__BKEY_PADDED(k, BKEY_BTREE_PTR_VAL_U64s_MAX) tmp;
struct bkey_i_extent *new_key;
struct bkey_s_extent e;
@@ -1488,8 +1500,6 @@ out:
bch2_btree_iter_unlock(&iter);
bio_put(&wbio->wbio.bio);
btree_node_write_done(c, b);
- if (cl)
- closure_put(cl);
return;
err:
set_btree_node_noevict(b);
@@ -1520,7 +1530,6 @@ static void btree_node_write_work(struct work_struct *work)
{
struct btree_write_bio *wbio =
container_of(work, struct btree_write_bio, work);
- struct closure *cl = wbio->cl;
struct bch_fs *c = wbio->wbio.c;
struct btree *b = wbio->wbio.bio.bi_private;
@@ -1542,8 +1551,6 @@ static void btree_node_write_work(struct work_struct *work)
bio_put(&wbio->wbio.bio);
btree_node_write_done(c, b);
- if (cl)
- closure_put(cl);
}
static void btree_node_write_endio(struct bio *bio)
@@ -1598,7 +1605,6 @@ static int validate_bset_for_write(struct bch_fs *c, struct btree *b,
}
void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
- struct closure *parent,
enum six_lock_type lock_type_held)
{
struct btree_write_bio *wbio;
@@ -1651,7 +1657,7 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
BUG_ON(btree_node_fake(b));
BUG_ON(!list_empty(&b->write_blocked));
- BUG_ON((b->will_make_reachable != NULL) != !b->written);
+ BUG_ON((b->will_make_reachable != 0) != !b->written);
BUG_ON(b->written >= c->opts.btree_node_size);
BUG_ON(bset_written(b, btree_bset_last(b)));
@@ -1786,7 +1792,6 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
struct btree_write_bio, wbio.bio);
wbio_init(&wbio->wbio.bio);
wbio->data = data;
- wbio->cl = parent;
wbio->wbio.order = order;
wbio->wbio.used_mempool = used_mempool;
wbio->wbio.bio.bi_opf = REQ_OP_WRITE|REQ_META|REQ_FUA;
@@ -1794,9 +1799,6 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
wbio->wbio.bio.bi_end_io = btree_node_write_endio;
wbio->wbio.bio.bi_private = b;
- if (parent)
- closure_get(parent);
-
bch2_bio_map(&wbio->wbio.bio, data);
/*
@@ -1893,7 +1895,6 @@ bool bch2_btree_post_write_cleanup(struct bch_fs *c, struct btree *b)
* Use this one if the node is intent locked:
*/
void bch2_btree_node_write(struct bch_fs *c, struct btree *b,
- struct closure *parent,
enum six_lock_type lock_type_held)
{
BUG_ON(lock_type_held == SIX_LOCK_write);
@@ -1901,7 +1902,7 @@ void bch2_btree_node_write(struct bch_fs *c, struct btree *b,
if (lock_type_held == SIX_LOCK_intent ||
six_trylock_convert(&b->lock, SIX_LOCK_read,
SIX_LOCK_intent)) {
- __bch2_btree_node_write(c, b, parent, SIX_LOCK_intent);
+ __bch2_btree_node_write(c, b, SIX_LOCK_intent);
/* don't cycle lock unnecessarily: */
if (btree_node_just_written(b)) {
@@ -1913,7 +1914,7 @@ void bch2_btree_node_write(struct bch_fs *c, struct btree *b,
if (lock_type_held == SIX_LOCK_read)
six_lock_downgrade(&b->lock);
} else {
- __bch2_btree_node_write(c, b, parent, SIX_LOCK_read);
+ __bch2_btree_node_write(c, b, SIX_LOCK_read);
}
}