138 lines
4.1 KiB
Diff
138 lines
4.1 KiB
Diff
From 01d8d04564c46cfafc454511601610af2fb4a8fb Mon Sep 17 00:00:00 2001
|
|
From: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Date: Sat, 23 Nov 2024 16:27:47 -0500
|
|
Subject: [PATCH 110/233] bcachefs: Can now block journal activity without
|
|
closing cur entry
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
|
---
|
|
fs/bcachefs/journal.c | 44 +++++++++++++++++++++++++++++++++++--
|
|
fs/bcachefs/journal.h | 3 ++-
|
|
fs/bcachefs/journal_types.h | 2 ++
|
|
3 files changed, 46 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
|
|
index 2cf8f24d50cc..bfbb1ac60c3d 100644
|
|
--- a/fs/bcachefs/journal.c
|
|
+++ b/fs/bcachefs/journal.c
|
|
@@ -217,6 +217,12 @@ void bch2_journal_buf_put_final(struct journal *j, u64 seq)
|
|
if (__bch2_journal_pin_put(j, seq))
|
|
bch2_journal_reclaim_fast(j);
|
|
bch2_journal_do_writes(j);
|
|
+
|
|
+ /*
|
|
+ * for __bch2_next_write_buffer_flush_journal_buf(), when quiescing an
|
|
+ * open journal entry
|
|
+ */
|
|
+ wake_up(&j->wait);
|
|
}
|
|
|
|
/*
|
|
@@ -251,6 +257,9 @@ static void __journal_entry_close(struct journal *j, unsigned closed_val, bool t
|
|
if (!__journal_entry_is_open(old))
|
|
return;
|
|
|
|
+ if (old.cur_entry_offset == JOURNAL_ENTRY_BLOCKED_VAL)
|
|
+ old.cur_entry_offset = j->cur_entry_offset_if_blocked;
|
|
+
|
|
/* Close out old buffer: */
|
|
buf->data->u64s = cpu_to_le32(old.cur_entry_offset);
|
|
|
|
@@ -868,16 +877,44 @@ int bch2_journal_meta(struct journal *j)
|
|
void bch2_journal_unblock(struct journal *j)
|
|
{
|
|
spin_lock(&j->lock);
|
|
- j->blocked--;
|
|
+ if (!--j->blocked &&
|
|
+ j->cur_entry_offset_if_blocked < JOURNAL_ENTRY_CLOSED_VAL &&
|
|
+ j->reservations.cur_entry_offset == JOURNAL_ENTRY_BLOCKED_VAL) {
|
|
+ union journal_res_state old, new;
|
|
+
|
|
+ old.v = atomic64_read(&j->reservations.counter);
|
|
+ do {
|
|
+ new.v = old.v;
|
|
+ new.cur_entry_offset = j->cur_entry_offset_if_blocked;
|
|
+ } while (!atomic64_try_cmpxchg(&j->reservations.counter, &old.v, new.v));
|
|
+ }
|
|
spin_unlock(&j->lock);
|
|
|
|
journal_wake(j);
|
|
}
|
|
|
|
+static void __bch2_journal_block(struct journal *j)
|
|
+{
|
|
+ if (!j->blocked++) {
|
|
+ union journal_res_state old, new;
|
|
+
|
|
+ old.v = atomic64_read(&j->reservations.counter);
|
|
+ do {
|
|
+ j->cur_entry_offset_if_blocked = old.cur_entry_offset;
|
|
+
|
|
+ if (j->cur_entry_offset_if_blocked >= JOURNAL_ENTRY_CLOSED_VAL)
|
|
+ break;
|
|
+
|
|
+ new.v = old.v;
|
|
+ new.cur_entry_offset = JOURNAL_ENTRY_BLOCKED_VAL;
|
|
+ } while (!atomic64_try_cmpxchg(&j->reservations.counter, &old.v, new.v));
|
|
+ }
|
|
+}
|
|
+
|
|
void bch2_journal_block(struct journal *j)
|
|
{
|
|
spin_lock(&j->lock);
|
|
- j->blocked++;
|
|
+ __bch2_journal_block(j);
|
|
spin_unlock(&j->lock);
|
|
|
|
journal_quiesce(j);
|
|
@@ -1481,6 +1518,9 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
|
|
case JOURNAL_ENTRY_CLOSED_VAL:
|
|
prt_printf(out, "closed\n");
|
|
break;
|
|
+ case JOURNAL_ENTRY_BLOCKED_VAL:
|
|
+ prt_printf(out, "blocked\n");
|
|
+ break;
|
|
default:
|
|
prt_printf(out, "%u/%u\n", s.cur_entry_offset, j->cur_entry_u64s);
|
|
break;
|
|
diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h
|
|
index 2762be6f9814..6d3c839bbbef 100644
|
|
--- a/fs/bcachefs/journal.h
|
|
+++ b/fs/bcachefs/journal.h
|
|
@@ -285,7 +285,8 @@ static inline void bch2_journal_buf_put(struct journal *j, unsigned idx, u64 seq
|
|
spin_lock(&j->lock);
|
|
bch2_journal_buf_put_final(j, seq);
|
|
spin_unlock(&j->lock);
|
|
- }
|
|
+ } else if (unlikely(s.cur_entry_offset == JOURNAL_ENTRY_BLOCKED_VAL))
|
|
+ wake_up(&j->wait);
|
|
}
|
|
|
|
/*
|
|
diff --git a/fs/bcachefs/journal_types.h b/fs/bcachefs/journal_types.h
|
|
index 19183fcf7ad7..425d1abb257e 100644
|
|
--- a/fs/bcachefs/journal_types.h
|
|
+++ b/fs/bcachefs/journal_types.h
|
|
@@ -112,6 +112,7 @@ union journal_res_state {
|
|
*/
|
|
#define JOURNAL_ENTRY_OFFSET_MAX ((1U << 20) - 1)
|
|
|
|
+#define JOURNAL_ENTRY_BLOCKED_VAL (JOURNAL_ENTRY_OFFSET_MAX - 2)
|
|
#define JOURNAL_ENTRY_CLOSED_VAL (JOURNAL_ENTRY_OFFSET_MAX - 1)
|
|
#define JOURNAL_ENTRY_ERROR_VAL (JOURNAL_ENTRY_OFFSET_MAX)
|
|
|
|
@@ -193,6 +194,7 @@ struct journal {
|
|
* insufficient devices:
|
|
*/
|
|
enum journal_errors cur_entry_error;
|
|
+ unsigned cur_entry_offset_if_blocked;
|
|
|
|
unsigned buf_size_want;
|
|
/*
|
|
--
|
|
2.45.2
|
|
|