aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/virtio_blk.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 12:23:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 12:23:45 -0400
commit1f0918d03ff4b5c94540c71ce889672abdbc2f4a (patch)
treeecee710444fb3405da55933501e339e10e4ac880 /drivers/block/virtio_blk.c
parent4266c97a3ef4604561a22212eb0eab8a3c338971 (diff)
parentca60a42c9be41c07ebcc2ec8c43dd1be53f147bf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: lguest: don't force VIRTIO_F_NOTIFY_ON_EMPTY lguest: cleanup for map_switcher() lguest: use PGDIR_SHIFT for PAE code to allow different PAGE_OFFSET lguest: use set_pte/set_pmd uniformly for real page table entries lguest: move panic notifier registration to its expected place. virtio_blk: add support for cache flush virtio: add virtio IDs file virtio: get rid of redundant VIRTIO_ID_9P definition virtio: make add_buf return capacity remaining virtio_pci: minor MSI-X cleanups
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r--drivers/block/virtio_blk.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index aa89fe45237d..43f19389647a 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -3,6 +3,7 @@
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/hdreg.h> 4#include <linux/hdreg.h>
5#include <linux/virtio.h> 5#include <linux/virtio.h>
6#include <linux/virtio_ids.h>
6#include <linux/virtio_blk.h> 7#include <linux/virtio_blk.h>
7#include <linux/scatterlist.h> 8#include <linux/scatterlist.h>
8 9
@@ -91,15 +92,26 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
91 return false; 92 return false;
92 93
93 vbr->req = req; 94 vbr->req = req;
94 if (blk_fs_request(vbr->req)) { 95 switch (req->cmd_type) {
96 case REQ_TYPE_FS:
95 vbr->out_hdr.type = 0; 97 vbr->out_hdr.type = 0;
96 vbr->out_hdr.sector = blk_rq_pos(vbr->req); 98 vbr->out_hdr.sector = blk_rq_pos(vbr->req);
97 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 99 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
98 } else if (blk_pc_request(vbr->req)) { 100 break;
101 case REQ_TYPE_BLOCK_PC:
99 vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; 102 vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
100 vbr->out_hdr.sector = 0; 103 vbr->out_hdr.sector = 0;
101 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 104 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
102 } else { 105 break;
106 case REQ_TYPE_LINUX_BLOCK:
107 if (req->cmd[0] == REQ_LB_OP_FLUSH) {
108 vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
109 vbr->out_hdr.sector = 0;
110 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
111 break;
112 }
113 /*FALLTHRU*/
114 default:
103 /* We don't put anything else in the queue. */ 115 /* We don't put anything else in the queue. */
104 BUG(); 116 BUG();
105 } 117 }
@@ -139,7 +151,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
139 } 151 }
140 } 152 }
141 153
142 if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) { 154 if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) {
143 mempool_free(vbr, vblk->pool); 155 mempool_free(vbr, vblk->pool);
144 return false; 156 return false;
145 } 157 }
@@ -199,6 +211,12 @@ out:
199 return err; 211 return err;
200} 212}
201 213
214static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
215{
216 req->cmd_type = REQ_TYPE_LINUX_BLOCK;
217 req->cmd[0] = REQ_LB_OP_FLUSH;
218}
219
202static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, 220static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
203 unsigned cmd, unsigned long data) 221 unsigned cmd, unsigned long data)
204{ 222{
@@ -337,7 +355,10 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
337 index++; 355 index++;
338 356
339 /* If barriers are supported, tell block layer that queue is ordered */ 357 /* If barriers are supported, tell block layer that queue is ordered */
340 if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) 358 if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
359 blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_DRAIN_FLUSH,
360 virtblk_prepare_flush);
361 else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
341 blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); 362 blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
342 363
343 /* If disk is read-only in the host, the guest should obey */ 364 /* If disk is read-only in the host, the guest should obey */
@@ -424,7 +445,7 @@ static struct virtio_device_id id_table[] = {
424static unsigned int features[] = { 445static unsigned int features[] = {
425 VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, 446 VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
426 VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, 447 VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
427 VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY 448 VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
428}; 449};
429 450
430/* 451/*