@@ -260,7 +260,7 @@ static void nbd_dev_remove(struct nbd_device *nbd)
260
260
mutex_lock (& nbd_index_mutex );
261
261
idr_remove (& nbd_index_idr , nbd -> index );
262
262
mutex_unlock (& nbd_index_mutex );
263
-
263
+ destroy_workqueue ( nbd -> recv_workq );
264
264
kfree (nbd );
265
265
}
266
266
@@ -1319,10 +1319,6 @@ static void nbd_config_put(struct nbd_device *nbd)
1319
1319
kfree (nbd -> config );
1320
1320
nbd -> config = NULL ;
1321
1321
1322
- if (nbd -> recv_workq )
1323
- destroy_workqueue (nbd -> recv_workq );
1324
- nbd -> recv_workq = NULL ;
1325
-
1326
1322
nbd -> tag_set .timeout = 0 ;
1327
1323
nbd -> disk -> queue -> limits .discard_granularity = 0 ;
1328
1324
nbd -> disk -> queue -> limits .discard_alignment = 0 ;
@@ -1351,14 +1347,6 @@ static int nbd_start_device(struct nbd_device *nbd)
1351
1347
return - EINVAL ;
1352
1348
}
1353
1349
1354
- nbd -> recv_workq = alloc_workqueue ("knbd%d-recv" ,
1355
- WQ_MEM_RECLAIM | WQ_HIGHPRI |
1356
- WQ_UNBOUND , 0 , nbd -> index );
1357
- if (!nbd -> recv_workq ) {
1358
- dev_err (disk_to_dev (nbd -> disk ), "Could not allocate knbd recv work queue.\n" );
1359
- return - ENOMEM ;
1360
- }
1361
-
1362
1350
blk_mq_update_nr_hw_queues (& nbd -> tag_set , config -> num_connections );
1363
1351
nbd -> pid = task_pid_nr (current );
1364
1352
@@ -1784,6 +1772,15 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
1784
1772
}
1785
1773
nbd -> disk = disk ;
1786
1774
1775
+ nbd -> recv_workq = alloc_workqueue ("nbd%d-recv" ,
1776
+ WQ_MEM_RECLAIM | WQ_HIGHPRI |
1777
+ WQ_UNBOUND , 0 , nbd -> index );
1778
+ if (!nbd -> recv_workq ) {
1779
+ dev_err (disk_to_dev (nbd -> disk ), "Could not allocate knbd recv work queue.\n" );
1780
+ err = - ENOMEM ;
1781
+ goto out_err_disk ;
1782
+ }
1783
+
1787
1784
/*
1788
1785
* Tell the block layer that we are not a rotational device
1789
1786
*/
@@ -1814,7 +1811,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
1814
1811
disk -> first_minor = index << part_shift ;
1815
1812
if (disk -> first_minor < index || disk -> first_minor > MINORMASK ) {
1816
1813
err = - EINVAL ;
1817
- goto out_err_disk ;
1814
+ goto out_free_work ;
1818
1815
}
1819
1816
1820
1817
disk -> minors = 1 << part_shift ;
@@ -1823,7 +1820,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
1823
1820
sprintf (disk -> disk_name , "nbd%d" , index );
1824
1821
err = add_disk (disk );
1825
1822
if (err )
1826
- goto out_err_disk ;
1823
+ goto out_free_work ;
1827
1824
1828
1825
/*
1829
1826
* Now publish the device.
@@ -1832,6 +1829,8 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
1832
1829
nbd_total_devices ++ ;
1833
1830
return nbd ;
1834
1831
1832
+ out_free_work :
1833
+ destroy_workqueue (nbd -> recv_workq );
1835
1834
out_err_disk :
1836
1835
blk_cleanup_disk (disk );
1837
1836
out_free_idr :
@@ -2087,13 +2086,10 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd)
2087
2086
nbd_disconnect (nbd );
2088
2087
sock_shutdown (nbd );
2089
2088
/*
2090
- * Make sure recv thread has finished, so it does not drop the last
2091
- * config ref and try to destroy the workqueue from inside the work
2092
- * queue. And this also ensure that we can safely call nbd_clear_que()
2089
+ * Make sure recv thread has finished, we can safely call nbd_clear_que()
2093
2090
* to cancel the inflight I/Os.
2094
2091
*/
2095
- if (nbd -> recv_workq )
2096
- flush_workqueue (nbd -> recv_workq );
2092
+ flush_workqueue (nbd -> recv_workq );
2097
2093
nbd_clear_que (nbd );
2098
2094
nbd -> task_setup = NULL ;
2099
2095
mutex_unlock (& nbd -> config_lock );
0 commit comments