diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 20:22:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 20:22:52 -0400 |
commit | 1756ac3d3c41341297ea25b818b7fce505bb2a9a (patch) | |
tree | 96382220afbb82fd5c576c4c08b3c3e13282851f /drivers/block | |
parent | 98edb6ca4174f17a64890a02f44c211c8b44fb3c (diff) | |
parent | 0643e4c6e4fd67778fa886a89e6ec2320e0ff4d3 (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.c | 46 |
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 | ||
186 | static void virtblk_prepare_flush(struct request_queue *q, struct request *req) | 193 | static 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 | */ | ||
201 | static 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 | |||
192 | static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | 222 | static 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 | */ |