aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.21-pre4-sparse
diff options
context:
space:
mode:
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-03-07 11:29:57 +0000
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-03-07 11:29:57 +0000
commit07486ec49f025987359499eb2f06f0b794994d42 (patch)
treed5ca0fe98a09dc1f3f2d8c8089d5ae7b4489b699 /xenolinux-2.4.21-pre4-sparse
parentd0ec9023281a5d6ed0aee9341c7889320664e862 (diff)
downloadxen-07486ec49f025987359499eb2f06f0b794994d42.tar.gz
xen-07486ec49f025987359499eb2f06f0b794994d42.tar.bz2
xen-07486ec49f025987359499eb2f06f0b794994d42.zip
bitkeeper revision 1.111 (3e6882b5ERWU6qPXXUlLkYvavej4FQ)
xl_segment.c, xl_scsi.c, xl_ide.c, xl_block.h, xl_block.c: Partition tables are now revalidated on demand for all XL blkdevs (IDE, SCSI, and virtual).
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse')
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c72
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h10
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c11
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c7
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c7
5 files changed, 84 insertions, 23 deletions
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 985fda050f..567af806b5 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
@@ -34,7 +34,7 @@ static int nr_pending;
/* Convert from a XenoLinux major device to the Xen-level 'physical' device */
static inline unsigned short xldev_to_physdev(kdev_t xldev)
{
- unsigned short physdev;
+ unsigned short physdev = 0;
switch ( MAJOR(xldev) )
{
@@ -49,11 +49,10 @@ static inline unsigned short xldev_to_physdev(kdev_t xldev)
case XLVIRT_MAJOR:
physdev = XENDEV_VIRTUAL;
break;
-
- default:
- BUG();
}
+ if ( physdev == 0 ) BUG();
+
physdev += (MINOR(xldev) >> PARTN_SHIFT);
return physdev;
@@ -84,23 +83,36 @@ static inline struct gendisk *xldev_to_gendisk(kdev_t xldev)
return gd;
}
+
+static inline xl_disk_t *xldev_to_xldisk(kdev_t xldev)
+{
+ struct gendisk *gd = xldev_to_gendisk(xldev);
+ return (xl_disk_t *)gd->real_devices + (MINOR(xldev) >> PARTN_SHIFT);
+}
+
+
int xenolinux_block_open(struct inode *inode, struct file *filep)
{
- DPRINTK("xenolinux_block_open\n");
+ xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
+ disk->usage++;
+ DPRINTK("xenolinux_block_open\n");
return 0;
}
+
int xenolinux_block_release(struct inode *inode, struct file *filep)
{
+ xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
+ disk->usage--;
DPRINTK("xenolinux_block_release\n");
return 0;
}
-
int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
unsigned command, unsigned long argument)
{
+ kdev_t dev = inode->i_rdev;
struct hd_geometry *geo = (struct hd_geometry *)argument;
struct gendisk *gd;
struct hd_struct *part;
@@ -112,10 +124,10 @@ int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
if (!inode) return -EINVAL;
DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
- command, (long) argument, inode->i_rdev);
+ command, (long) argument, dev);
- gd = xldev_to_gendisk(inode->i_rdev);
- part = &gd->part[MINOR(inode->i_rdev)];
+ gd = xldev_to_gendisk(dev);
+ part = &gd->part[MINOR(dev)];
switch ( command )
{
@@ -125,25 +137,26 @@ int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
case BLKRRPART: /* re-read partition table */
DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART);
- break;
+ if ( !capable(CAP_SYS_ADMIN) ) return -EACCES;
+ return xenolinux_block_revalidate(dev);
case BLKSSZGET:
- switch ( MAJOR(inode->i_rdev) )
+ switch ( MAJOR(dev) )
{
case XLIDE_MAJOR:
DPRINTK_IOCTL(" BLKSSZGET: %x 0x%x\n", BLKSSZGET,
- xlide_hwsect(MINOR(inode->i_rdev)));
- return xlide_hwsect(MINOR(inode->i_rdev));
+ xlide_hwsect(MINOR(dev)));
+ return xlide_hwsect(MINOR(dev));
case XLSCSI_MAJOR:
DPRINTK_IOCTL(" BLKSSZGET: %x 0x%x\n", BLKSSZGET,
- xlscsi_hwsect(MINOR(inode->i_rdev)));
- return xlscsi_hwsect(MINOR(inode->i_rdev));
+ xlscsi_hwsect(MINOR(dev)));
+ return xlscsi_hwsect(MINOR(dev));
case XLVIRT_MAJOR:
DPRINTK_IOCTL(" BLKSSZGET: %x 0x%x\n", BLKSSZGET,
- xlsegment_hwsect(MINOR(inode->i_rdev)));
- return xlsegment_hwsect(MINOR(inode->i_rdev));
+ xlsegment_hwsect(MINOR(dev)));
+ return xlsegment_hwsect(MINOR(dev));
default:
printk(KERN_ALERT "BLKSSZGET ioctl() on bogus disk!\n");
@@ -202,10 +215,33 @@ int xenolinux_block_check(kdev_t dev)
int xenolinux_block_revalidate(kdev_t dev)
{
- DPRINTK("xenolinux_block_revalidate\n");
+ struct gendisk *gd = xldev_to_gendisk(dev);
+ xl_disk_t *disk = xldev_to_xldisk(dev);
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ if ( disk->usage > 1 )
+ {
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return -EBUSY;
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ 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;
+ }
+
+ grok_partitions(gd, MINOR(dev) >> PARTN_SHIFT,
+ 1 << PARTN_SHIFT, disk->capacity);
+
return 0;
}
+
/*
* hypervisor_request
*
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h
index 2140b30d7b..17ca09d9f2 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h
@@ -35,6 +35,16 @@
#define DPRINTK_IOCTL(_f, _a...) ((void)0)
#endif
+/*
+ * We have one of these per XL-IDE, XL-SCSI, and XL-VIRT device.
+ * They hang in an array off the gendisk structure. We may end up putting
+ * all kinds of interesting stuff here :-)
+ */
+typedef struct xl_disk {
+ int usage;
+ unsigned long capacity;
+} xl_disk_t;
+
/* Generic layer. */
extern int xenolinux_control_msg(int operration, char *buffer);
extern int xenolinux_block_open(struct inode *inode, struct file *filep);
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c
index f07c54dcb4..9d6ef64c75 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c
@@ -78,6 +78,8 @@ int xlide_init(xen_disk_info_t *xdi)
for ( i = 0; i < xdi->count; i++ )
if ( xdi->disks[i].type == XEN_DISK_IDE ) units++;
+ if ( units == 0 ) return 0;
+
/* Construct an appropriate gendisk structure. */
minors = units * (1<<IDE_PARTN_BITS);
gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
@@ -88,7 +90,7 @@ int xlide_init(xen_disk_info_t *xdi)
gd->minor_shift = IDE_PARTN_BITS;
gd->max_p = 1<<IDE_PARTN_BITS;
gd->nr_real = units;
- gd->real_devices = NULL;
+ gd->real_devices = kmalloc(units * sizeof(xl_disk_t), GFP_KERNEL);
gd->next = NULL;
gd->fops = &xlide_block_fops;
gd->de_arr = kmalloc(sizeof(*gd->de_arr) * units, GFP_KERNEL);
@@ -97,14 +99,17 @@ int xlide_init(xen_disk_info_t *xdi)
memset(gd->part, 0, minors * sizeof(struct hd_struct));
memset(gd->de_arr, 0, sizeof(*gd->de_arr) * units);
memset(gd->flags, 0, sizeof(*gd->flags) * units);
+ memset(gd->real_devices, 0, sizeof(xl_disk_t) * units);
xlide_gendisk = gd;
add_gendisk(gd);
-
+
/* Now register each disk in turn. */
disk = 0;
for ( i = 0; i < xdi->count; i++ )
{
if ( xdi->disks[i].type != XEN_DISK_IDE ) continue;
+ ((xl_disk_t *)gd->real_devices)[disk].capacity =
+ xdi->disks[i].capacity;
register_disk(gd,
MKDEV(XLIDE_MAJOR, disk<<IDE_PARTN_BITS),
1<<IDE_PARTN_BITS,
@@ -112,7 +117,7 @@ int xlide_init(xen_disk_info_t *xdi)
xdi->disks[i].capacity);
disk++;
}
-
+
printk(KERN_ALERT
"XenoLinux Virtual IDE Device Driver installed [device: %d]\n",
XLIDE_MAJOR);
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c
index ddbd22d5f1..68566799bd 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c
@@ -79,6 +79,8 @@ int xlscsi_init(xen_disk_info_t *xdi)
for ( i = 0; i < xdi->count; i++ )
if ( xdi->disks[i].type == XEN_DISK_SCSI ) units++;
+ if ( units == 0 ) return 0;
+
/* Construct an appropriate gendisk structure. */
minors = units * (1<<SCSI_PARTN_BITS);
gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
@@ -89,7 +91,7 @@ int xlscsi_init(xen_disk_info_t *xdi)
gd->minor_shift = SCSI_PARTN_BITS;
gd->max_p = 1<<SCSI_PARTN_BITS;
gd->nr_real = units;
- gd->real_devices = NULL;
+ gd->real_devices = kmalloc(units * sizeof(xl_disk_t), GFP_KERNEL);
gd->next = NULL;
gd->fops = &xlscsi_block_fops;
gd->de_arr = kmalloc(sizeof(*gd->de_arr) * units, GFP_KERNEL);
@@ -98,6 +100,7 @@ int xlscsi_init(xen_disk_info_t *xdi)
memset(gd->part, 0, minors * sizeof(struct hd_struct));
memset(gd->de_arr, 0, sizeof(*gd->de_arr) * units);
memset(gd->flags, 0, sizeof(*gd->flags) * units);
+ memset(gd->real_devices, 0, sizeof(xl_disk_t) * units);
xlscsi_gendisk = gd;
add_gendisk(gd);
@@ -106,6 +109,8 @@ int xlscsi_init(xen_disk_info_t *xdi)
for ( i = 0; i < xdi->count; i++ )
{
if ( xdi->disks[i].type != XEN_DISK_SCSI ) continue;
+ ((xl_disk_t *)gd->real_devices)[disk].capacity =
+ xdi->disks[i].capacity;
register_disk(gd,
MKDEV(XLSCSI_MAJOR, disk<<SCSI_PARTN_BITS),
1<<SCSI_PARTN_BITS,
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 8dfa24fc09..da2086e22c 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
@@ -96,6 +96,8 @@ int __init xlseg_init(void)
for ( i = 0; i < xdi->count; i++ )
if ( xdi->disks[i].type == XEN_DISK_VIRTUAL ) units++;
+ if ( units == 0 ) return 0;
+
/* Construct an appropriate gendisk structure. */
minors = units * (1<<VIRT_PARTN_BITS);
gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
@@ -106,7 +108,7 @@ int __init xlseg_init(void)
gd->minor_shift = VIRT_PARTN_BITS;
gd->max_p = 1<<VIRT_PARTN_BITS;
gd->nr_real = units;
- gd->real_devices = NULL;
+ gd->real_devices = kmalloc(units * sizeof(xl_disk_t), GFP_KERNEL);
gd->next = NULL;
gd->fops = &xlsegment_block_fops;
gd->de_arr = kmalloc(sizeof(*gd->de_arr) * units, GFP_KERNEL);
@@ -115,6 +117,7 @@ int __init xlseg_init(void)
memset(gd->part, 0, minors * sizeof(struct hd_struct));
memset(gd->de_arr, 0, sizeof(*gd->de_arr) * units);
memset(gd->flags, 0, sizeof(*gd->flags) * units);
+ memset(gd->real_devices, 0, sizeof(xl_disk_t) * units);
xlsegment_gendisk = gd;
add_gendisk(gd);
@@ -123,6 +126,8 @@ int __init xlseg_init(void)
for ( i = 0; i < xdi->count; i++ )
{
if ( xdi->disks[i].type != XEN_DISK_VIRTUAL ) continue;
+ ((xl_disk_t *)gd->real_devices)[disk].capacity =
+ xdi->disks[i].capacity;
register_disk(gd,
MKDEV(XLVIRT_MAJOR, disk<<VIRT_PARTN_BITS),
1<<VIRT_PARTN_BITS,