From 61a664017f391947bda0466cfd1ef03959661e20 Mon Sep 17 00:00:00 2001 From: "ach61@labyrinth.cl.cam.ac.uk" Date: Tue, 22 Apr 2003 12:58:25 +0000 Subject: bitkeeper revision 1.160.3.1 (3ea53c71xG2JEZ0LCbFRAxt9kayWBw) fix earlier merge problems user space virtual disk manager --- .../arch/xeno/drivers/block/xl_block.c | 17 +- .../arch/xeno/drivers/block/xl_segment.c | 8 +- .../arch/xeno/drivers/block/xl_segment_proc.c | 22 +- xenolinux-2.4.21-pre4-sparse/drivers/block/genhd.c | 258 +++++++++++++++++++++ 4 files changed, 284 insertions(+), 21 deletions(-) create mode 100644 xenolinux-2.4.21-pre4-sparse/drivers/block/genhd.c (limited to 'xenolinux-2.4.21-pre4-sparse') diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c index 1c8022375a..9de2f0bf96 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c @@ -45,7 +45,7 @@ static inline void signal_requests_to_xen(void) } /* Convert from a XenoLinux major device to the Xen-level 'physical' device */ -static inline unsigned short xldev_to_physdev(kdev_t xldev) +inline unsigned short xldev_to_physdev(kdev_t xldev) { unsigned short physdev = 0; @@ -149,7 +149,6 @@ int xenolinux_block_ioctl(struct inode *inode, struct file *filep, case BLKRRPART: /* re-read partition table */ DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART); - if ( !capable(CAP_SYS_ADMIN) ) return -EACCES; return xenolinux_block_revalidate(dev); case BLKSSZGET: @@ -231,7 +230,11 @@ int xenolinux_block_revalidate(kdev_t dev) xl_disk_t *disk = xldev_to_xldisk(dev); unsigned long flags; int i, partn_shift = PARTN_SHIFT(dev); + int xdev = dev & XENDEV_IDX_MASK; + DPRINTK("xenolinux_block_revalidate: %d %d %d\n", + dev, xdev, XENDEV_IDX_MASK); + spin_lock_irqsave(&io_request_lock, flags); if ( disk->usage > 1 ) { @@ -242,9 +245,9 @@ int xenolinux_block_revalidate(kdev_t dev) for ( i = 0; i < (1 << partn_shift); i++ ) { - invalidate_device(dev + i, 1); - gd->part[dev + i].start_sect = 0; - gd->part[dev + i].nr_sects = 0; + invalidate_device(xdev + i, 1); + gd->part[xdev + i].start_sect = 0; + gd->part[xdev + i].nr_sects = 0; } grok_partitions(gd, MINOR(dev) >> partn_shift, @@ -438,7 +441,8 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs) case XEN_BLOCK_READ: case XEN_BLOCK_WRITE: if ( bret->status ) - printk(KERN_ALERT "Bad return from blkdev data request\n"); + printk(KERN_ALERT "Bad return from blkdev data request: %lx\n", + bret->status); for ( bh = (struct buffer_head *)bret->id; bh != NULL; bh = next_bh ) @@ -491,6 +495,7 @@ int xenolinux_control_msg(int operation, char *buffer, int size) /* We copy from an aligned buffer, as interface needs sector alignment. */ aligned_buf = (char *)get_free_page(GFP_KERNEL); if ( aligned_buf == NULL ) BUG(); + memcpy(aligned_buf, buffer, size); xlblk_control_msg_pending = 1; spin_lock_irqsave(&io_request_lock, flags); diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c index 48848f9010..2e86c25831 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c @@ -1,7 +1,7 @@ /****************************************************************************** * xl_segment.c * - * Xenolinux virtual block-device driver (vhd). + * Xenolinux virtual block-device driver (xvd). * */ @@ -52,11 +52,11 @@ int __init xlseg_init(void) memset(xdi, 0, sizeof(*xdi)); xenolinux_control_msg(XEN_BLOCK_PROBE_SEG, (char *)xdi, sizeof(*xdi)); - DPRINTK("vhd block device probe:\n"); + DPRINTK("xvd block device probe:\n"); for ( i = 0; i < xdi->count; i++ ) { - DPRINTK(" %2d: type: %d, capacity: %ld\n", - i, xdi->disks[i].type, xdi->disks[i].capacity); + DPRINTK(" %2d: device: %d, capacity: %ld\n", + i, xdi->disks[i].device, xdi->disks[i].capacity); } result = register_blkdev(XLVIRT_MAJOR, XLVIRT_MAJOR_NAME, diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment_proc.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment_proc.c index 3149be747b..59a3884de9 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment_proc.c +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment_proc.c @@ -123,7 +123,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, return count; } - string = get_string(NULL); /* look for Segment */ + string = get_string(NULL); /* look for Segment */ if (string == NULL || (*string != 's' && *string != 'S')) { printk (KERN_ALERT @@ -132,7 +132,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, return count; } - string = get_string(NULL); /* segment number */ + string = get_string(NULL); /* segment number */ if (string == NULL) { printk (KERN_ALERT "error: segment number missing\n"); @@ -140,7 +140,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, } xvd.segment = (int) to_number(string); - string = get_string(NULL); /* look for Extents */ + string = get_string(NULL); /* look for Extents */ if (string == NULL || (*string != 'e' && *string != 'E')) { printk (KERN_ALERT @@ -149,7 +149,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, return count; } - string = get_string(NULL); /* number of extents */ + string = get_string(NULL); /* number of extents */ if (string == NULL) { printk (KERN_ALERT "error: number of extents missing\n"); @@ -161,7 +161,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, for (loop = 0; loop < xvd.ext_count; loop++) { - string = get_string(NULL); /* look for Disk */ + string = get_string(NULL); /* look for Disk */ if (string == NULL || (*string != 'd' && *string != 'D')) { printk (KERN_ALERT @@ -169,15 +169,15 @@ static int proc_write_vhd(struct file *file, const char *buffer, string); return count; } - string = get_string(NULL); /* disk number */ + string = get_string(NULL); /* disk number */ if (string == NULL) { printk (KERN_ALERT "error: disk number missing\n"); return count; } - xvd.extents[loop].disk = (int) to_number(string); + xvd.extents[loop].disk = xldev_to_physdev((int) to_number(string)); - string = get_string(NULL); /* look for Offset */ + string = get_string(NULL); /* look for Offset */ if (string == NULL || (*string != 'o' && *string != 'O')) { printk (KERN_ALERT @@ -185,7 +185,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, string); return count; } - string = get_string(NULL); /* offset */ + string = get_string(NULL); /* offset */ if (string == NULL) { printk (KERN_ALERT "error: offset missing\n"); @@ -193,7 +193,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, } xvd.extents[loop].offset = to_number(string); - string = get_string(NULL); /* look for Size */ + string = get_string(NULL); /* look for Size */ if (string == NULL || (*string != 's' && *string != 'S')) { printk (KERN_ALERT @@ -201,7 +201,7 @@ static int proc_write_vhd(struct file *file, const char *buffer, string); return count; } - string = get_string(NULL); /* size */ + string = get_string(NULL); /* size */ if (string == NULL) { printk (KERN_ALERT "error: extent size missing\n"); diff --git a/xenolinux-2.4.21-pre4-sparse/drivers/block/genhd.c b/xenolinux-2.4.21-pre4-sparse/drivers/block/genhd.c new file mode 100644 index 0000000000..403d52e0a1 --- /dev/null +++ b/xenolinux-2.4.21-pre4-sparse/drivers/block/genhd.c @@ -0,0 +1,258 @@ +/* + * Code extracted from + * linux/kernel/hd.c + * + * Copyright (C) 1991-1998 Linus Torvalds + * + * devfs support - jj, rgooch, 980122 + * + * Moved partition checking code to fs/partitions* - Russell King + * (linux@arm.uk.linux.org) + */ + +/* + * TODO: rip out the remaining init crap from this file --hch + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Global kernel list of partitioning information. + * + * XXX: you should _never_ access this directly. + * the only reason this is exported is source compatiblity. + */ +/*static*/ struct gendisk *gendisk_head; +static struct gendisk *gendisk_array[MAX_BLKDEV]; +static rwlock_t gendisk_lock = RW_LOCK_UNLOCKED; + +EXPORT_SYMBOL(gendisk_head); + + +/** + * add_gendisk - add partitioning information to kernel list + * @gp: per-device partitioning information + * + * This function registers the partitioning information in @gp + * with the kernel. + */ +void +add_gendisk(struct gendisk *gp) +{ + struct gendisk *sgp; + + write_lock(&gendisk_lock); + + /* + * In 2.5 this will go away. Fix the drivers who rely on + * old behaviour. + */ + + for (sgp = gendisk_head; sgp; sgp = sgp->next) + { + if (sgp == gp) + { +// printk(KERN_ERR "add_gendisk: device major %d is buggy and added a live gendisk!\n", +// sgp->major) + goto out; + } + } + gendisk_array[gp->major] = gp; + gp->next = gendisk_head; + gendisk_head = gp; +out: + write_unlock(&gendisk_lock); +} + +EXPORT_SYMBOL(add_gendisk); + + +/** + * del_gendisk - remove partitioning information from kernel list + * @gp: per-device partitioning information + * + * This function unregisters the partitioning information in @gp + * with the kernel. + */ +void +del_gendisk(struct gendisk *gp) +{ + struct gendisk **gpp; + + write_lock(&gendisk_lock); + gendisk_array[gp->major] = NULL; + for (gpp = &gendisk_head; *gpp; gpp = &((*gpp)->next)) + if (*gpp == gp) + break; + if (*gpp) + *gpp = (*gpp)->next; + write_unlock(&gendisk_lock); +} + +EXPORT_SYMBOL(del_gendisk); + + +/** + * get_gendisk - get partitioning information for a given device + * @dev: device to get partitioning information for + * + * This function gets the structure containing partitioning + * information for the given device @dev. + */ +struct gendisk * +get_gendisk(kdev_t dev) +{ + struct gendisk *gp = NULL; + int maj = MAJOR(dev); + + read_lock(&gendisk_lock); + if ((gp = gendisk_array[maj])) + goto out; + + /* This is needed for early 2.4 source compatiblity. --hch */ + for (gp = gendisk_head; gp; gp = gp->next) + if (gp->major == maj) + break; +out: + read_unlock(&gendisk_lock); + return gp; +} + +EXPORT_SYMBOL(get_gendisk); + + +/** + * walk_gendisk - issue a command for every registered gendisk + * @walk: user-specified callback + * @data: opaque data for the callback + * + * This function walks through the gendisk chain and calls back + * into @walk for every element. + */ +int +walk_gendisk(int (*walk)(struct gendisk *, void *), void *data) +{ + struct gendisk *gp; + int error = 0; + + read_lock(&gendisk_lock); + for (gp = gendisk_head; gp; gp = gp->next) + if ((error = walk(gp, data))) + break; + read_unlock(&gendisk_lock); + + return error; +} + +#ifdef CONFIG_PROC_FS +/* iterator */ +static void *part_start(struct seq_file *s, loff_t *ppos) +{ + struct gendisk *gp; + loff_t pos = *ppos; + + read_lock(&gendisk_lock); + for (gp = gendisk_head; gp; gp = gp->next) + if (!pos--) + return gp; + return NULL; +} + +static void *part_next(struct seq_file *s, void *v, loff_t *pos) +{ + ++*pos; + return ((struct gendisk *)v)->next; +} + +static void part_stop(struct seq_file *s, void *v) +{ + read_unlock(&gendisk_lock); +} + +static int part_show(struct seq_file *s, void *v) +{ + struct gendisk *gp = v; + char buf[64]; + int n; + + if (gp == gendisk_head) { + seq_puts(s, "major minor #blocks start_sect nr_sects name" +#ifdef CONFIG_BLK_STATS + " rio rmerge rsect ruse wio wmerge " + "wsect wuse running use aveq" +#endif + "\n\n"); + } + + /* show the full disk and all non-0 size partitions of it */ + for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) { + if (gp->part[n].nr_sects) { +#ifdef CONFIG_BLK_STATS + struct hd_struct *hd = &gp->part[n]; + + disk_round_stats(hd); + seq_printf(s, "%4d %4d %10d %10ld %s " + "%d %d %d %d %d %d %d %d %d %d %d\n", + gp->major, n, gp->sizes[n], + gp->part[n].start_sect, + gp->part[n].nr_sects, + disk_name(gp, n, buf), + hd->rd_ios, hd->rd_merges, +#define MSEC(x) ((x) * 1000 / HZ) + hd->rd_sectors, MSEC(hd->rd_ticks), + hd->wr_ios, hd->wr_merges, + hd->wr_sectors, MSEC(hd->wr_ticks), + hd->ios_in_flight, MSEC(hd->io_ticks), + MSEC(hd->aveq)); +#else + seq_printf(s, "%4d %4d %10d %10ld %10ld %s\n", + gp->major, n, gp->sizes[n], + gp->part[n].start_sect, + gp->part[n].nr_sects, + disk_name(gp, n, buf)); +#endif /* CONFIG_BLK_STATS */ + } + } + + return 0; +} + +struct seq_operations partitions_op = { + .start = part_start, + .next = part_next, + .stop = part_stop, + .show = part_show, +}; +#endif + +extern int blk_dev_init(void); +extern int net_dev_init(void); +extern void console_map_init(void); +extern int atmdev_init(void); + +int __init device_init(void) +{ + blk_dev_init(); + sti(); +#ifdef CONFIG_NET + net_dev_init(); +#endif +#ifdef CONFIG_ATM + (void) atmdev_init(); +#endif +#ifdef CONFIG_VT + console_map_init(); +#endif + return 0; +} + +__initcall(device_init); -- cgit v1.2.3