summaryrefslogtreecommitdiff
path: root/fs/bcachefs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-02-20 17:34:26 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-03-17 10:35:43 -0400
commit611e7945529430e37f99df4e1e2678904c6f4041 (patch)
tree076e9aa1e77e4697e0413b9d5c79d199be680aa8 /fs/bcachefs
parentc36a644c565769dac853d4e45479256fe7b6050c (diff)
Diffstat (limited to 'fs/bcachefs')
-rw-r--r--fs/bcachefs/bcachefs.h1
-rw-r--r--fs/bcachefs/btree_update_leaf.c2
-rw-r--r--fs/bcachefs/btree_write_buffer.c34
-rw-r--r--fs/bcachefs/btree_write_buffer.h1
-rw-r--r--fs/bcachefs/btree_write_buffer_types.h1
-rw-r--r--fs/bcachefs/journal_io.c2
-rw-r--r--fs/bcachefs/opts.h2
7 files changed, 39 insertions, 4 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index a0d0c6bf9af8..aacf4e20fbbe 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -646,6 +646,7 @@ typedef struct {
#define BCH_WRITE_REFS() \
x(trans) \
+ x(write_buffer_flush) \
x(write) \
x(promote) \
x(node_rewrite) \
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 512692e7c362..8ade84befa39 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -641,7 +641,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
}
if (!(flags & BTREE_INSERT_WRITE_BUFFER_FLUSH) &&
- c->btree_write_buffer.nr > c->btree_write_buffer.size / 2)
+ c->btree_write_buffer.nr > c->btree_write_buffer.size * 3 / 4)
return -BCH_ERR_btree_insert_need_flush_buffer;
/*
diff --git a/fs/bcachefs/btree_write_buffer.c b/fs/bcachefs/btree_write_buffer.c
index d9d8aa50f13f..e08d876f2432 100644
--- a/fs/bcachefs/btree_write_buffer.c
+++ b/fs/bcachefs/btree_write_buffer.c
@@ -149,9 +149,9 @@ trans_commit:
bch2_trans_commit(trans, NULL, NULL,
commit_flags|
BTREE_INSERT_NOFAIL|
+ BTREE_INSERT_WRITE_BUFFER_FLUSH|
BTREE_INSERT_JOURNAL_RECLAIM|
- BTREE_INSERT_WRITE_BUFFER_FLUSH);
-
+ JOURNAL_WATERMARK_reserved);
}
int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans, unsigned commit_flags,
@@ -246,6 +246,7 @@ out:
bch2_journal_pin_drop(j, &pin);
return ret;
slowpath:
+ BUG();
trace_write_buffer_flush_slowpath(trans, i - keys, nr);
dst = keys;
@@ -318,6 +319,34 @@ int bch2_btree_write_buffer_flush_sync(struct btree_trans *trans, unsigned commi
return ret;
}
+static void bch2_write_buffer_flush_work(struct work_struct *work)
+{
+ struct bch_fs *c = container_of(work, struct bch_fs, btree_write_buffer.work);
+ struct btree_write_buffer *wb = &c->btree_write_buffer;
+ struct btree_trans trans;
+ int ret = 0;
+
+ bch2_trans_init(&trans, c, 0, 0);
+
+ mutex_lock(&wb->flush_lock);
+
+ while (wb->nr && !ret)
+ ret = bch2_btree_write_buffer_flush_locked(&trans, 0, true);
+
+ mutex_unlock(&wb->flush_lock);
+
+ bch2_trans_exit(&trans);
+
+ bch2_write_ref_put(c, BCH_WRITE_REF_write_buffer_flush);
+}
+
+void bch2_queue_btree_write_buffer_flush(struct bch_fs *c)
+{
+ if (bch2_write_ref_tryget(c, BCH_WRITE_REF_write_buffer_flush) &&
+ !queue_work(system_long_wq, &c->btree_write_buffer.work))
+ bch2_write_ref_put(c, BCH_WRITE_REF_write_buffer_flush);
+}
+
static int bch2_btree_write_buffer_journal_flush(struct journal *j,
struct journal_entry_pin *_pin, u64 seq)
{
@@ -372,6 +401,7 @@ int bch2_fs_btree_write_buffer_init(struct bch_fs *c)
mutex_init(&wb->lock);
mutex_init(&wb->flush_lock);
wb->size = c->opts.btree_write_buffer_size;
+ INIT_WORK(&wb->work, bch2_write_buffer_flush_work);
wb->keys[0] = kvmalloc_array(wb->size, sizeof(*wb->keys[0]), GFP_KERNEL);
wb->keys[1] = kvmalloc_array(wb->size, sizeof(*wb->keys[1]), GFP_KERNEL);
diff --git a/fs/bcachefs/btree_write_buffer.h b/fs/bcachefs/btree_write_buffer.h
index 5663a0f941d2..032ce152daf5 100644
--- a/fs/bcachefs/btree_write_buffer.h
+++ b/fs/bcachefs/btree_write_buffer.h
@@ -8,6 +8,7 @@ int bch2_btree_write_buffer_flush(struct btree_trans *);
int bch2_write_buffer_key(struct bch_fs *, u64, unsigned,
enum btree_id, struct bkey_i *);
+void bch2_queue_btree_write_buffer_flush(struct bch_fs *);
void bch2_fs_btree_write_buffer_exit(struct bch_fs *);
int bch2_fs_btree_write_buffer_init(struct bch_fs *);
diff --git a/fs/bcachefs/btree_write_buffer_types.h b/fs/bcachefs/btree_write_buffer_types.h
index 14251b4ae990..8f3008ef2f0a 100644
--- a/fs/bcachefs/btree_write_buffer_types.h
+++ b/fs/bcachefs/btree_write_buffer_types.h
@@ -18,6 +18,7 @@ struct btree_write_buffer {
struct mutex lock;
struct mutex flush_lock;
struct journal_entry_pin journal_pin;
+ struct work_struct work;
size_t nr;
size_t size;
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
index f9a1c8a6a8e2..962f0648f701 100644
--- a/fs/bcachefs/journal_io.c
+++ b/fs/bcachefs/journal_io.c
@@ -1700,6 +1700,8 @@ static void bch2_journal_entries_postprocess(struct bch_fs *c, struct jset *jset
//pr_info("write_buffer %u - %zu", nr, c->btree_write_buffer.nr);
mutex_unlock(&c->btree_write_buffer.lock);
+
+ bch2_queue_btree_write_buffer_flush(c);
}
void bch2_journal_write(struct closure *cl)
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index 603749eb253e..48ee8f0e6ac9 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -215,7 +215,7 @@ enum opt_type {
x(btree_write_buffer_size, u32, \
OPT_FS|OPT_MOUNT, \
OPT_UINT(16, (1U << 20) - 1), \
- BCH2_NO_SB_OPT, 1U << 15, \
+ BCH2_NO_SB_OPT, 1U << 12, \
NULL, "Number of btree write buffer entries") \
x(gc_reserve_percent, u8, \
OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \