summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-02-01 04:14:52 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-02-05 00:30:27 -0500
commitab8b3e611a960d723c1592a40bfba61919d55c6d (patch)
treecb00cabe02260e03684fe913345ba44226ab1d8d
parent9adb5e0f1905e0be658a0422d04b3abb5640cd20 (diff)
bcachefs: Fix a shutdown bug
btree node prefetching can kick off reads in the background - have to flush them
-rw-r--r--fs/bcachefs/btree_io.c28
-rw-r--r--fs/bcachefs/btree_io.h2
-rw-r--r--fs/bcachefs/super.c10
3 files changed, 40 insertions, 0 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c
index f4acfcdc3f21..9b4eff1c83d1 100644
--- a/fs/bcachefs/btree_io.c
+++ b/fs/bcachefs/btree_io.c
@@ -1918,6 +1918,34 @@ void bch2_btree_node_write(struct bch_fs *c, struct btree *b,
}
}
+static void __bch2_btree_flush_all(struct bch_fs *c, unsigned flag)
+{
+ struct bucket_table *tbl;
+ struct rhash_head *pos;
+ struct btree *b;
+ unsigned i;
+restart:
+ rcu_read_lock();
+ for_each_cached_btree(b, c, tbl, i, pos)
+ if (test_bit(flag, &b->flags)) {
+ rcu_read_unlock();
+ wait_on_bit_io(&b->flags, flag, TASK_UNINTERRUPTIBLE);
+ goto restart;
+
+ }
+ rcu_read_unlock();
+}
+
+void bch2_btree_flush_all_reads(struct bch_fs *c)
+{
+ __bch2_btree_flush_all(c, BTREE_NODE_read_in_flight);
+}
+
+void bch2_btree_flush_all_writes(struct bch_fs *c)
+{
+ __bch2_btree_flush_all(c, BTREE_NODE_write_in_flight);
+}
+
void bch2_btree_verify_flushed(struct bch_fs *c)
{
struct bucket_table *tbl;
diff --git a/fs/bcachefs/btree_io.h b/fs/bcachefs/btree_io.h
index c0b5a0b637e1..f27907168629 100644
--- a/fs/bcachefs/btree_io.h
+++ b/fs/bcachefs/btree_io.h
@@ -136,6 +136,8 @@ do { \
} \
} while (0)
+void bch2_btree_flush_all_reads(struct bch_fs *);
+void bch2_btree_flush_all_writes(struct bch_fs *);
void bch2_btree_verify_flushed(struct bch_fs *);
ssize_t bch2_dirty_btree_nodes_print(struct bch_fs *, char *);
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 4c8569b02e1f..8c7a147a0833 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -259,6 +259,13 @@ static void __bch2_fs_read_only(struct bch_fs *c)
bch2_fs_journal_stop(&c->journal);
/*
+ * the journal kicks off btree writes via reclaim - wait for in flight
+ * writes after stopping journal:
+ */
+ if (test_bit(BCH_FS_EMERGENCY_RO, &c->flags))
+ bch2_btree_flush_all_writes(c);
+
+ /*
* After stopping journal:
*/
for_each_member_device(ca, c, i)
@@ -476,6 +483,9 @@ void bch2_fs_stop(struct bch_fs *c)
bch_fs_mark_clean(c);
+ /* btree prefetch might have kicked off reads in the background: */
+ bch2_btree_flush_all_reads(c);
+
for_each_member_device(ca, c, i)
cancel_work_sync(&ca->io_error_work);