diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-12-19 14:17:42 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-12-27 15:11:28 -0500 |
commit | 89c33713831965a0679caa420095cdb0672ac3b2 (patch) | |
tree | 67348f6e3a91e0ee39d163ccddc8db2e9fe33f55 | |
parent | ec5742e69075b4ab768891790b7a7ae587d17f65 (diff) |
bcachefs: Add bch2_journal_flush_all_pins()
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/journal.c | 20 | ||||
-rw-r--r-- | fs/bcachefs/journal.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 2 |
5 files changed, 27 insertions, 9 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index d472b3b81bfd..f5811ef57bdb 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -519,6 +519,7 @@ struct bch_fs { struct bio_set btree_read_bio; struct btree_root btree_roots[BTREE_ID_NR]; + bool btree_roots_dirty; struct mutex btree_root_lock; struct btree_cache btree_cache; diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 09f515f4dace..6351e9c2490f 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -21,7 +21,7 @@ static void btree_node_will_make_reachable(struct btree_update *, struct btree *); static void btree_update_drop_new_node(struct bch_fs *, struct btree *); -static void bch2_btree_set_root_ondisk(struct bch_fs *, struct btree *); +static void bch2_btree_set_root_ondisk(struct bch_fs *, struct btree *, int); /* Debug code: */ @@ -686,7 +686,7 @@ retry: BUG_ON(c->btree_roots[b->btree_id].as != as); c->btree_roots[b->btree_id].as = NULL; - bch2_btree_set_root_ondisk(c, b); + bch2_btree_set_root_ondisk(c, b, WRITE); /* * We don't have to wait anything anything here (before @@ -1055,7 +1055,7 @@ static void bch2_btree_set_root_inmem(struct btree_update *as, struct btree *b) gc_pos_btree_root(b->btree_id)); } -static void bch2_btree_set_root_ondisk(struct bch_fs *c, struct btree *b) +static void bch2_btree_set_root_ondisk(struct bch_fs *c, struct btree *b, int rw) { struct btree_root *r = &c->btree_roots[b->btree_id]; @@ -1065,6 +1065,8 @@ static void bch2_btree_set_root_ondisk(struct bch_fs *c, struct btree *b) bkey_copy(&r->key, &b->key); r->level = b->level; r->alive = true; + if (rw == WRITE) + c->btree_roots_dirty = true; mutex_unlock(&c->btree_root_lock); } @@ -1963,7 +1965,7 @@ void bch2_btree_set_root_for_read(struct bch_fs *c, struct btree *b) BUG_ON(btree_node_root(c, b)); __bch2_btree_set_root_inmem(c, b); - bch2_btree_set_root_ondisk(c, b); + bch2_btree_set_root_ondisk(c, b, READ); } int bch2_btree_root_alloc(struct bch_fs *c, enum btree_id id, @@ -1999,7 +2001,7 @@ int bch2_btree_root_alloc(struct bch_fs *c, enum btree_id id, BUG_ON(btree_node_root(c, b)); bch2_btree_set_root_inmem(as, b); - bch2_btree_set_root_ondisk(c, b); + bch2_btree_set_root_ondisk(c, b, WRITE); bch2_btree_open_bucket_put(c, b); six_unlock_intent(&b->lock); diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 36c48209f669..63ac277aec18 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -1853,6 +1853,21 @@ void bch2_journal_flush_pins(struct journal *j, u64 seq_to_flush) bch2_journal_error(j)); } +int bch2_journal_flush_all_pins(struct journal *j) +{ + struct bch_fs *c = container_of(j, struct bch_fs, journal); + bool flush; + + bch2_journal_flush_pins(j, U64_MAX); + + spin_lock(&j->lock); + flush = last_seq(j) != j->last_seq_ondisk || + c->btree_roots_dirty; + spin_unlock(&j->lock); + + return flush ? bch2_journal_meta(j) : 0; +} + static bool should_discard_bucket(struct journal *j, struct journal_device *ja) { bool ret; @@ -2235,6 +2250,7 @@ static void journal_write(struct closure *cl) if (r->alive) bch2_journal_add_btree_root(w, i, &r->key, r->level); } + c->btree_roots_dirty = false; mutex_unlock(&c->btree_root_lock); journal_write_compact(jset); @@ -2864,9 +2880,7 @@ void bch2_fs_journal_stop(struct journal *j) * journal entries, then force a brand new empty journal entry to be * written: */ - bch2_journal_flush_pins(j, U64_MAX); - bch2_journal_flush_async(j, NULL); - bch2_journal_meta(j); + bch2_journal_flush_all_pins(j); cancel_delayed_work_sync(&j->write_work); cancel_delayed_work_sync(&j->reclaim_work); diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h index 9d6c79c6c113..e6532f2f6100 100644 --- a/fs/bcachefs/journal.h +++ b/fs/bcachefs/journal.h @@ -164,6 +164,7 @@ void bch2_journal_pin_add_if_older(struct journal *, struct journal_entry_pin *, journal_pin_flush_fn); void bch2_journal_flush_pins(struct journal *, u64); +int bch2_journal_flush_all_pins(struct journal *); struct closure; struct bch_fs; diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 0b63b112fa83..c343d9f29ed9 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -212,7 +212,7 @@ static void __bch2_fs_read_only(struct bch_fs *c) * Flush journal before stopping allocators, because flushing journal * blacklist entries involves allocating new btree nodes: */ - bch2_journal_flush_pins(&c->journal, U64_MAX); + bch2_journal_flush_all_pins(&c->journal); if (!bch2_journal_error(&c->journal)) bch2_btree_verify_flushed(c); |