diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-03-03 18:39:07 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2019-04-03 12:44:09 -0400 |
commit | 319b6fb9fc86790ab4712ca6540800291df7be41 (patch) | |
tree | 3bffd476be964bc80919e3b0043d797f1f9ed3d0 | |
parent | 89c9412c5d108b329d100716896a91983788a1c2 (diff) |
bcachefs: Separate discards from rest of journal reclaim
-rw-r--r-- | fs/bcachefs/journal.c | 13 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.h | 1 | ||||
-rw-r--r-- | 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 16ec417910da..48a1bc54ead1 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 37275ff57b31..68050db7914a 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -44,6 +44,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); @@ -64,9 +65,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; @@ -155,7 +161,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 1d688d6fa2cc..75117f2464c0 100644 --- a/fs/bcachefs/journal_reclaim.h +++ b/fs/bcachefs/journal_reclaim.h @@ -33,6 +33,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 9f1db6d28cd9..cb848ff6e24b 100644 --- a/fs/bcachefs/journal_types.h +++ b/fs/bcachefs/journal_types.h @@ -209,6 +209,8 @@ struct journal { /* protects advancing ja->discard_idx: */ struct mutex discard_lock; + bool can_discard; + unsigned write_delay_ms; unsigned reclaim_delay_ms; |