The DO_IT ioctl does a lot of things to handle the connection. This
patch splits the DO_IT ioctl routine into three functions
nbd_connection_start()/run()/stop(). This makes it easier to read and
allows other functions to call the same code. This patch prepares the
DO_IT code for nbd-root device.

Signed-off-by: Markus Pargmann <[email protected]>
---
 drivers/block/nbd.c | 146 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 91 insertions(+), 55 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 6bd7df2ff648..0ff6ebbec252 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -596,6 +596,95 @@ static void do_nbd_request(struct request_queue *q)
        }
 }
 
+static int nbd_connection_start(struct block_device *bdev,
+                               struct nbd_device *nbd)
+{
+       if (nbd->flags & NBD_FLAG_READ_ONLY)
+               set_device_ro(bdev, true);
+       if (nbd->flags & NBD_FLAG_SEND_TRIM)
+               queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
+       if (nbd->flags & NBD_FLAG_SEND_FLUSH)
+               blk_queue_flush(nbd->disk->queue, REQ_FLUSH);
+       else
+               blk_queue_flush(nbd->disk->queue, 0);
+       return 0;
+}
+
+static int nbd_connection_run(struct nbd_device *nbd)
+{
+       struct task_struct *thread;
+       int error;
+
+       thread = kthread_run(nbd_thread, nbd, "%s", nbd->disk->disk_name);
+       if (IS_ERR(thread)) {
+               mutex_lock(&nbd->tx_lock);
+               return PTR_ERR(thread);
+       }
+
+       error = nbd_do_it(nbd);
+
+       kthread_stop(thread);
+
+       return error;
+}
+
+/*
+ * Call with tx_lock held
+ */
+static int nbd_connection_stop(struct block_device *bdev,
+                              struct nbd_device *nbd)
+{
+       struct socket *sock;
+
+       sock_shutdown(nbd, 0);
+       sock = nbd->sock;
+       nbd->sock = NULL;
+       nbd_clear_que(nbd);
+       dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
+       kill_bdev(bdev);
+       queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
+       set_device_ro(bdev, false);
+       if (sock)
+               sockfd_put(sock);
+
+       nbd->flags = 0;
+       nbd->bytesize = 0;
+       bdev->bd_inode->i_size = 0;
+       set_capacity(nbd->disk, 0);
+
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
+       if (nbd->disconnect) /* user requested, ignore socket errors */
+               return 0;
+
+       return nbd->harderror;
+}
+
+/*
+ * Call with tx_lock held
+ */
+static int nbd_connection_handler(struct block_device *bdev,
+                                 struct nbd_device *nbd)
+{
+       int error;
+
+       mutex_unlock(&nbd->tx_lock);
+
+       error = nbd_connection_start(bdev, nbd);
+       if (error)
+               return error;
+
+       error = nbd_connection_run(nbd);
+
+       mutex_lock(&nbd->tx_lock);
+       if (error)
+               return error;
+
+       error = nbd_connection_stop(bdev, nbd);
+
+       return error;
+}
+
 /* Must be called with tx_lock held */
 
 static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
@@ -684,61 +773,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct 
nbd_device *nbd,
                set_capacity(nbd->disk, nbd->bytesize >> 9);
                return 0;
 
-       case NBD_DO_IT: {
-               struct task_struct *thread;
-               struct socket *sock;
-               int error;
-
-               if (nbd->pid)
-                       return -EBUSY;
-               if (!nbd->sock)
-                       return -EINVAL;
-
-               mutex_unlock(&nbd->tx_lock);
-
-               if (nbd->flags & NBD_FLAG_READ_ONLY)
-                       set_device_ro(bdev, true);
-               if (nbd->flags & NBD_FLAG_SEND_TRIM)
-                       queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
-                               nbd->disk->queue);
-               if (nbd->flags & NBD_FLAG_SEND_FLUSH)
-                       blk_queue_flush(nbd->disk->queue, REQ_FLUSH);
-               else
-                       blk_queue_flush(nbd->disk->queue, 0);
-
-               thread = kthread_run(nbd_thread, nbd, "%s",
-                                    nbd->disk->disk_name);
-               if (IS_ERR(thread)) {
-                       mutex_lock(&nbd->tx_lock);
-                       return PTR_ERR(thread);
-               }
-
-               error = nbd_do_it(nbd);
-               kthread_stop(thread);
-
-               mutex_lock(&nbd->tx_lock);
-               if (error)
-                       return error;
-               sock_shutdown(nbd, 0);
-               sock = nbd->sock;
-               nbd->sock = NULL;
-               nbd_clear_que(nbd);
-               dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
-               kill_bdev(bdev);
-               queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
-               set_device_ro(bdev, false);
-               if (sock)
-                       sockfd_put(sock);
-               nbd->flags = 0;
-               nbd->bytesize = 0;
-               bdev->bd_inode->i_size = 0;
-               set_capacity(nbd->disk, 0);
-               if (max_part > 0)
-                       ioctl_by_bdev(bdev, BLKRRPART, 0);
-               if (nbd->disconnect) /* user requested, ignore socket errors */
-                       return 0;
-               return nbd->harderror;
-       }
+       case NBD_DO_IT:
+               return nbd_connection_handler(bdev, nbd);
 
        case NBD_CLEAR_QUE:
                /*
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to