3 #include <linux/slab.h>
6 #include <linux/module.h>
8 #include <linux/virtio.h>
75 static inline int virtblk_result(
struct virtblk_req *vbr)
103 static void virtblk_add_buf_wait(
struct virtio_blk *vblk,
114 spin_lock_irq(vblk->
disk->queue->queue_lock);
117 spin_unlock_irq(vblk->
disk->queue->queue_lock);
121 spin_unlock_irq(vblk->
disk->queue->queue_lock);
130 static inline void virtblk_add_req(
struct virtblk_req *vbr,
131 unsigned int out,
unsigned int in)
135 spin_lock_irq(vblk->
disk->queue->queue_lock);
138 spin_unlock_irq(vblk->
disk->queue->queue_lock);
139 virtblk_add_buf_wait(vblk, vbr, out, in);
143 spin_unlock_irq(vblk->
disk->queue->queue_lock);
146 static int virtblk_bio_send_flush(
struct virtblk_req *vbr)
148 unsigned int out = 0, in = 0;
155 sg_set_buf(&vbr->
sg[out + in++], &vbr->
status,
sizeof(vbr->
status));
157 virtblk_add_req(vbr, out, in);
162 static int virtblk_bio_send_data(
struct virtblk_req *vbr)
165 unsigned int num, out = 0, in = 0;
166 struct bio *bio = vbr->
bio;
170 vbr->
out_hdr.sector = bio->bi_sector;
171 vbr->
out_hdr.ioprio = bio_prio(bio);
177 sg_set_buf(&vbr->
sg[num + out + in++], &vbr->
status,
190 virtblk_add_req(vbr, out, in);
201 virtblk_bio_send_data(vbr);
210 virtblk_bio_send_flush(vbr);
213 static inline void virtblk_request_done(
struct virtblk_req *vbr)
217 int error = virtblk_result(vbr);
219 if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
220 req->resid_len = vbr->
in_hdr.residual;
221 req->sense_len = vbr->
in_hdr.sense_len;
222 req->errors = vbr->
in_hdr.errors;
223 }
else if (req->cmd_type == REQ_TYPE_SPECIAL) {
224 req->errors = (error != 0);
231 static inline void virtblk_bio_flush_done(
struct virtblk_req *vbr)
245 static inline void virtblk_bio_data_done(
struct virtblk_req *vbr)
260 static inline void virtblk_bio_done(
struct virtblk_req *vbr)
263 virtblk_bio_flush_done(vbr);
265 virtblk_bio_data_done(vbr);
271 bool bio_done =
false, req_done =
false;
281 virtblk_bio_done(vbr);
284 virtblk_request_done(vbr);
292 spin_unlock_irqrestore(vblk->
disk->queue->queue_lock, flags);
301 unsigned long num, out = 0, in = 0;
314 vbr->
out_hdr.ioprio = req_get_ioprio(vbr->
req);
316 switch (req->cmd_type) {
320 vbr->
out_hdr.ioprio = req_get_ioprio(vbr->
req);
322 case REQ_TYPE_BLOCK_PC:
325 vbr->
out_hdr.ioprio = req_get_ioprio(vbr->
req);
327 case REQ_TYPE_SPECIAL:
330 vbr->
out_hdr.ioprio = req_get_ioprio(vbr->
req);
346 if (vbr->
req->cmd_type == REQ_TYPE_BLOCK_PC)
347 sg_set_buf(&vblk->
sg[out++], vbr->
req->cmd, vbr->
req->cmd_len);
351 if (vbr->
req->cmd_type == REQ_TYPE_BLOCK_PC) {
353 sg_set_buf(&vblk->
sg[num + out + in++], &vbr->
in_hdr,
357 sg_set_buf(&vblk->
sg[num + out + in++], &vbr->
status,
361 if (rq_data_dir(vbr->
req) ==
WRITE) {
390 if (!do_req(q, vblk, req)) {
402 static void virtblk_make_request(
struct request_queue *q,
struct bio *bio)
409 vbr = virtblk_alloc_req(vblk,
GFP_NOIO);
425 virtblk_bio_send_flush(vbr);
427 virtblk_bio_send_data(vbr);
432 static int virtblk_get_id(
struct gendisk *disk,
char *id_str)
450 req->cmd_type = REQ_TYPE_SPECIAL;
458 unsigned int cmd,
unsigned long data)
460 struct gendisk *disk = bdev->
bd_disk;
470 (
void __user *)data);
486 geo->
heads = vgeo.heads;
498 static const struct block_device_operations virtblk_fops = {
499 .ioctl = virtblk_ioctl,
501 .getgeo = virtblk_getgeo,
504 static int index_to_minor(
int index)
509 static int minor_to_index(
int minor)
517 struct gendisk *disk = dev_to_disk(dev);
524 err = virtblk_get_id(disk, buf);
541 char cap_str_2[10], cap_str_10[10];
550 &capacity,
sizeof(capacity));
553 if ((
sector_t)capacity != capacity) {
554 dev_warn(&vdev->
dev,
"Capacity %llu too large: truncating\n",
555 (
unsigned long long)capacity);
559 size = capacity * queue_logical_block_size(q);
563 dev_notice(&vdev->
dev,
564 "new size: %llu %d-byte logical blocks (%s/%s)\n",
565 (
unsigned long long)capacity,
566 queue_logical_block_size(q),
567 cap_str_10, cap_str_2);
569 set_capacity(vblk->
disk, capacity);
575 static void virtblk_config_changed(
struct virtio_device *vdev)
587 vblk->
vq = virtio_find_single_vq(vblk->
vdev, virtblk_done,
"requests");
588 if (IS_ERR(vblk->
vq))
589 err = PTR_ERR(vblk->
vq);
600 const int base =
'z' -
'a' + 1;
601 char *begin = buf +
strlen(prefix);
612 *--p =
'a' + (index %
unit);
613 index = (index /
unit) - 1;
614 }
while (index >= 0);
622 static int virtblk_get_cache_mode(
struct virtio_device *vdev)
636 static void virtblk_update_cache_mode(
struct virtio_device *vdev)
638 u8 writeback = virtblk_get_cache_mode(vdev);
649 static const char *
const virtblk_cache_types[] = {
650 "write through",
"write back"
655 const char *buf,
size_t count)
657 struct gendisk *disk = dev_to_disk(dev);
664 for (i =
ARRAY_SIZE(virtblk_cache_types); --i >= 0; )
674 &writeback,
sizeof(writeback));
676 virtblk_update_cache_mode(vdev);
684 struct gendisk *disk = dev_to_disk(dev);
686 u8 writeback = virtblk_get_cache_mode(vblk->
vdev);
689 return snprintf(buf, 40,
"%s\n", virtblk_cache_types[writeback]);
694 virtblk_cache_type_show,
NULL);
697 virtblk_cache_type_show, virtblk_cache_type_store);
723 if (err || !sg_elems)
750 pool_size +=
sizeof(
struct scatterlist) * sg_elems;
751 vblk->
pool = mempool_create_kmalloc_pool(1, pool_size);
774 virtblk_name_format(
"vd", index, vblk->
disk->disk_name, DISK_NAME_LEN);
777 vblk->
disk->first_minor = index_to_minor(index);
778 vblk->
disk->private_data = vblk;
779 vblk->
disk->fops = &virtblk_fops;
780 vblk->
disk->driverfs_dev = &vdev->
dev;
784 virtblk_update_cache_mode(vdev);
796 dev_warn(&vdev->
dev,
"Capacity %llu too large: truncating\n",
797 (
unsigned long long)cap);
800 set_capacity(vblk->
disk, cap);
828 blk_size = queue_logical_block_size(q);
833 &physical_block_exp);
834 if (!err && physical_block_exp)
836 blk_size * (1 << physical_block_exp));
841 if (!err && alignment_offset)
847 if (!err && min_io_size)
853 if (!err && opt_io_size)
863 &dev_attr_cache_type_rw);
866 &dev_attr_cache_type_ro);
879 vdev->
config->del_vqs(vdev);
891 int index = vblk->
index;
902 vdev->
config->reset(vdev);
908 vdev->
config->del_vqs(vdev);
919 vdev->
config->reset(vdev);
928 spin_lock_irq(vblk->
disk->queue->queue_lock);
930 spin_unlock_irq(vblk->
disk->queue->queue_lock);
933 vdev->
config->del_vqs(vdev);
943 ret = init_vq(vdev->
priv);
945 spin_lock_irq(vblk->
disk->queue->queue_lock);
947 spin_unlock_irq(vblk->
disk->queue->queue_lock);
972 .driver.name = KBUILD_MODNAME,
975 .probe = virtblk_probe,
977 .config_changed = virtblk_config_changed,
979 .freeze = virtblk_freeze,
980 .restore = virtblk_restore,
995 goto out_destroy_workqueue;
1000 goto out_unregister_blkdev;
1003 out_unregister_blkdev:
1005 out_destroy_workqueue:
1010 static void __exit fini(
void)