summaryrefslogtreecommitdiff
path: root/fs/bcachefs/journal.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-02-28 16:21:07 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:26 -0400
commitdfc0f7ea00a71e12772d174e5f070dd5b1bf8981 (patch)
tree7dec51b65566d2e2c265eb57a17a36ff311d00ac /fs/bcachefs/journal.c
parentfbec3b8800ac8244ce751d0ba5b83d94ee48fc76 (diff)
bcachefs: bch2_journal_halt() now takes journal lock
This change is prep work for moving some work from __journal_entry_close() to journal_entry_open(): without this change, journal_entry_open() doesn't know if it's going to be able to open a new journal entry until the cmpxchg loop, meaning it can't create the new journal pin entry and update other global state because those have to be done prior to the cmpxchg opening the new journal entry. Fortunately, we don't call bch2_journal_halt() from interrupt context. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/journal.c')
-rw-r--r--fs/bcachefs/journal.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
index 880ca2061012..0570cd1cb8cf 100644
--- a/fs/bcachefs/journal.c
+++ b/fs/bcachefs/journal.c
@@ -96,12 +96,15 @@ static void bch2_journal_buf_init(struct journal *j)
void bch2_journal_halt(struct journal *j)
{
union journal_res_state old, new;
- u64 v = atomic64_read(&j->reservations.counter);
+ u64 v;
+
+ spin_lock(&j->lock);
+ v = atomic64_read(&j->reservations.counter);
do {
old.v = new.v = v;
if (old.cur_entry_offset == JOURNAL_ENTRY_ERROR_VAL)
- return;
+ goto out;
new.cur_entry_offset = JOURNAL_ENTRY_ERROR_VAL;
} while ((v = atomic64_cmpxchg(&j->reservations.counter,
@@ -115,6 +118,8 @@ void bch2_journal_halt(struct journal *j)
j->err_seq = journal_cur_seq(j);
journal_wake(j);
closure_wake_up(&journal_cur_buf(j)->wait);
+out:
+ spin_unlock(&j->lock);
}
/* journal entry close/open: */
@@ -266,6 +271,9 @@ static int journal_entry_open(struct journal *j)
if (j->cur_entry_error)
return j->cur_entry_error;
+ if (bch2_journal_error(j))
+ return cur_entry_insufficient_devices; /* -EROFS */
+
BUG_ON(!j->cur_entry_sectors);
/* We used to add things to the first journal entry before opening it,
@@ -296,8 +304,7 @@ static int journal_entry_open(struct journal *j)
do {
old.v = new.v = v;
- if (old.cur_entry_offset == JOURNAL_ENTRY_ERROR_VAL)
- return cur_entry_insufficient_devices;
+ BUG_ON(old.cur_entry_offset == JOURNAL_ENTRY_ERROR_VAL);
EBUG_ON(journal_state_count(new, new.idx));
journal_state_inc(&new);