nbd: don't start req until after the dead connection logic
[linux-block.git] / drivers / block / nbd.c
index 2aa87cbdede0ed19b77c8e4aaffea2c2d8146758..95cab69d9c8be14a27206a96dc451f41add31cda 100644 (file)
@@ -289,15 +289,6 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
                cmd->status = BLK_STS_TIMEOUT;
                return BLK_EH_HANDLED;
        }
-
-       /* If we are waiting on our dead timer then we could get timeout
-        * callbacks for our request.  For this we just want to reset the timer
-        * and let the queue side take care of everything.
-        */
-       if (!completion_done(&cmd->send_complete)) {
-               nbd_config_put(nbd);
-               return BLK_EH_RESET_TIMER;
-       }
        config = nbd->config;
 
        if (config->num_connections > 1) {
@@ -715,9 +706,9 @@ static int wait_for_reconnect(struct nbd_device *nbd)
                return 0;
        if (test_bit(NBD_DISCONNECTED, &config->runtime_flags))
                return 0;
-       wait_event_interruptible_timeout(config->conn_wait,
-                                        atomic_read(&config->live_connections),
-                                        config->dead_conn_timeout);
+       wait_event_timeout(config->conn_wait,
+                          atomic_read(&config->live_connections),
+                          config->dead_conn_timeout);
        return atomic_read(&config->live_connections);
 }
 
@@ -732,6 +723,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
        if (!refcount_inc_not_zero(&nbd->config_refs)) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Socks array is empty\n");
+               blk_mq_start_request(req);
                return -EINVAL;
        }
        config = nbd->config;
@@ -740,6 +732,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
                dev_err_ratelimited(disk_to_dev(nbd->disk),
                                    "Attempted send on invalid socket\n");
                nbd_config_put(nbd);
+               blk_mq_start_request(req);
                return -EINVAL;
        }
        cmd->status = BLK_STS_OK;
@@ -763,6 +756,7 @@ again:
                         */
                        sock_shutdown(nbd);
                        nbd_config_put(nbd);
+                       blk_mq_start_request(req);
                        return -EIO;
                }
                goto again;
@@ -773,6 +767,7 @@ again:
         * here so that it gets put _after_ the request that is already on the
         * dispatch list.
         */
+       blk_mq_start_request(req);
        if (unlikely(nsock->pending && nsock->pending != req)) {
                blk_mq_requeue_request(req, true);
                ret = 0;
@@ -785,10 +780,10 @@ again:
        ret = nbd_send_cmd(nbd, cmd, index);
        if (ret == -EAGAIN) {
                dev_err_ratelimited(disk_to_dev(nbd->disk),
-                                   "Request send failed trying another connection\n");
+                                   "Request send failed, requeueing\n");
                nbd_mark_nsock_dead(nbd, nsock, 1);
-               mutex_unlock(&nsock->tx_lock);
-               goto again;
+               blk_mq_requeue_request(req, true);
+               ret = 0;
        }
 out:
        mutex_unlock(&nsock->tx_lock);
@@ -812,7 +807,6 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
         * done sending everything over the wire.
         */
        init_completion(&cmd->send_complete);
-       blk_mq_start_request(bd->rq);
 
        /* We can be called directly from the user space process, which means we
         * could possibly have signals pending so our sendmsg will fail.  In
@@ -1194,6 +1188,12 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
+       /* The block layer will pass back some non-nbd ioctls in case we have
+        * special handling for them, but we don't so just return an error.
+        */
+       if (_IOC_TYPE(cmd) != 0xab)
+               return -EINVAL;
+
        mutex_lock(&nbd->config_lock);
 
        /* Don't allow ioctl operations on a nbd device that was created with