summaryrefslogtreecommitdiff
path: root/fs/bcachefs/journal_reclaim.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/journal_reclaim.c')
-rw-r--r--fs/bcachefs/journal_reclaim.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c
index f23e5ee9ad75..6400a63ed79b 100644
--- a/fs/bcachefs/journal_reclaim.c
+++ b/fs/bcachefs/journal_reclaim.c
@@ -148,6 +148,9 @@ static struct journal_space __journal_space_available(struct journal *j, unsigne
BUG_ON(nr_devs_want > ARRAY_SIZE(dev_space));
+ ssize_t mem_limit = max_t(ssize_t, 0,
+ (totalram_pages() * PAGE_SIZE) / 4 - j->dirty_entry_bytes);
+
for_each_member_device_rcu(c, ca, &c->rw_devs[BCH_DATA_journal]) {
if (!ca->journal.nr ||
!ca->mi.durability)
@@ -180,6 +183,7 @@ static struct journal_space __journal_space_available(struct journal *j, unsigne
* @nr_devs_want largest devices:
*/
space = dev_space[nr_devs_want - 1];
+ space.total = min(space.total, mem_limit >> 9);
space.next_entry = min(space.next_entry, min_bucket_size);
return space;
}
@@ -328,9 +332,17 @@ void bch2_journal_reclaim_fast(struct journal *j)
* Unpin journal entries whose reference counts reached zero, meaning
* all btree nodes got written out
*/
+ struct journal_entry_pin_list *pin_list;
while (!fifo_empty(&j->pin) &&
j->pin.front <= j->seq_ondisk &&
- !atomic_read(&fifo_peek_front(&j->pin).count)) {
+ !atomic_read(&(pin_list = &fifo_peek_front(&j->pin))->count)) {
+
+ if (WARN_ON(j->dirty_entry_bytes < pin_list->bytes))
+ pin_list->bytes = j->dirty_entry_bytes;
+
+ j->dirty_entry_bytes -= pin_list->bytes;
+ pin_list->bytes = 0;
+
j->pin.front++;
popped = true;
}