Commit eac3ca0f authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: New journal_entry_res mechanism

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 6e1b0718
...@@ -64,11 +64,6 @@ static void bch2_journal_buf_init(struct journal *j) ...@@ -64,11 +64,6 @@ static void bch2_journal_buf_init(struct journal *j)
buf->data->u64s = 0; 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) static inline bool journal_entry_empty(struct jset *j)
{ {
struct jset_entry *i; struct jset_entry *i;
...@@ -130,7 +125,7 @@ static enum { ...@@ -130,7 +125,7 @@ static enum {
j->prev_buf_sectors = j->prev_buf_sectors =
vstruct_blocks_plus(buf->data, c->block_bits, vstruct_blocks_plus(buf->data, c->block_bits,
journal_entry_u64s_reserve(buf)) * buf->u64s_reserved) *
c->opts.block_size; c->opts.block_size;
BUG_ON(j->prev_buf_sectors > j->cur_buf_sectors); BUG_ON(j->prev_buf_sectors > j->cur_buf_sectors);
...@@ -225,6 +220,7 @@ static int journal_entry_open(struct journal *j) ...@@ -225,6 +220,7 @@ static int journal_entry_open(struct journal *j)
return sectors; return sectors;
buf->disk_sectors = sectors; buf->disk_sectors = sectors;
buf->u64s_reserved = j->entry_u64s_reserved;
sectors = min_t(unsigned, sectors, buf->size >> 9); sectors = min_t(unsigned, sectors, buf->size >> 9);
j->cur_buf_sectors = sectors; j->cur_buf_sectors = sectors;
...@@ -233,11 +229,7 @@ static int journal_entry_open(struct journal *j) ...@@ -233,11 +229,7 @@ static int journal_entry_open(struct journal *j)
/* Subtract the journal header */ /* Subtract the journal header */
u64s -= sizeof(struct jset) / sizeof(u64); u64s -= sizeof(struct jset) / sizeof(u64);
/* u64s -= buf->u64s_reserved;
* Btree roots, prio pointers don't get added until right before we do
* the write:
*/
u64s -= journal_entry_u64s_reserve(buf);
u64s = max_t(ssize_t, 0L, u64s); u64s = max_t(ssize_t, 0L, u64s);
BUG_ON(u64s >= JOURNAL_ENTRY_CLOSED_VAL); BUG_ON(u64s >= JOURNAL_ENTRY_CLOSED_VAL);
...@@ -437,6 +429,45 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res, ...@@ -437,6 +429,45 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res,
return ret; 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 bch2_journal_last_unwritten_seq(struct journal *j)
{ {
u64 seq; u64 seq;
...@@ -1024,6 +1055,10 @@ int bch2_fs_journal_init(struct journal *j) ...@@ -1024,6 +1055,10 @@ int bch2_fs_journal_init(struct journal *j)
j->write_delay_ms = 1000; j->write_delay_ms = 1000;
j->reclaim_delay_ms = 100; 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, atomic64_set(&j->reservations.counter,
((union journal_res_state) ((union journal_res_state)
{ .cur_entry_offset = JOURNAL_ENTRY_CLOSED_VAL }).v); { .cur_entry_offset = JOURNAL_ENTRY_CLOSED_VAL }).v);
......
...@@ -333,6 +333,10 @@ static inline int bch2_journal_res_get(struct journal *j, struct journal_res *re ...@@ -333,6 +333,10 @@ static inline int bch2_journal_res_get(struct journal *j, struct journal_res *re
return 0; return 0;
} }
void bch2_journal_entry_res_resize(struct journal *,
struct journal_entry_res *,
unsigned);
u64 bch2_journal_last_unwritten_seq(struct journal *); u64 bch2_journal_last_unwritten_seq(struct journal *);
int bch2_journal_open_seq_async(struct journal *, u64, struct closure *); int bch2_journal_open_seq_async(struct journal *, u64, struct closure *);
......
...@@ -24,6 +24,7 @@ struct journal_buf { ...@@ -24,6 +24,7 @@ struct journal_buf {
unsigned size; unsigned size;
unsigned disk_sectors; unsigned disk_sectors;
unsigned u64s_reserved;
/* bloom filter: */ /* bloom filter: */
unsigned long has_inode[1024 / sizeof(unsigned long)]; unsigned long has_inode[1024 / sizeof(unsigned long)];
}; };
...@@ -155,6 +156,9 @@ struct journal { ...@@ -155,6 +156,9 @@ struct journal {
u64 seq_ondisk; u64 seq_ondisk;
u64 last_seq_ondisk; u64 last_seq_ondisk;
/* Reserved space in journal entry to be used just prior to write */
unsigned entry_u64s_reserved;
/* /*
* FIFO of journal entries whose btree updates have not yet been * FIFO of journal entries whose btree updates have not yet been
* written out. * written out.
...@@ -243,4 +247,11 @@ struct journal_device { ...@@ -243,4 +247,11 @@ struct journal_device {
struct closure read; struct closure read;
}; };
/*
* journal_entry_res - reserve space in every journal entry:
*/
struct journal_entry_res {
unsigned u64s;
};
#endif /* _BCACHEFS_JOURNAL_TYPES_H */ #endif /* _BCACHEFS_JOURNAL_TYPES_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment