nbd: Fix signal handling
authorBart Van Assche <bvanassche@acm.org>
Fri, 10 May 2024 20:23:13 +0000 (13:23 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jun 2024 11:49:14 +0000 (13:49 +0200)
[ Upstream commit e56d4b633fffea9510db468085bed0799cba4ecd ]

Both nbd_send_cmd() and nbd_handle_cmd() return either a negative error
number or a positive blk_status_t value. nbd_queue_rq() converts these
return values into a blk_status_t value. There is a bug in the conversion
code: if nbd_send_cmd() returns BLK_STS_RESOURCE, nbd_queue_rq() should
return BLK_STS_RESOURCE instead of BLK_STS_OK. Fix this, move the
conversion code into nbd_handle_cmd() and fix the remaining sparse warnings.

This patch fixes the following sparse warnings:

drivers/block/nbd.c:673:32: warning: incorrect type in return expression (different base types)
drivers/block/nbd.c:673:32:    expected int
drivers/block/nbd.c:673:32:    got restricted blk_status_t [usertype]
drivers/block/nbd.c:714:48: warning: incorrect type in return expression (different base types)
drivers/block/nbd.c:714:48:    expected int
drivers/block/nbd.c:714:48:    got restricted blk_status_t [usertype]
drivers/block/nbd.c:1120:21: warning: incorrect type in assignment (different base types)
drivers/block/nbd.c:1120:21:    expected int [assigned] ret
drivers/block/nbd.c:1120:21:    got restricted blk_status_t [usertype]
drivers/block/nbd.c:1125:16: warning: incorrect type in return expression (different base types)
drivers/block/nbd.c:1125:16:    expected restricted blk_status_t
drivers/block/nbd.c:1125:16:    got int [assigned] ret

Cc: Christoph Hellwig <hch@lst.de>
Cc: Josef Bacik <jbacik@fb.com>
Cc: Yu Kuai <yukuai3@huawei.com>
Cc: Markus Pargmann <mpa@pengutronix.de>
Fixes: fc17b6534eb8 ("blk-mq: switch ->queue_rq return value to blk_status_t")
Cc: stable@vger.kernel.org
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20240510202313.25209-6-bvanassche@acm.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/block/nbd.c

index a906674f71147bed85fe8bbad6a53172c31461a3..1089dc646b80825d59174977417e3baa416bc3b7 100644 (file)
@@ -569,6 +569,10 @@ static inline int was_interrupted(int result)
        return result == -ERESTARTSYS || result == -EINTR;
 }
 
+/*
+ * Returns BLK_STS_RESOURCE if the caller should retry after a delay. Returns
+ * -EAGAIN if the caller should requeue @cmd. Returns -EIO if sending failed.
+ */
 static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 {
        struct request *req = blk_mq_rq_from_pdu(cmd);
@@ -652,7 +656,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
                                nsock->sent = sent;
                        }
                        set_bit(NBD_CMD_REQUEUED, &cmd->flags);
-                       return BLK_STS_RESOURCE;
+                       return (__force int)BLK_STS_RESOURCE;
                }
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                        "Send control failed (result %d)\n", result);
@@ -693,7 +697,7 @@ send_pages:
                                        nsock->pending = req;
                                        nsock->sent = sent;
                                        set_bit(NBD_CMD_REQUEUED, &cmd->flags);
-                                       return BLK_STS_RESOURCE;
+                                       return (__force int)BLK_STS_RESOURCE;
                                }
                                dev_err(disk_to_dev(nbd->disk),
                                        "Send data failed (result %d)\n",
@@ -990,7 +994,7 @@ static int wait_for_reconnect(struct nbd_device *nbd)
        return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags);
 }
 
-static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
+static blk_status_t nbd_handle_cmd(struct nbd_cmd *cmd, int index)
 {
        struct request *req = blk_mq_rq_from_pdu(cmd);
        struct nbd_device *nbd = cmd->nbd;
@@ -1004,14 +1008,14 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
        if (!config) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Socks array is empty\n");
-               return -EINVAL;
+               return BLK_STS_IOERR;
        }
 
        if (index >= config->num_connections) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Attempted send on invalid socket\n");
                nbd_config_put(nbd);
-               return -EINVAL;
+               return BLK_STS_IOERR;
        }
        cmd->status = BLK_STS_OK;
 again:
@@ -1034,7 +1038,7 @@ again:
                         */
                        sock_shutdown(nbd);
                        nbd_config_put(nbd);
-                       return -EIO;
+                       return BLK_STS_IOERR;
                }
                goto again;
        }
@@ -1047,7 +1051,7 @@ again:
        blk_mq_start_request(req);
        if (unlikely(nsock->pending && nsock->pending != req)) {
                nbd_requeue_cmd(cmd);
-               ret = 0;
+               ret = BLK_STS_OK;
                goto out;
        }
        /*
@@ -1066,19 +1070,19 @@ again:
                                    "Request send failed, requeueing\n");
                nbd_mark_nsock_dead(nbd, nsock, 1);
                nbd_requeue_cmd(cmd);
-               ret = 0;
+               ret = BLK_STS_OK;
        }
 out:
        mutex_unlock(&nsock->tx_lock);
        nbd_config_put(nbd);
-       return ret;
+       return ret < 0 ? BLK_STS_IOERR : (__force blk_status_t)ret;
 }
 
 static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
                        const struct blk_mq_queue_data *bd)
 {
        struct nbd_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
-       int ret;
+       blk_status_t ret;
 
        /*
         * Since we look at the bio's to send the request over the network we
@@ -1098,10 +1102,6 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
         * appropriate.
         */
        ret = nbd_handle_cmd(cmd, hctx->queue_num);
-       if (ret < 0)
-               ret = BLK_STS_IOERR;
-       else if (!ret)
-               ret = BLK_STS_OK;
        mutex_unlock(&cmd->lock);
 
        return ret;