41 #include <linux/cdrom.h>
42 #include <linux/module.h>
43 #include <linux/slab.h>
46 #include <linux/bitmap.h>
51 #include <xen/events.h>
59 #include <asm/xen/hypervisor.h>
74 static const struct block_device_operations xlvbd_block_fops;
76 #define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
93 struct blkif_front_ring
ring;
110 static unsigned int nr_minors;
111 static unsigned long *minors;
114 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
115 (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE)
116 #define GRANT_INVALID_REF 0
118 #define PARTS_PER_DISK 16
119 #define PARTS_PER_EXT_DISK 256
121 #define BLKIF_MAJOR(dev) ((dev)>>8)
122 #define BLKIF_MINOR(dev) ((dev) & 0xff)
125 #define EXTENDED (1<<EXT_SHIFT)
126 #define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
127 #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
128 #define EMULATED_HD_DISK_MINOR_OFFSET (0)
129 #define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256)
130 #define EMULATED_SD_DISK_MINOR_OFFSET (0)
131 #define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_SD_DISK_MINOR_OFFSET / 256)
133 #define DEV_NAME "xvd"
147 if (info->
shadow[
id].req.u.rw.id !=
id)
157 static const char *op_name(
int op)
159 static const char *
const names[] = {
174 static int xlbd_reserve_minors(
unsigned int minor,
unsigned int nr)
176 unsigned int end = minor +
nr;
179 if (end > nr_minors) {
180 unsigned long *
bitmap, *old;
187 spin_lock(&minor_lock);
188 if (end > nr_minors) {
196 spin_unlock(&minor_lock);
200 spin_lock(&minor_lock);
206 spin_unlock(&minor_lock);
211 static void xlbd_release_minors(
unsigned int minor,
unsigned int nr)
213 unsigned int end = minor +
nr;
216 spin_lock(&minor_lock);
218 spin_unlock(&minor_lock);
221 static void blkif_restart_queue_callback(
void *
arg)
244 unsigned command,
unsigned long argument)
249 dev_dbg(&info->
xbdev->dev,
"command: 0x%x, argument: 0x%lx\n",
250 command, (
long)argument);
254 dev_dbg(&info->
xbdev->dev,
"FIXME: support multisession CDs later\n");
256 if (
put_user(0, (
char __user *)(argument + i)))
261 struct gendisk *gd = info->
gd;
262 if (gd->flags & GENHD_FL_CD)
282 static int blkif_queue_request(
struct request *
req)
285 unsigned long buffer_mfn;
288 unsigned int fsect, lsect;
300 blkif_restart_queue_callback,
308 id = get_id_from_freelist(info);
311 ring_req->
u.
rw.id =
id;
332 ring_req->
u.
discard.nr_sectors = blk_rq_sectors(req);
346 lsect = fsect + (sg->
length >> 9) - 1;
353 info->
xbdev->otherend_id,
358 ring_req->
u.
rw.seg[
i] =
362 .last_sect = lsect };
366 info->
ring.req_prod_pvt++;
377 static inline void flush_requests(
struct blkfront_info *info)
397 pr_debug(
"Entered do_blkif_request\n");
402 info = req->rq_disk->private_data;
409 if ((req->cmd_type != REQ_TYPE_FS) ||
416 pr_debug(
"do_blk_req %p: cmd %p, sec %lx, "
417 "(%u/%u) buffer:%p [%s]\n",
418 req, req->cmd, (
unsigned long)blk_rq_pos(req),
419 blk_rq_cur_sectors(req), blk_rq_sectors(req),
420 req->buffer, rq_data_dir(req) ?
"write" :
"read");
422 if (blkif_queue_request(req)) {
434 flush_requests(info);
437 static int xlvbd_init_blk_queue(
struct gendisk *gd,
u16 sector_size)
446 queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
449 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq);
454 queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, rq);
487 "flush diskcache" :
"barrier or flush"),
491 static int xen_translate_vdev(
int vdevice,
int *minor,
unsigned int *
offset)
545 "incorrect, please use an xvd device instead\n");
551 static char *encode_disk_name(
char *
ptr,
unsigned int n)
554 ptr = encode_disk_name(ptr, n / 26 - 1);
561 u16 vdisk_info,
u16 sector_size)
581 err = xen_translate_vdev(info->
vdevice, &minor, &offset);
588 offset = minor / nr_parts;
591 "emulated IDE disks,\n\t choose an xvd device name"
592 "from xvde on\n", info->
vdevice);
595 pr_warn(
"blkfront: %#x's minor (%#x) out of range; ignoring\n",
600 if ((minor % nr_parts) == 0)
601 nr_minors = nr_parts;
603 err = xlbd_reserve_minors(minor, nr_minors);
613 ptr = encode_disk_name(gd->disk_name +
sizeof(
DEV_NAME) - 1, offset);
614 BUG_ON(ptr >= gd->disk_name + DISK_NAME_LEN);
618 snprintf(ptr, gd->disk_name + DISK_NAME_LEN - ptr,
619 "%d", minor & (nr_parts - 1));
622 gd->first_minor = minor;
623 gd->fops = &xlvbd_block_fops;
624 gd->private_data =
info;
625 gd->driverfs_dev = &(info->
xbdev->dev);
626 set_capacity(gd, capacity);
628 if (xlvbd_init_blk_queue(gd, sector_size)) {
633 info->
rq = gd->queue;
642 gd->flags |= GENHD_FL_REMOVABLE;
645 gd->flags |= GENHD_FL_CD;
650 xlbd_release_minors(minor, nr_minors);
655 static void xlvbd_release_gendisk(
struct blkfront_info *info)
657 unsigned int minor, nr_minors;
670 spin_unlock_irqrestore(&info->
io_lock, flags);
677 minor = info->
gd->first_minor;
678 nr_minors = info->
gd->minors;
679 xlbd_release_minors(minor, nr_minors);
688 static void kick_pending_request_queues(
struct blkfront_info *info)
694 do_blkif_request(info->
rq);
704 kick_pending_request_queues(info);
705 spin_unlock_irq(&info->
io_lock);
719 spin_unlock_irq(&info->
io_lock);
727 (
unsigned long)info->
ring.sring);
742 for (i = 0; i < s->
req.u.rw.nr_segments; i++)
758 spin_unlock_irqrestore(&info->
io_lock, flags);
763 rp = info->
ring.sring->rsp_prod;
766 for (i = info->
ring.rsp_cons; i != rp; i++) {
777 WARN(1,
"%s: response to %s has incorrect id (%ld)\n",
778 info->
gd->disk_name, op_name(bret->
operation),
id);
786 blkif_completion(&info->
shadow[
id]);
788 if (add_id_to_freelist(info,
id)) {
789 WARN(1,
"%s: response to %s (id %ld) couldn't be recycled!\n",
790 info->
gd->disk_name, op_name(bret->
operation),
id);
804 queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
805 queue_flag_clear(QUEUE_FLAG_SECDISCARD, rq);
817 info->
shadow[
id].req.u.rw.nr_segments == 0)) {
833 dev_dbg(&info->
xbdev->dev,
"Bad return from blkdev data "
834 "request: %x\n", bret->
status);
843 info->
ring.rsp_cons =
i;
845 if (i != info->
ring.req_prod_pvt) {
851 info->
ring.sring->rsp_event = i + 1;
853 kick_pending_request_queues(info);
855 spin_unlock_irqrestore(&info->
io_lock, flags);
864 struct blkif_sring *sring;
895 "bind_evtchn_to_irqhandler failed");
916 err = setup_blkring(dev, info);
924 goto destroy_blkring;
930 message =
"writing ring-ref";
931 goto abort_transaction;
934 "event-channel",
"%u", info->
evtchn);
936 message =
"writing event-channel";
937 goto abort_transaction;
940 XEN_IO_PROTO_ABI_NATIVE);
942 message =
"writing protocol";
943 goto abort_transaction;
951 goto destroy_blkring;
982 "virtual-device",
"%i", &vdevice);
1007 "%s: HVM does not support vbd %d as xen block device\n",
1016 if (
strncmp(type,
"cdrom", 5) == 0) {
1036 info->
shadow[i].req.u.rw.id = i+1;
1037 info->
shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
1043 err = talk_to_blkback(dev, info);
1071 info->
shadow[i].req.u.rw.id = i+1;
1073 info->
shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
1086 req->
u.
rw.id = get_id_from_freelist(info);
1091 for (j = 0; j < req->
u.
rw.nr_segments; j++)
1093 req->
u.
rw.seg[j].gref,
1094 info->
xbdev->otherend_id,
1096 rq_data_dir(info->
shadow[req->
u.
rw.id].request));
1100 info->
ring.req_prod_pvt++;
1107 spin_lock_irq(&info->
io_lock);
1113 flush_requests(info);
1116 kick_pending_request_queues(info);
1118 spin_unlock_irq(&info->
io_lock);
1138 err = talk_to_blkback(dev, info);
1140 err = blkif_recover(info);
1172 "Device in use; refusing to close");
1175 xlvbd_release_gendisk(info);
1183 static void blkfront_setup_discard(
struct blkfront_info *info)
1187 unsigned int discard_granularity;
1188 unsigned int discard_alignment;
1189 unsigned int discard_secure;
1196 if (
strncmp(type,
"phy", 3) == 0) {
1198 "discard-granularity",
"%u", &discard_granularity,
1199 "discard-alignment",
"%u", &discard_alignment,
1207 "discard-secure",
"%d", &discard_secure,
1212 }
else if (
strncmp(type,
"file", 4) == 0)
1237 "sectors",
"%Lu", §ors);
1242 set_capacity(info->
gd, sectors);
1254 __func__, info->
xbdev->otherend);
1257 "sectors",
"%llu", §ors,
1258 "info",
"%u", &binfo,
1259 "sector-size",
"%lu", §or_size,
1263 "reading backend fields at %s",
1264 info->
xbdev->otherend);
1272 "feature-barrier",
"%d", &barrier,
1282 if (!err && barrier) {
1291 "feature-flush-cache",
"%d", &flush,
1294 if (!err && flush) {
1300 "feature-discard",
"%d", &discard,
1303 if (!err && discard)
1304 blkfront_setup_discard(info);
1306 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
1309 info->
xbdev->otherend);
1316 spin_lock_irq(&info->
io_lock);
1318 kick_pending_request_queues(info);
1319 spin_unlock_irq(&info->
io_lock);
1334 dev_dbg(&dev->
dev,
"blkfront:blkback_changed to state %d.\n", backend_state);
1336 switch (backend_state) {
1347 blkfront_connect(info);
1351 blkfront_closing(info);
1360 struct gendisk *disk;
1364 blkif_free(info, 0);
1387 info = disk->private_data;
1390 "%s was hot-unplugged, %d stale handles\n",
1394 xlvbd_release_gendisk(info);
1395 disk->private_data =
NULL;
1414 struct gendisk *disk = bdev->
bd_disk;
1420 info = disk->private_data;
1440 static int blkif_release(
struct gendisk *disk,
fmode_t mode)
1459 xbdev = info->
xbdev;
1464 xlvbd_release_gendisk(info);
1473 xlvbd_release_gendisk(info);
1474 disk->private_data =
NULL;
1484 static const struct block_device_operations xlvbd_block_fops =
1488 .release = blkif_release,
1489 .getgeo = blkif_getgeo,
1490 .ioctl = blkif_ioctl,
1500 .probe = blkfront_probe,
1501 .
remove = blkfront_remove,
1502 .
resume = blkfront_resume,
1503 .otherend_changed = blkback_changed,
1504 .is_ready = blkfront_is_ready,
1507 static int __init xlblk_init(
void)
1534 static void __exit xlblk_exit(
void)