Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcachefs: Split out btree_node_rewrite_worker

This fixes a deadlock due to using btree_interior_update_worker for non
interior updates - async btree node rewrites were blocking, and then
blocking other interior updates.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+11 -2
+2
fs/bcachefs/bcachefs.h
··· 849 849 struct workqueue_struct *btree_interior_update_worker; 850 850 struct work_struct btree_interior_update_work; 851 851 852 + struct workqueue_struct *btree_node_rewrite_worker; 853 + 852 854 struct list_head pending_node_rewrites; 853 855 struct mutex pending_node_rewrites_lock; 854 856
+9 -2
fs/bcachefs/btree_update_interior.c
··· 2161 2161 bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite); 2162 2162 } 2163 2163 2164 - queue_work(c->btree_interior_update_worker, &a->work); 2164 + queue_work(c->btree_node_rewrite_worker, &a->work); 2165 2165 } 2166 2166 2167 2167 void bch2_do_pending_node_rewrites(struct bch_fs *c) ··· 2173 2173 list_del(&a->list); 2174 2174 2175 2175 bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite); 2176 - queue_work(c->btree_interior_update_worker, &a->work); 2176 + queue_work(c->btree_node_rewrite_worker, &a->work); 2177 2177 } 2178 2178 mutex_unlock(&c->pending_node_rewrites_lock); 2179 2179 } ··· 2510 2510 2511 2511 void bch2_fs_btree_interior_update_exit(struct bch_fs *c) 2512 2512 { 2513 + if (c->btree_node_rewrite_worker) 2514 + destroy_workqueue(c->btree_node_rewrite_worker); 2513 2515 if (c->btree_interior_update_worker) 2514 2516 destroy_workqueue(c->btree_interior_update_worker); 2515 2517 mempool_exit(&c->btree_interior_update_pool); ··· 2534 2532 c->btree_interior_update_worker = 2535 2533 alloc_workqueue("btree_update", WQ_UNBOUND|WQ_MEM_RECLAIM, 8); 2536 2534 if (!c->btree_interior_update_worker) 2535 + return -BCH_ERR_ENOMEM_btree_interior_update_worker_init; 2536 + 2537 + c->btree_node_rewrite_worker = 2538 + alloc_ordered_workqueue("btree_node_rewrite", WQ_UNBOUND); 2539 + if (!c->btree_node_rewrite_worker) 2537 2540 return -BCH_ERR_ENOMEM_btree_interior_update_worker_init; 2538 2541 2539 2542 if (mempool_init_kmalloc_pool(&c->btree_interior_update_pool, 1,