提交 4cb2ea28 编写于 作者: J john cooper 提交者: Rusty Russell

Add virtio disk identification support

Add virtio-blk device id (s/n) support via virtio request.
Signed-off-by: Njohn cooper <john.cooper@redhat.com>
Signed-off-by: NRusty Russell <rusty@rustcorp.com.au>
上级 537b60d1
...@@ -70,6 +70,8 @@ static void blk_done(struct virtqueue *vq) ...@@ -70,6 +70,8 @@ static void blk_done(struct virtqueue *vq)
vbr->req->sense_len = vbr->in_hdr.sense_len; vbr->req->sense_len = vbr->in_hdr.sense_len;
vbr->req->errors = vbr->in_hdr.errors; 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); __blk_end_request_all(vbr->req, error);
list_del(&vbr->list); list_del(&vbr->list);
...@@ -103,6 +105,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, ...@@ -103,6 +105,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
vbr->out_hdr.sector = 0; vbr->out_hdr.sector = 0;
vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
break; 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: case REQ_TYPE_LINUX_BLOCK:
if (req->cmd[0] == REQ_LB_OP_FLUSH) { if (req->cmd[0] == REQ_LB_OP_FLUSH) {
vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
...@@ -189,6 +196,29 @@ static void virtblk_prepare_flush(struct request_queue *q, struct request *req) ...@@ -189,6 +196,29 @@ static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
req->cmd[0] = REQ_LB_OP_FLUSH; 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, static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long data) unsigned cmd, unsigned long data)
{ {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */ #define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */
#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
struct virtio_blk_config { struct virtio_blk_config {
/* The capacity (in 512-byte sectors). */ /* The capacity (in 512-byte sectors). */
__u64 capacity; __u64 capacity;
...@@ -67,6 +69,9 @@ struct virtio_blk_config { ...@@ -67,6 +69,9 @@ struct virtio_blk_config {
/* Cache flush command */ /* Cache flush command */
#define VIRTIO_BLK_T_FLUSH 4 #define VIRTIO_BLK_T_FLUSH 4
/* Get device ID command */
#define VIRTIO_BLK_T_GET_ID 8
/* Barrier before this op. */ /* Barrier before this op. */
#define VIRTIO_BLK_T_BARRIER 0x80000000 #define VIRTIO_BLK_T_BARRIER 0x80000000
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册