Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6.git] / block / scsi_ioctl.c
index dcd9c71fe8d3adddd115396f17d8644100ba3540..b3e210723a71f637605852b7d8136ef594af95d2 100644 (file)
@@ -226,7 +226,6 @@ static int sg_io(struct file *file, request_queue_t *q,
        unsigned long start_time;
        int writing = 0, ret = 0;
        struct request *rq;
-       struct bio *bio;
        char sense[SCSI_SENSE_BUFFERSIZE];
        unsigned char cmd[BLK_MAX_CDB];
 
@@ -258,30 +257,6 @@ static int sg_io(struct file *file, request_queue_t *q,
        if (!rq)
                return -ENOMEM;
 
-       if (hdr->iovec_count) {
-               const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
-               struct sg_iovec *iov;
-
-               iov = kmalloc(size, GFP_KERNEL);
-               if (!iov) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               if (copy_from_user(iov, hdr->dxferp, size)) {
-                       kfree(iov);
-                       ret = -EFAULT;
-                       goto out;
-               }
-
-               ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count);
-               kfree(iov);
-       } else if (hdr->dxfer_len)
-               ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
-
-       if (ret)
-               goto out;
-
        /*
         * fill in request structure
         */
@@ -294,7 +269,6 @@ static int sg_io(struct file *file, request_queue_t *q,
        rq->sense_len = 0;
 
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
-       bio = rq->bio;
 
        /*
         * bounce this after holding a reference to the original bio, it's
@@ -309,6 +283,31 @@ static int sg_io(struct file *file, request_queue_t *q,
        if (!rq->timeout)
                rq->timeout = BLK_DEFAULT_TIMEOUT;
 
+       if (hdr->iovec_count) {
+               const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
+               struct sg_iovec *iov;
+
+               iov = kmalloc(size, GFP_KERNEL);
+               if (!iov) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               if (copy_from_user(iov, hdr->dxferp, size)) {
+                       kfree(iov);
+                       ret = -EFAULT;
+                       goto out;
+               }
+
+               ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
+                                         hdr->dxfer_len);
+               kfree(iov);
+       } else if (hdr->dxfer_len)
+               ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
+
+       if (ret)
+               goto out;
+
        rq->retries = 0;
 
        start_time = jiffies;
@@ -339,7 +338,7 @@ static int sg_io(struct file *file, request_queue_t *q,
                        hdr->sb_len_wr = len;
        }
 
-       if (blk_rq_unmap_user(bio, hdr->dxfer_len))
+       if (blk_rq_unmap_user(rq))
                ret = -EFAULT;
 
        /* may not have succeeded, but output values written to control