Patchwork [3/4] Add virtio disk identification support

login
register
mail settings
Submitter john cooper
Date March 25, 2010, 5:33 a.m.
Message ID <4BAAF5AD.3030608@redhat.com>
Download mbox | patch
Permalink /patch/48494/
State New
Headers show

Comments

john cooper - March 25, 2010, 5:33 a.m.
Add virtio-blk device id (s/n) support via virtio request.

Signed-off-by: john cooper <john.cooper@redhat.com>
---

Patch

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 3c64af0..cd66806 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -69,6 +69,8 @@  static void blk_done(struct virtqueue *vq)
 			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);
@@ -102,6 +104,11 @@  static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
 		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;
@@ -188,6 +195,30 @@  static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
 	req->cmd[0] = REQ_LB_OP_FLUSH;
 }
 
+/* return id (s/n) string for *disk to *id_str
+ */
+static int virtblk_get_id(struct gendisk *disk, char *id_str)
+{
+	struct virtio_blk *vblk = disk->private_data;
+	struct request *req;
+	struct bio *bio;
+
+	bio = bio_map_kern(vblk->disk->queue, id_str, 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);
+	}
+
+	req->cmd_type = REQ_TYPE_SPECIAL;
+	return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
+}
+
 static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
 			 unsigned cmd, unsigned long data)
 {
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
index e52029e..167720d 100644
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -17,6 +17,8 @@ 
 #define VIRTIO_BLK_F_FLUSH	9	/* Cache flush command support */
 #define VIRTIO_BLK_F_TOPOLOGY	10	/* Topology information is available */
 
+#define VIRTIO_BLK_ID_BYTES	20	/* ID string length */
+
 struct virtio_blk_config {
 	/* The capacity (in 512-byte sectors). */
 	__u64 capacity;
@@ -67,6 +69,9 @@  struct virtio_blk_config {
 /* Cache flush command */
 #define VIRTIO_BLK_T_FLUSH	4
 
+/* Get device ID command */
+#define VIRTIO_BLK_T_GET_ID    8
+
 /* Barrier before this op. */
 #define VIRTIO_BLK_T_BARRIER	0x80000000