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.c60
1 files changed, 23 insertions, 37 deletions
diff --git a/libbcachefs/btree_io.c b/libbcachefs/btree_io.c
index d827692b..b56b1735 100644
--- a/libbcachefs/btree_io.c
+++ b/libbcachefs/btree_io.c
@@ -1311,8 +1311,7 @@ static void btree_node_write_endio(struct bio *bio)
void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
struct closure *parent,
- enum six_lock_type lock_type_held,
- int idx_to_write)
+ enum six_lock_type lock_type_held)
{
struct bio *bio;
struct bch_write_bio *wbio;
@@ -1344,14 +1343,8 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
if (!(old & (1 << BTREE_NODE_dirty)))
return;
- if (idx_to_write >= 0 &&
- idx_to_write != !!(old & (1 << BTREE_NODE_write_idx)))
- return;
-
if (old & (1 << BTREE_NODE_write_in_flight)) {
- wait_on_bit_io(&b->flags,
- BTREE_NODE_write_in_flight,
- TASK_UNINTERRUPTIBLE);
+ btree_node_wait_on_io(b);
continue;
}
@@ -1614,37 +1607,29 @@ bool bch2_btree_post_write_cleanup(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,
- int idx_to_write)
+ enum six_lock_type lock_type_held)
{
BUG_ON(lock_type_held == SIX_LOCK_write);
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, idx_to_write);
+ __bch2_btree_node_write(c, b, parent, SIX_LOCK_intent);
- six_lock_write(&b->lock);
- bch2_btree_post_write_cleanup(c, b);
- six_unlock_write(&b->lock);
+ /* don't cycle lock unnecessarily: */
+ if (btree_node_just_written(b)) {
+ six_lock_write(&b->lock);
+ bch2_btree_post_write_cleanup(c, b);
+ six_unlock_write(&b->lock);
+ }
if (lock_type_held == SIX_LOCK_read)
six_lock_downgrade(&b->lock);
} else {
- __bch2_btree_node_write(c, b, parent, SIX_LOCK_read, idx_to_write);
+ __bch2_btree_node_write(c, b, parent, SIX_LOCK_read);
}
}
-static void bch2_btree_node_write_dirty(struct bch_fs *c, struct btree *b,
- struct closure *parent)
-{
- six_lock_read(&b->lock);
- BUG_ON(b->level);
-
- bch2_btree_node_write(c, b, parent, SIX_LOCK_read, -1);
- six_unlock_read(&b->lock);
-}
-
/*
* Write all dirty btree nodes to disk, including roots
*/
@@ -1654,7 +1639,7 @@ void bch2_btree_flush(struct bch_fs *c)
struct btree *b;
struct bucket_table *tbl;
struct rhash_head *pos;
- bool dropped_lock;
+ bool saw_dirty;
unsigned i;
closure_init_stack(&cl);
@@ -1662,26 +1647,27 @@ void bch2_btree_flush(struct bch_fs *c)
rcu_read_lock();
do {
- dropped_lock = false;
+ saw_dirty = false;
i = 0;
restart:
tbl = rht_dereference_rcu(c->btree_cache_table.tbl,
&c->btree_cache_table);
for (; i < tbl->size; i++)
- rht_for_each_entry_rcu(b, pos, tbl, i, hash)
- /*
- * XXX - locking for b->level, when called from
- * bch2_journal_move()
- */
- if (!b->level && btree_node_dirty(b)) {
+ rht_for_each_entry_rcu(b, pos, tbl, i, hash) {
+ saw_dirty |= btree_node_dirty(b);
+
+ if (btree_node_dirty(b) &&
+ btree_node_may_write(b)) {
rcu_read_unlock();
- bch2_btree_node_write_dirty(c, b, &cl);
- dropped_lock = true;
+ six_lock_read(&b->lock);
+ bch2_btree_node_write_dirty(c, b, &cl, 1);
+ six_unlock_read(&b->lock);
rcu_read_lock();
goto restart;
}
- } while (dropped_lock);
+ }
+ } while (saw_dirty);
rcu_read_unlock();