diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-01-24 16:50:48 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:15 -0400 |
commit | eac3ca0f49737ba3120ccaa990877b2a05bc88cc (patch) | |
tree | 3cc6fda61ffd4f2ac6984c5bebfbdfdd8332baf0 /fs/bcachefs/journal.c | |
parent | 6e1b07183a32583cbe4d781ea0e14e0b06bc44af (diff) |
bcachefs: New journal_entry_res mechanism
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/journal.c')
-rw-r--r-- | fs/bcachefs/journal.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 310553bd5323..dd10f1c993e5 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -64,11 +64,6 @@ static void bch2_journal_buf_init(struct journal *j) buf->data->u64s = 0; } -static inline size_t journal_entry_u64s_reserve(struct journal_buf *buf) -{ - return BTREE_ID_NR * (JSET_KEYS_U64s + BKEY_EXTENT_U64s_MAX); -} - static inline bool journal_entry_empty(struct jset *j) { struct jset_entry *i; @@ -130,7 +125,7 @@ static enum { j->prev_buf_sectors = vstruct_blocks_plus(buf->data, c->block_bits, - journal_entry_u64s_reserve(buf)) * + buf->u64s_reserved) * c->opts.block_size; BUG_ON(j->prev_buf_sectors > j->cur_buf_sectors); @@ -225,6 +220,7 @@ static int journal_entry_open(struct journal *j) return sectors; buf->disk_sectors = sectors; + buf->u64s_reserved = j->entry_u64s_reserved; sectors = min_t(unsigned, sectors, buf->size >> 9); j->cur_buf_sectors = sectors; @@ -233,11 +229,7 @@ static int journal_entry_open(struct journal *j) /* Subtract the journal header */ u64s -= sizeof(struct jset) / sizeof(u64); - /* - * Btree roots, prio pointers don't get added until right before we do - * the write: - */ - u64s -= journal_entry_u64s_reserve(buf); + u64s -= buf->u64s_reserved; u64s = max_t(ssize_t, 0L, u64s); BUG_ON(u64s >= JOURNAL_ENTRY_CLOSED_VAL); @@ -437,6 +429,45 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res, return ret; } +/* journal_entry_res: */ + +void bch2_journal_entry_res_resize(struct journal *j, + struct journal_entry_res *res, + unsigned new_u64s) +{ + union journal_res_state state; + int d = new_u64s - res->u64s; + + spin_lock(&j->lock); + + j->entry_u64s_reserved += d; + if (d <= 0) + goto out_unlock; + + j->cur_entry_u64s -= d; + smp_mb(); + state = READ_ONCE(j->reservations); + + if (state.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL && + state.cur_entry_offset > j->cur_entry_u64s) { + j->cur_entry_u64s += d; + /* + * Not enough room in current journal entry, have to flush it: + */ + __journal_entry_close(j); + goto out; + } + + journal_cur_buf(j)->u64s_reserved += d; +out_unlock: + spin_unlock(&j->lock); +out: + res->u64s += d; + return; +} + +/* journal flushing: */ + u64 bch2_journal_last_unwritten_seq(struct journal *j) { u64 seq; @@ -1024,6 +1055,10 @@ int bch2_fs_journal_init(struct journal *j) j->write_delay_ms = 1000; j->reclaim_delay_ms = 100; + /* Btree roots: */ + j->entry_u64s_reserved += + BTREE_ID_NR * (JSET_KEYS_U64s + BKEY_EXTENT_U64s_MAX); + atomic64_set(&j->reservations.counter, ((union journal_res_state) { .cur_entry_offset = JOURNAL_ENTRY_CLOSED_VAL }).v); |