Skip to content

Commit cddce01

Browse files
YongjiXieaxboe
authored andcommitted
nbd: Aovid double completion of a request
There is a race between iterating over requests in nbd_clear_que() and completing requests in recv_work(), which can lead to double completion of a request. To fix it, flush the recv worker before iterating over the requests and don't abort the completed request while iterating. Fixes: 96d97e1 ("nbd: clear_sock on netlink disconnect") Reported-by: Jiang Yadong <[email protected]> Signed-off-by: Xie Yongji <[email protected]> Reviewed-by: Josef Bacik <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 454bb67 commit cddce01

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

drivers/block/nbd.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,10 @@ static bool nbd_clear_req(struct request *req, void *data, bool reserved)
818818
{
819819
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
820820

821+
/* don't abort one completed request */
822+
if (blk_mq_request_completed(req))
823+
return true;
824+
821825
mutex_lock(&cmd->lock);
822826
cmd->status = BLK_STS_IOERR;
823827
mutex_unlock(&cmd->lock);
@@ -2004,15 +2008,19 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd)
20042008
{
20052009
mutex_lock(&nbd->config_lock);
20062010
nbd_disconnect(nbd);
2007-
nbd_clear_sock(nbd);
2008-
mutex_unlock(&nbd->config_lock);
2011+
sock_shutdown(nbd);
20092012
/*
20102013
* Make sure recv thread has finished, so it does not drop the last
20112014
* config ref and try to destroy the workqueue from inside the work
2012-
* queue.
2015+
* queue. And this also ensure that we can safely call nbd_clear_que()
2016+
* to cancel the inflight I/Os.
20132017
*/
20142018
if (nbd->recv_workq)
20152019
flush_workqueue(nbd->recv_workq);
2020+
nbd_clear_que(nbd);
2021+
nbd->task_setup = NULL;
2022+
mutex_unlock(&nbd->config_lock);
2023+
20162024
if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
20172025
&nbd->config->runtime_flags))
20182026
nbd_config_put(nbd);

0 commit comments

Comments
 (0)