diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index a9ac68c17533..770b26f28c75 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -580,6 +580,8 @@ struct bch_fs { struct mutex btree_interior_update_lock; struct closure_waitlist btree_interior_update_wait; + mempool_t btree_iters_pool; + struct workqueue_struct *wq; /* copygc needs its own workqueue for index updates.. */ struct workqueue_struct *copygc_wq; diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index ae19ba125a71..6cde68537c3e 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -1648,10 +1648,7 @@ static int btree_trans_realloc_iters(struct btree_trans *trans) bch2_trans_unlock(trans); - new_iters = kmalloc(sizeof(struct btree_iter) * BTREE_ITER_MAX, - GFP_NOFS); - if (!new_iters) - return -ENOMEM; + new_iters = mempool_alloc(&trans->c->btree_iters_pool, GFP_NOFS); memcpy(new_iters, trans->iters, sizeof(struct btree_iter) * trans->nr_iters); @@ -1679,12 +1676,10 @@ static int btree_trans_realloc_iters(struct btree_trans *trans) return 0; } -int bch2_trans_preload_iters(struct btree_trans *trans) +void bch2_trans_preload_iters(struct btree_trans *trans) { - if (trans->iters != trans->iters_onstack) - return 0; - - return btree_trans_realloc_iters(trans); + if (trans->iters == trans->iters_onstack) + btree_trans_realloc_iters(trans); } static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans, @@ -1868,7 +1863,7 @@ int bch2_trans_exit(struct btree_trans *trans) kfree(trans->mem); if (trans->iters != trans->iters_onstack) - kfree(trans->iters); + mempool_free(trans->iters, &trans->c->btree_iters_pool); trans->mem = (void *) 0x1; trans->iters = (void *) 0x1; return ret; diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 1667ba448a18..63ff89644fe4 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -270,7 +270,7 @@ static inline int btree_iter_err(struct bkey_s_c k) /* new multiple iterator interface: */ -int bch2_trans_preload_iters(struct btree_trans *); +void bch2_trans_preload_iters(struct btree_trans *); void bch2_trans_iter_free(struct btree_trans *, struct btree_iter *); diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 50e310fea4cf..33fff198858a 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -398,7 +398,7 @@ static int check_dirents(struct bch_fs *c) bch2_trans_init(&trans, c); - BUG_ON(bch2_trans_preload_iters(&trans)); + bch2_trans_preload_iters(&trans); iter = bch2_trans_get_iter(&trans, BTREE_ID_DIRENTS, POS(BCACHEFS_ROOT_INO, 0), 0); @@ -539,7 +539,7 @@ static int check_xattrs(struct bch_fs *c) bch2_trans_init(&trans, c); - BUG_ON(bch2_trans_preload_iters(&trans)); + bch2_trans_preload_iters(&trans); iter = bch2_trans_get_iter(&trans, BTREE_ID_XATTRS, POS(BCACHEFS_ROOT_INO, 0), 0); diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index e44bc95d8deb..63e4d97d15d7 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -372,6 +372,7 @@ static void bch2_fs_free(struct bch_fs *c) bch2_fs_compress_exit(c); percpu_free_rwsem(&c->usage_lock); free_percpu(c->usage_percpu); + mempool_exit(&c->btree_iters_pool); mempool_exit(&c->btree_bounce_pool); bioset_exit(&c->btree_bio); mempool_exit(&c->btree_interior_update_pool); @@ -600,6 +601,8 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) percpu_init_rwsem(&c->usage_lock) || mempool_init_kvpmalloc_pool(&c->btree_bounce_pool, 1, btree_bytes(c)) || + mempool_init_kmalloc_pool(&c->btree_iters_pool, 1, + sizeof(struct btree_iter) * BTREE_ITER_MAX) || bch2_io_clock_init(&c->io_clock[READ]) || bch2_io_clock_init(&c->io_clock[WRITE]) || bch2_fs_journal_init(&c->journal) ||