All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: linux-kernel@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>,
	virtualization@lists.linux-foundation.org,
	john cooper <john.cooper@redhat.com>
Subject: [PATCH 3/4] virtio_blk: implement a request-based ID command, VIRTIO_BLK_T_GET_ID
Date: Wed, 30 Sep 2009 02:48:44 +0930	[thread overview]
Message-ID: <200909300248.44583.rusty@rustcorp.com.au> (raw)


This is fairly simple: we create a request pointing at the 1k kmalloc,
then just change the type so our do_req() knows to mark it as a GET_ID
for the server.

Seems to work here; the only issue is that the error didn't get passed
back from __blk_end_request_all to blk_execute_rq, so we set ->errors
to 1 on error.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jens Axboe <axboe@kernel.dk>
---
 drivers/block/virtio_blk.c |   66 +++++++++++++++++++++++++++++++++++----------
 include/linux/virtio_blk.h |    4 ++
 2 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -72,6 +72,8 @@ static void blk_done(struct virtqueue *v
 			vbr->req->sense_len = vbr->in_hdr.sense_len;
 			vbr->req->errors = vbr->in_hdr.errors;
 		}
+		if (blk_special_request(vbr->req))
+			vbr->req->errors = (error != 0);
 
 		__blk_end_request_all(vbr->req, error);
 		list_del(&vbr->list);
@@ -105,6 +107,11 @@ static bool do_req(struct request_queue 
 		vbr->out_hdr.sector = 0;
 		vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
 		break;
+	case REQ_TYPE_SPECIAL:
+		vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID;
+		vbr->out_hdr.sector = 0;
+		vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+		break;
 	case REQ_TYPE_LINUX_BLOCK:
 		if (req->cmd[0] == REQ_LB_OP_FLUSH) {
 			vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
@@ -201,29 +208,59 @@ struct virtio_blk_config_deprecated {
 	__u8 identify[VIRTIO_BLK_ID_BYTES];
 } __attribute__((packed));
 
-static int virtblk_identify(struct gendisk *disk, void *argp)
+static int virtblk_identify_deprecated(struct virtio_blk *vblk, void *opaque)
+{
+	return virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY,
+		offsetof(struct virtio_blk_config_deprecated, identify), opaque,
+		VIRTIO_BLK_ID_BYTES);
+}
+
+static int virtblk_get_id(struct virtio_blk *vblk, void *opaque)
+{
+	struct request *req;
+	struct bio *bio;
+
+	bio = bio_map_kern(vblk->disk->queue, opaque, VIRTIO_BLK_ID_BYTES,
+			   GFP_KERNEL);
+	if (IS_ERR(bio))
+		return PTR_ERR(bio);
+
+	req = blk_make_request(vblk->disk->queue, bio, GFP_KERNEL);
+	if (IS_ERR(req)) {
+		bio_put(bio);
+		return PTR_ERR(req);
+	}
+
+	/* This is actually a special request. */
+	req->cmd_type = REQ_TYPE_SPECIAL;
+	return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
+}
+
+static int virtblk_identify(struct gendisk *disk, void __user *argp)
 {
 	struct virtio_blk *vblk = disk->private_data;
 	void *opaque;
-	int err = -ENOMEM;
+	int err;
 
 	opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
 	if (!opaque)
-		goto out;
+		return -ENOMEM;
 
-	err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY,
-		offsetof(struct virtio_blk_config_deprecated, identify), opaque,
-		VIRTIO_BLK_ID_BYTES);
+	/* The modern way. */
+	if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_GET_ID))
+		err = virtblk_get_id(vblk, opaque);
+	/* The deprecated way. */
+	else if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_IDENTIFY))
+		err = virtblk_identify_deprecated(vblk, opaque);
+	/* No way. */
+	else
+		err = -ENOTTY;
 
-	if (err)
-		goto out_kfree;
+	if (!err)
+		if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
+			err = -EFAULT;
 
-	if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
-		err = -EFAULT;
-
-out_kfree:
 	kfree(opaque);
-out:
 	return err;
 }
 
@@ -460,7 +497,8 @@ 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, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
+	VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH,
+	VIRTIO_BLK_F_GET_ID
 };
 
 /*
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -15,6 +15,7 @@
 #define VIRTIO_BLK_F_SCSI	7	/* Supports scsi command passthru */
 #define VIRTIO_BLK_F_IDENTIFY	8	/* ATA IDENTIFY support (deprecated) */
 #define VIRTIO_BLK_F_FLUSH	9	/* Cache flush command support */
+#define VIRTIO_BLK_F_GET_ID	10	/* VIRTIO_BLK_T_GET_ID support */
 
 #define VIRTIO_BLK_ID_BYTES	(sizeof(__u16[256]))	/* IDENTIFY DATA */
 
@@ -65,6 +66,9 @@ struct virtio_blk_config {
 /* Cache flush command */
 #define VIRTIO_BLK_T_FLUSH	4
 
+/* Get ID command */
+#define VIRTIO_BLK_T_GET_ID	8
+
 /* Barrier before this op. */
 #define VIRTIO_BLK_T_BARRIER	0x80000000
 


             reply	other threads:[~2009-09-29 17:18 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-29 17:18 Rusty Russell [this message]
  -- strict thread matches above, loose matches on Subject: below --
2009-09-29 17:18 [PATCH 3/4] virtio_blk: implement a request-based ID command, VIRTIO_BLK_T_GET_ID Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200909300248.44583.rusty@rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=axboe@kernel.dk \
    --cc=john.cooper@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.