diff options
-rw-r--r-- | fs/bcachefs/journal.h | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h index 8d17330aea99..54446580ac5d 100644 --- a/fs/bcachefs/journal.h +++ b/fs/bcachefs/journal.h @@ -344,19 +344,29 @@ static inline int journal_res_get_fast(struct journal *j, unsigned flags) { union journal_res_state old, new; - unsigned offset; + unsigned u64s, offset; old.v = atomic64_read(&j->reservations.counter); do { new.v = old.v; /* + * Round up the end of the journal reservation to the next + * cacheline boundary: + */ + u64s = res->u64s; + offset = sizeof(struct jset) / sizeof(u64) + + new.cur_entry_offset + u64s; + u64s += ((offset - 1) & ((SMP_CACHE_BYTES / sizeof(u64)) - 1)) + 1; + + + /* * Check if there is still room in the current journal * entry, smp_rmb() guarantees that reads from reservations.counter * occur before accessing cur_entry_u64s: */ smp_rmb(); - if (new.cur_entry_offset + res->u64s > j->cur_entry_u64s) + if (new.cur_entry_offset + u64s > j->cur_entry_u64s) return 0; EBUG_ON(!journal_state_count(new, new.idx)); @@ -364,7 +374,7 @@ static inline int journal_res_get_fast(struct journal *j, if ((flags & BCH_WATERMARK_MASK) < j->watermark) return 0; - new.cur_entry_offset += res->u64s; + new.cur_entry_offset += u64s; journal_state_inc(&new); /* @@ -380,6 +390,7 @@ static inline int journal_res_get_fast(struct journal *j, &old.v, new.v)); res->ref = true; + res->u64s = u64s; res->offset = old.cur_entry_offset; res->seq = journal_cur_seq(j); res->seq -= (res->seq - old.idx) & JOURNAL_STATE_BUF_MASK; |