All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] virtio_blk: SG_IO passthru support
@ 2009-04-27  8:21 Christoph Hellwig
  2009-04-27 10:11 ` Christian Borntraeger
  2009-05-05  3:13 ` Rusty Russell
  0 siblings, 2 replies; 3+ messages in thread
From: Christoph Hellwig @ 2009-04-27  8:21 UTC (permalink / raw)
  To: Rusty Russell, Hannes Reinecke; +Cc: Christian Borntraeger, kvm

From: Hannes Reinecke <hare@suse.de>

Add support for SG_IO passthru to virtio_blk.  We add the scsi command
block after the normal outhdr, and the scsi inhdr with full status
information aswell as the sense buffer before the regular inhdr.

[hch: forward ported, added the VIRTIO_BLK_F_SCSI flags, some comments
 and tested the whole beast]


Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/drivers/block/virtio_blk.c
===================================================================
--- linux-2.6.orig/drivers/block/virtio_blk.c	2009-04-26 23:01:41.330960470 +0200
+++ linux-2.6/drivers/block/virtio_blk.c	2009-04-27 00:18:04.708076895 +0200
@@ -37,6 +37,7 @@ struct virtblk_req
 	struct list_head list;
 	struct request *req;
 	struct virtio_blk_outhdr out_hdr;
+	struct virtio_scsi_inhdr in_hdr;
 	u8 status;
 };
 
@@ -49,7 +50,9 @@ static void blk_done(struct virtqueue *v
 
 	spin_lock_irqsave(&vblk->lock, flags);
 	while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
+		unsigned int nr_bytes;
 		int error;
+
 		switch (vbr->status) {
 		case VIRTIO_BLK_S_OK:
 			error = 0;
@@ -62,7 +65,15 @@ static void blk_done(struct virtqueue *v
 			break;
 		}
 
-		__blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req));
+		if (blk_pc_request(vbr->req)) {
+			vbr->req->data_len = vbr->in_hdr.residual;
+			nr_bytes = vbr->in_hdr.data_len;
+			vbr->req->sense_len = vbr->in_hdr.sense_len;
+			vbr->req->errors = vbr->in_hdr.errors;
+		} else
+			nr_bytes = blk_rq_bytes(vbr->req);
+
+		__blk_end_request(vbr->req, error, nr_bytes);
 		list_del(&vbr->list);
 		mempool_free(vbr, vblk->pool);
 	}
