diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-02-20 17:34:26 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-03-17 10:35:43 -0400 |
commit | 611e7945529430e37f99df4e1e2678904c6f4041 (patch) | |
tree | 076e9aa1e77e4697e0413b9d5c79d199be680aa8 /fs/bcachefs | |
parent | c36a644c565769dac853d4e45479256fe7b6050c (diff) |
Diffstat (limited to 'fs/bcachefs')
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_write_buffer.c | 34 | ||||
-rw-r--r-- | fs/bcachefs/btree_write_buffer.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_write_buffer_types.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/journal_io.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/opts.h | 2 |
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, \ |