summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-01-25 00:50:48 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:08:15 +0300
commiteac3ca0f49737ba3120ccaa990877b2a05bc88cc (patch)
tree3cc6fda61ffd4f2ac6984c5bebfbdfdd8332baf0 /fs
parent6e1b07183a32583cbe4d781ea0e14e0b06bc44af (diff)
downloadlinux-eac3ca0f49737ba3120ccaa990877b2a05bc88cc.tar.xz
bcachefs: New journal_entry_res mechanism
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/journal.c57
-rw-r--r--fs/bcachefs/journal.h4
-rw-r--r--fs/bcachefs/journal_types.h11
3 files changed, 61 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);
diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h
index d9c094ba2ca0..6ef34bdae628 100644
--- a/fs/bcachefs/journal.h
+++ b/fs/bcachefs/journal.h
@@ -333,6 +333,10 @@ out:
return 0;
}
+void bch2_journal_entry_res_resize(struct journal *,
+ struct journal_entry_res *,
+ unsigned);
+
u64 bch2_journal_last_unwritten_seq(struct journal *);
int bch2_journal_open_seq_async(struct journal *, u64, struct closure *);
diff --git a/fs/bcachefs/journal_types.h b/fs/bcachefs/journal_types.h
index 51e453652d67..5f6d2320c5cd 100644
--- a/fs/bcachefs/journal_types.h
+++ b/fs/bcachefs/journal_types.h
@@ -24,6 +24,7 @@ struct journal_buf {
unsigned size;
unsigned disk_sectors;
+ unsigned u64s_reserved;
/* bloom filter: */
unsigned long has_inode[1024 / sizeof(unsigned long)];
};
@@ -155,6 +156,9 @@ struct journal {
u64 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
* written out.
@@ -243,4 +247,11 @@ struct journal_device {
struct closure read;
};
+/*
+ * journal_entry_res - reserve space in every journal entry:
+ */
+struct journal_entry_res {
+ unsigned u64s;
+};
+
#endif /* _BCACHEFS_JOURNAL_TYPES_H */