@@ -74,7 +85,7 @@ static void blk_done(struct virtqueue *v
 static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
 		   struct request *req)
 {
-	unsigned long num, out, in;
+	unsigned long num, out = 0, in = 0;
 	struct virtblk_req *vbr;
 
 	vbr = mempool_alloc(vblk->pool, GFP_ATOMIC);
@@ -99,18 +110,36 @@ static bool do_req(struct request_queue 
 	if (blk_barrier_rq(vbr->req))
 		vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
 
-	sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
-	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
-	sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status));
-
-	if (rq_data_dir(vbr->req) == WRITE) {
-		vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
-		out = 1 + num;
-		in = 1;
-	} else {
-		vbr->out_hdr.type |= VIRTIO_BLK_T_IN;
-		out = 1;
-		in = 1 + num;
+	sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr));
+
+	/*
+	 * If this is a packet command we need a couple of additional headers.
+	 * Behind the normal outhdr we put a segment with the scsi command
+	 * block, and before the normal inhdr we put the sense data and the
+	 * inhdr with additional status information before the normal inhdr.
+	 */
+	if (blk_pc_request(vbr->req))
+		sg_set_buf(&vblk->sg[out++], vbr->req->cmd, vbr->req->cmd_len);
+
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg + out);
+
+	if (blk_pc_request(vbr->req)) {
+		sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96);
+		sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr,
+			   sizeof(vbr->in_hdr));
+	}
+
+	sg_set_buf(&vblk->sg[num + out + in++], &vbr->status,
+		   sizeof(vbr->status));
+
+	if (num) {
+		if (rq_data_dir(vbr->req) == WRITE) {
+			vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
+			out += num;
+		} else {
+			vbr->out_hdr.type |= VIRTIO_BLK_T_IN;
+			in += num;
+		}
 	}
 
 	if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) {
@@ -149,8 +178,16 @@ static void do_virtblk_request(struct re
 static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
 			 unsigned cmd, unsigned long data)
 {
-	return scsi_cmd_ioctl(bdev->bd_disk->queue,
-			      bdev->bd_disk, mode, cmd,
+	struct gendisk *disk = bdev->bd_disk;
+	struct virtio_blk *vblk = disk->private_data;
+
+	/*
+	 * Only allow the generic SCSI ioctls if the host can support it.
+	 */
+	if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
+		return -ENOIOCTLCMD;
+
+	return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
 			      (void __user *)data);
 }
 
@@ -356,6 +393,7 @@ static struct virtio_device_id id_table[
 static unsigned int features[] = {
 	VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
 	VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
+	VIRTIO_BLK_F_SCSI,
 };
 
 static struct virtio_driver virtio_blk = {
Index: linux-2.6/include/linux/virtio_blk.h
===================================================================
--- linux-2.6.orig/include/linux/virtio_blk.h	2009-04-26 23:01:41.341980169 +0200
+++ linux-2.6/include/linux/virtio_blk.h	2009-04-26 23:02:41.304977714 +0200
@@ -15,6 +15,7 @@
 #define VIRTIO_BLK_F_GEOMETRY	4	/* Legacy geometry available  */
 #define VIRTIO_BLK_F_RO		5	/* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE	6	/* Block size of disk is available*/
+#define VIRTIO_BLK_F_SCSI	7	/* Supports scsi command passthru */
 
 struct virtio_blk_config
 {
@@ -55,6 +56,14 @@ struct virtio_blk_outhdr
 	__u64 sector;
 };
 
+struct virtio_scsi_inhdr
+{
+	__u32 errors;
+	__u32 data_len;
+	__u32 sense_len;
+	__u32 residual;
+};
+
 /* And this is the final byte of the write scatter-gather list. */
 #define VIRTIO_BLK_S_OK		0
 #define VIRTIO_BLK_S_IOERR	1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] virtio_blk: SG_IO passthru support
  2009-04-27  8:21 [PATCH] virtio_blk: SG_IO passthru support Christoph Hellwig
@ 2009-04-27 10:11 ` Christian Borntraeger
  2009-05-05  3:13 ` Rusty Russell
  1 sibling, 0 replies; 3+ messages in thread
From: Christian Borntraeger @ 2009-04-27 10:11 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Rusty Russell, Hannes Reinecke, kvm

Am Monday 27 April 2009 10:21:21 schrieben Sie:
> From: Hannes Reinecke <hare@suse.de>
> 
> Add support for SG_IO passthru to virtio_blk.  We add the scsi command
> block after the normal outhdr, and the scsi inhdr with full status
> information aswell as the sense buffer before the regular inhdr.
> 
> [hch: forward ported, added the VIRTIO_BLK_F_SCSI flags, some comments
>  and tested the whole beast]

I like the VIRTIO_BLK_F_SCSI flag - it avoids some problems we had with an
earlier version. (I believe we found a solution, but this explicit check
looks much more reliable)
I gave this patch a short test with the kuli loader (s390 userspace). You can
consider the "VIRTIO_BLK_F_SCSI not available" case
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>

Christian



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] virtio_blk: SG_IO passthru support
  2009-04-27  8:21 [PATCH] virtio_blk: SG_IO passthru support Christoph Hellwig
  2009-04-27 10:11 ` Christian Borntraeger
@ 2009-05-05  3:13 ` Rusty Russell
  1 sibling, 0 replies; 3+ messages in thread
From: Rusty Russell @ 2009-05-05  3:13 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Hannes Reinecke, Christian Borntraeger, kvm

On Mon, 27 Apr 2009 05:51:21 pm Christoph Hellwig wrote:
> From: Hannes Reinecke <hare@suse.de>
> 
> Add support for SG_IO passthru to virtio_blk.  We add the scsi command
> block after the normal outhdr, and the scsi inhdr with full status
> information aswell as the sense buffer before the regular inhdr.
> 
> [hch: forward ported, added the VIRTIO_BLK_F_SCSI flags, some comments
>  and tested the whole beast]

Thanks Christoph, it's really nice to get a patch which is well thought-out,
thorough and intuitive.

Oh, and if you're bored, it'd be nice to have lguest support for at least
ejecting a CDROM.

Applied,
Rusty.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-05-05  4:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-27  8:21 [PATCH] virtio_blk: SG_IO passthru support Christoph Hellwig
2009-04-27 10:11 ` Christian Borntraeger
2009-05-05  3:13 ` Rusty Russell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.