diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-01 04:14:52 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-05 00:30:27 -0500 |
commit | ab8b3e611a960d723c1592a40bfba61919d55c6d (patch) | |
tree | cb00cabe02260e03684fe913345ba44226ab1d8d | |
parent | 9adb5e0f1905e0be658a0422d04b3abb5640cd20 (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.c | 28 | ||||
-rw-r--r-- | fs/bcachefs/btree_io.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 10 |
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); |