1 /******************************************************************************
4 * XenLinux virtual block-device driver (xvd).
6 * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
7 * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
8 * Copyright (c) 2004-2005, Christian Limpach
10 * This file may be distributed separately from the Linux kernel, or
11 * incorporated into other software packages, subject to the following license:
13 * Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this source file (the "Software"), to deal in the Software without
15 * restriction, including without limitation the rights to use, copy, modify,
16 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
17 * and to permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
33 #include <linux/blkdev.h>
34 #include <linux/list.h>
37 * For convenience we distinguish between ide, scsi and 'other' (i.e.,
38 * potentially combinations of the two) in the naming scheme and in a few other
42 #define NUM_IDE_MAJORS 10
43 #define NUM_SCSI_MAJORS 9
44 #define NUM_VBD_MAJORS 1
48 blkif_sector_t capacity; /* 0: Size in terms of 512-byte sectors. */
49 blkif_vdev_t device; /* 8: Device number (opaque 16 bit value). */
51 struct list_head list;
54 static struct xlbd_type_info xlbd_ide_type = {
61 static struct xlbd_type_info xlbd_scsi_type = {
63 .partn_per_major = 16,
68 static struct xlbd_type_info xlbd_vbd_type = {
70 .partn_per_major = 16,
75 static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
78 #define XLBD_MAJOR_IDE_START 0
79 #define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS)
80 #define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
82 #define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
83 #define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
84 #define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
86 /* Information about our VBDs. */
88 struct list_head vbds_list;
90 struct request_queue *xlbd_blk_queue = NULL;
92 #define MAJOR_XEN(dev) ((dev)>>8)
93 #define MINOR_XEN(dev) ((dev) & 0xff)
95 static struct block_device_operations xlvbd_block_fops =
99 .release = blkif_release,
100 .ioctl = blkif_ioctl,
103 spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED;
105 static struct lvdisk * xlvbd_device_alloc(void)
109 ret = kmalloc(sizeof(struct lvdisk), GFP_KERNEL);
111 memset(ret, '\0', sizeof(struct lvdisk));
112 INIT_LIST_HEAD(&ret->list);
117 static void xlvbd_device_free(struct lvdisk *disk)
119 list_del(&disk->list);
123 static vdisk_t * xlvbd_probe(int *ret)
125 blkif_response_t rsp;
127 vdisk_t *disk_info = NULL;
131 buf = __get_free_page(GFP_KERNEL);
135 memset(&req, 0, sizeof(req));
136 req.operation = BLKIF_OP_PROBE;
138 #ifdef CONFIG_XEN_BLKDEV_GRANT
139 blkif_control_probe_send(&req, &rsp,
140 (unsigned long)(virt_to_machine(buf)));
142 req.frame_and_sects[0] = virt_to_machine(buf) | 7;
144 blkif_control_send(&req, &rsp);
146 if ( rsp.status <= 0 ) {
147 printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
154 disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
156 memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
164 static struct xlbd_major_info *xlbd_alloc_major_info(int major, int minor, int index)
166 struct xlbd_major_info *ptr;
168 ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
172 memset(ptr, 0, sizeof(struct xlbd_major_info));
177 case XLBD_MAJOR_IDE_RANGE:
178 ptr->type = &xlbd_ide_type;
179 ptr->index = index - XLBD_MAJOR_IDE_START;
181 case XLBD_MAJOR_SCSI_RANGE:
182 ptr->type = &xlbd_scsi_type;
183 ptr->index = index - XLBD_MAJOR_SCSI_START;
185 case XLBD_MAJOR_VBD_RANGE:
186 ptr->type = &xlbd_vbd_type;
187 ptr->index = index - XLBD_MAJOR_VBD_START;
191 if ( register_blkdev(ptr->major, ptr->type->devname) ) {
192 printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
193 ptr->major, ptr->type->devname);
198 devfs_mk_dir(ptr->type->devname);
199 major_info[index] = ptr;
203 static struct xlbd_major_info *xlbd_get_major_info(int device)
205 int major, minor, index;
207 major = MAJOR_XEN(device);
208 minor = MINOR_XEN(device);
211 case IDE0_MAJOR: index = 0; break;
212 case IDE1_MAJOR: index = 1; break;
213 case IDE2_MAJOR: index = 2; break;
214 case IDE3_MAJOR: index = 3; break;
215 case IDE4_MAJOR: index = 4; break;
216 case IDE5_MAJOR: index = 5; break;
217 case IDE6_MAJOR: index = 6; break;
218 case IDE7_MAJOR: index = 7; break;
219 case IDE8_MAJOR: index = 8; break;
220 case IDE9_MAJOR: index = 9; break;
221 case SCSI_DISK0_MAJOR: index = 10; break;
222 case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
223 index = 11 + major - SCSI_DISK1_MAJOR;
225 case SCSI_CDROM_MAJOR: index = 18; break;
226 default: index = 19; break;
229 return major_info[index]
231 : xlbd_alloc_major_info(major, minor, index);
234 static int xlvbd_blk_queue_alloc(struct xlbd_type_info *type)
236 xlbd_blk_queue = blk_init_queue(do_blkif_request, &blkif_io_lock);
237 if ( !xlbd_blk_queue )
240 elevator_init(xlbd_blk_queue, "noop");
243 * Turn off barking 'headactive' mode. We dequeue
244 * buffer heads as soon as we pass them to back-end
247 blk_queue_headactive(xlbd_blk_queue, 0);
249 /* Hard sector size and max sectors impersonate the equiv. hardware. */
250 blk_queue_hardsect_size(xlbd_blk_queue, 512);
251 blk_queue_max_sectors(xlbd_blk_queue, 512);
253 /* Each segment in a request is up to an aligned page in size. */
254 blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1);
255 blk_queue_max_segment_size(xlbd_blk_queue, PAGE_SIZE);
257 /* Ensure a merged request will fit in a single I/O ring slot. */
258 blk_queue_max_phys_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
259 blk_queue_max_hw_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
261 /* Make sure buffer addresses are sector-aligned. */
262 blk_queue_dma_alignment(xlbd_blk_queue, 511);
266 struct gendisk *xlvbd_alloc_gendisk(struct xlbd_major_info *mi, int minor,
270 struct xlbd_disk_info *di;
273 di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL);
277 di->xd_device = disk->device;
279 nb_minors = ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
280 ? mi->type->partn_per_major
283 gd = alloc_disk(nb_minors);
288 sprintf(gd->disk_name, "%s%c", mi->type->diskname,
289 'a' + mi->index * mi->type->partn_per_major +
290 (minor >> mi->type->partn_shift));
292 sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
293 'a' + mi->index * mi->type->partn_per_major +
294 (minor >> mi->type->partn_shift),
295 minor & ((1 << mi->type->partn_shift) - 1));
297 gd->major = mi->major;
298 gd->first_minor = minor;
299 gd->fops = &xlvbd_block_fops;
300 gd->private_data = di;
301 set_capacity(gd, disk->capacity);
303 if ( !xlbd_blk_queue )
304 if ( xlvbd_blk_queue_alloc(mi->type) )
307 gd->queue = xlbd_blk_queue;
311 printk(KERN_ALERT "error gendisk\n");
314 printk(KERN_ALERT "error out\n");
319 static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
324 struct block_device *bd;
326 struct xlbd_major_info *mi;
328 mi = xlbd_get_major_info(disk->device);
332 new = xlvbd_device_alloc();
335 new->capacity = disk->capacity;
336 new->device = disk->device;
337 new->info = disk->info;
339 minor = MINOR_XEN(disk->device);
340 device = MKDEV(mi->major, minor);
346 gd = xlvbd_alloc_gendisk(mi, minor, disk);
350 if ( VDISK_READONLY(disk->info) )
353 switch (VDISK_TYPE(disk->info)) {
354 case VDISK_TYPE_CDROM:
355 gd->flags |= GENHD_FL_REMOVABLE | GENHD_FL_CD;
357 case VDISK_TYPE_FLOPPY:
358 case VDISK_TYPE_TAPE:
359 gd->flags |= GENHD_FL_REMOVABLE;
361 case VDISK_TYPE_DISK:
364 printk(KERN_ALERT "XenLinux: unknown device type %d\n",
365 VDISK_TYPE(disk->info));
369 list_add(&new->list, list);
376 static int xlvbd_device_del(struct lvdisk *disk)
379 struct block_device *bd;
381 struct xlbd_disk_info *di;
384 device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
390 gd = get_gendisk(device, &unused);
391 di = gd->private_data;
393 if ( di->mi->usage != 0 ) {
394 printk(KERN_ALERT "VBD removal failed: used [dev=%x]\n", device);
401 xlvbd_device_free(disk);
407 static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
410 struct block_device *bd;
414 if ( ldisk->capacity == disk->capacity && ldisk->info == disk->info )
417 device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
423 gd = get_gendisk(device, &unused);
424 set_capacity(gd, disk->capacity);
425 ldisk->capacity = disk->capacity;
432 void xlvbd_refresh(void)
435 struct list_head *tmp, *tmp2;
439 newdisks = xlvbd_probe(&nr);
441 printk(KERN_ALERT "failed to probe\n");
446 list_for_each_safe(tmp, tmp2, &vbds_list) {
447 disk = list_entry(tmp, struct lvdisk, list);
449 for (i = 0; i < nr; i++) {
450 if ( !newdisks[i].device )
452 if ( disk->device == newdisks[i].device ) {
453 xlvbd_device_update(disk, &newdisks[i]);
454 newdisks[i].device = 0;
459 xlvbd_device_del(disk);
460 newdisks[i].device = 0;
463 for (i = 0; i < nr; i++)
464 if ( newdisks[i].device )
465 xlvbd_device_add(&vbds_list, &newdisks[i]);
470 * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
471 * state. The VBDs need to be updated in this way when the domain is
472 * initialised and also each time we receive an XLBLK_UPDATE event.
474 void xlvbd_update_vbds(void)
480 * Set up all the linux device goop for the virtual block devices
481 * (vbd's) that we know about. Note that although from the backend
482 * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
483 * number, the domain creation tools conventionally allocate these
484 * numbers to correspond to those used by 'real' linux -- this is just
485 * for convenience as it means e.g. that the same /etc/fstab can be
486 * used when booting with or without Xen.
493 INIT_LIST_HEAD(&vbds_list);
495 memset(major_info, 0, sizeof(major_info));
497 disks = xlvbd_probe(&nr);
499 printk(KERN_ALERT "failed to probe\n");
503 for (i = 0; i < nr; i++)
504 xlvbd_device_add(&vbds_list, &disks[i]);