From 2384db8f32a2df9e71cd3003d213b48f64cbde1e Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 3 Mar 2019 18:39:07 -0500 Subject: [PATCH] bcachefs: Separate discards from rest of journal reclaim Signed-off-by: Kent Overstreet --- fs/bcachefs/journal.c | 13 ++++++++++++- fs/bcachefs/journal_reclaim.c | 8 +++++++- fs/bcachefs/journal_reclaim.h | 1 + fs/bcachefs/journal_types.h | 2 ++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 17add726f2ace..80d7980cf5aa5 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -322,6 +322,7 @@ static int __journal_res_get(struct journal *j, struct journal_res *res, { struct bch_fs *c = container_of(j, struct bch_fs, journal); struct journal_buf *buf; + bool can_discard; int ret; retry: if (journal_res_get_fast(j, res, flags)) @@ -370,18 +371,28 @@ retry: !j->res_get_blocked_start) j->res_get_blocked_start = local_clock() ?: 1; + can_discard = j->can_discard; spin_unlock(&j->lock); if (!ret) goto retry; + if (ret == -ENOSPC) { /* * Journal is full - can't rely on reclaim from work item due to * freezing: */ trace_journal_full(c); - if (!(flags & JOURNAL_RES_GET_NONBLOCK)) + + if (!(flags & JOURNAL_RES_GET_NONBLOCK)) { + if (can_discard) { + bch2_journal_do_discards(j); + goto retry; + } + bch2_journal_reclaim_work(&j->reclaim_work.work); + } + ret = -EAGAIN; } diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c index 3a85fb8b85269..ac9e6cb3d4eef 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -45,6 +45,7 @@ void bch2_journal_space_available(struct journal *j) unsigned unwritten_sectors = j->reservations.prev_buf_unwritten ? journal_prev_buf(j)->sectors : 0; + bool can_discard = false; int ret = 0; lockdep_assert_held(&j->lock); @@ -65,9 +66,14 @@ void bch2_journal_space_available(struct journal *j) ja->bucket_seq[ja->dirty_idx_ondisk] < j->last_seq_ondisk) ja->dirty_idx_ondisk = (ja->dirty_idx_ondisk + 1) % ja->nr; + if (ja->discard_idx != ja->dirty_idx_ondisk) + can_discard = true; + nr_online++; } + j->can_discard = can_discard; + if (nr_online < c->opts.metadata_replicas_required) { ret = -EROFS; sectors_next_entry = 0; @@ -156,7 +162,7 @@ static bool should_discard_bucket(struct journal *j, struct journal_device *ja) * Advance ja->discard_idx as long as it points to buckets that are no longer * dirty, issuing discards if necessary: */ -static void bch2_journal_do_discards(struct journal *j) +void bch2_journal_do_discards(struct journal *j) { struct bch_fs *c = container_of(j, struct bch_fs, journal); struct bch_dev *ca; diff --git a/fs/bcachefs/journal_reclaim.h b/fs/bcachefs/journal_reclaim.h index a9afb229541b3..183419ea3e252 100644 --- a/fs/bcachefs/journal_reclaim.h +++ b/fs/bcachefs/journal_reclaim.h @@ -34,6 +34,7 @@ void bch2_journal_pin_add_if_older(struct journal *, journal_pin_flush_fn); void bch2_journal_pin_flush(struct journal *, struct journal_entry_pin *); +void bch2_journal_do_discards(struct journal *); void bch2_journal_reclaim_work(struct work_struct *); void bch2_journal_flush_pins(struct journal *, u64); diff --git a/fs/bcachefs/journal_types.h b/fs/bcachefs/journal_types.h index 09b2d22230335..c91a21e078098 100644 --- a/fs/bcachefs/journal_types.h +++ b/fs/bcachefs/journal_types.h @@ -210,6 +210,8 @@ struct journal { /* protects advancing ja->discard_idx: */ struct mutex discard_lock; + bool can_discard; + unsigned write_delay_ms; unsigned reclaim_delay_ms; -- 2.30.2