aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:22:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:22:52 -0400
commit1756ac3d3c41341297ea25b818b7fce505bb2a9a (patch)
tree96382220afbb82fd5c576c4c08b3c3e13282851f /drivers/block
parent98edb6ca4174f17a64890a02f44c211c8b44fb3c (diff)
parent0643e4c6e4fd67778fa886a89e6ec2320e0ff4d3 (diff)
Merge branch 'virtio' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* 'virtio' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: (27 commits) drivers/char: Eliminate use after free virtio: console: Accept console size along with resize control message virtio: console: Store each console's size in the console structure virtio: console: Resize console port 0 on config intr only if multiport is off virtio: console: Add support for nonblocking write()s virtio: console: Rename wait_is_over() to will_read_block() virtio: console: Don't always create a port 0 if using multiport virtio: console: Use a control message to add ports virtio: console: Move code around for future patches virtio: console: Remove config work handler virtio: console: Don't call hvc_remove() on unplugging console ports virtio: console: Return -EPIPE to hvc_console if we lost the connection virtio: console: Let host know of port or device add failures virtio: console: Add a __send_control_msg() that can send messages without a valid port virtio: Revert "virtio: disable multiport console support." virtio: add_buf_gfp trans_virtio: use virtqueue_xxx wrappers virtio-rng: use virtqueue_xxx wrappers virtio_ring: remove a level of indirection virtio_net: use virtqueue_xxx wrappers ... Fix up conflicts in drivers/net/virtio_net.c due to new virtqueue_xxx wrappers changes conflicting with some other cleanups.
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/virtio_blk.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 2138a7ae050c..83fa09a836ca 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -50,7 +50,7 @@ static void blk_done(struct virtqueue *vq)
50 unsigned long flags; 50 unsigned long flags;
51 51
52 spin_lock_irqsave(&vblk->lock, flags); 52 spin_lock_irqsave(&vblk->lock, flags);
53 while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { 53 while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) {
54 int error; 54 int error;
55 55
56 switch (vbr->status) { 56 switch (vbr->status) {
@@ -70,6 +70,8 @@ static void blk_done(struct virtqueue *vq)
70 vbr->req->sense_len = vbr->in_hdr.sense_len; 70 vbr->req->sense_len = vbr->in_hdr.sense_len;
71 vbr->req->errors = vbr->in_hdr.errors; 71 vbr->req->errors = vbr->in_hdr.errors;
72 } 72 }
73 if (blk_special_request(vbr->req))
74 vbr->req->errors = (error != 0);
73 75
74 __blk_end_request_all(vbr->req, error); 76 __blk_end_request_all(vbr->req, error);
75 list_del(&vbr->list); 77 list_del(&vbr->list);
@@ -103,6 +105,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
103 vbr->out_hdr.sector = 0; 105 vbr->out_hdr.sector = 0;
104 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 106 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
105 break; 107 break;
108 case REQ_TYPE_SPECIAL:
109 vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID;
110 vbr->out_hdr.sector = 0;
111 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
112 break;
106 case REQ_TYPE_LINUX_BLOCK: 113 case REQ_TYPE_LINUX_BLOCK:
107 if (req->cmd[0] == REQ_LB_OP_FLUSH) { 114 if (req->cmd[0] == REQ_LB_OP_FLUSH) {
108 vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; 115 vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
@@ -151,7 +158,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
151 } 158 }
152 } 159 }
153 160
154 if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { 161 if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) {
155 mempool_free(vbr, vblk->pool); 162 mempool_free(vbr, vblk->pool);
156 return false; 163 return false;
157 } 164 }
@@ -180,7 +187,7 @@ static void do_virtblk_request(struct request_queue *q)
180 } 187 }
181 188
182 if (issued) 189 if (issued)
183 vblk->vq->vq_ops->kick(vblk->vq); 190 virtqueue_kick(vblk->vq);
184} 191}
185 192
186static void virtblk_prepare_flush(struct request_queue *q, struct request *req) 193static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
@@ -189,12 +196,45 @@ static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
189 req->cmd[0] = REQ_LB_OP_FLUSH; 196 req->cmd[0] = REQ_LB_OP_FLUSH;
190} 197}
191 198
199/* return id (s/n) string for *disk to *id_str
200 */
201static int virtblk_get_id(struct gendisk *disk, char *id_str)
202{
203 struct virtio_blk *vblk = disk->private_data;
204 struct request *req;
205 struct bio *bio;
206
207 bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES,
208 GFP_KERNEL);
209 if (IS_ERR(bio))
210 return PTR_ERR(bio);
211
212 req = blk_make_request(vblk->disk->queue, bio, GFP_KERNEL);
213 if (IS_ERR(req)) {
214 bio_put(bio);
215 return PTR_ERR(req);
216 }
217
218 req->cmd_type = REQ_TYPE_SPECIAL;
219 return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
220}
221
192static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, 222static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
193 unsigned cmd, unsigned long data) 223 unsigned cmd, unsigned long data)
194{ 224{
195 struct gendisk *disk = bdev->bd_disk; 225 struct gendisk *disk = bdev->bd_disk;
196 struct virtio_blk *vblk = disk->private_data; 226 struct virtio_blk *vblk = disk->private_data;
197 227
228 if (cmd == 0x56424944) { /* 'VBID' */
229 void __user *usr_data = (void __user *)data;
230 char id_str[VIRTIO_BLK_ID_BYTES];
231 int err;
232
233 err = virtblk_get_id(disk, id_str);
234 if (!err && copy_to_user(usr_data, id_str, VIRTIO_BLK_ID_BYTES))
235 err = -EFAULT;
236 return err;
237 }
198 /* 238 /*
199 * Only allow the generic SCSI ioctls if the host can support it. 239 * Only allow the generic SCSI ioctls if the host can support it.
200 */ 240 */