ia64/xen-unstable

changeset 265:789c47e6318d

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).
author kaf24@labyrinth.cl.cam.ac.uk
date Fri Mar 07 11:29:57 2003 +0000 (2003-03-07)
parents 2e679e814ec4
children 8e200807a8b2
files xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c
line diff
     1.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c	Fri Mar 07 01:38:49 2003 +0000
     1.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c	Fri Mar 07 11:29:57 2003 +0000
     1.3 @@ -34,7 +34,7 @@ static int nr_pending;
     1.4  /* Convert from a XenoLinux major device to the Xen-level 'physical' device */
     1.5  static inline unsigned short xldev_to_physdev(kdev_t xldev) 
     1.6  {
     1.7 -    unsigned short physdev;
     1.8 +    unsigned short physdev = 0;
     1.9  
    1.10      switch ( MAJOR(xldev) ) 
    1.11      { 
    1.12 @@ -49,10 +49,9 @@ static inline unsigned short xldev_to_ph
    1.13      case XLVIRT_MAJOR:
    1.14          physdev = XENDEV_VIRTUAL;
    1.15          break;
    1.16 +    } 
    1.17  
    1.18 -    default: 
    1.19 -        BUG();
    1.20 -    } 
    1.21 +    if ( physdev == 0 ) BUG();
    1.22  
    1.23      physdev += (MINOR(xldev) >> PARTN_SHIFT);
    1.24  
    1.25 @@ -84,23 +83,36 @@ static inline struct gendisk *xldev_to_g
    1.26      return gd;
    1.27  }
    1.28  
    1.29 +
    1.30 +static inline xl_disk_t *xldev_to_xldisk(kdev_t xldev)
    1.31 +{
    1.32 +    struct gendisk *gd = xldev_to_gendisk(xldev);
    1.33 +    return (xl_disk_t *)gd->real_devices + (MINOR(xldev) >> PARTN_SHIFT);
    1.34 +}
    1.35 +
    1.36 +
    1.37  int xenolinux_block_open(struct inode *inode, struct file *filep)
    1.38  {
    1.39 -    DPRINTK("xenolinux_block_open\n"); 
    1.40 +    xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
    1.41 +    disk->usage++;
    1.42 +    DPRINTK("xenolinux_block_open\n");
    1.43      return 0;
    1.44  }
    1.45  
    1.46 +
    1.47  int xenolinux_block_release(struct inode *inode, struct file *filep)
    1.48  {
    1.49 +    xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
    1.50 +    disk->usage--;
    1.51      DPRINTK("xenolinux_block_release\n");
    1.52      return 0;
    1.53  }
    1.54  
    1.55  
    1.56 -
    1.57  int xenolinux_block_ioctl(struct inode *inode, struct file *filep,
    1.58  			  unsigned command, unsigned long argument)
    1.59  {
    1.60 +    kdev_t dev = inode->i_rdev;
    1.61      struct hd_geometry *geo = (struct hd_geometry *)argument;
    1.62      struct gendisk *gd;     
    1.63      struct hd_struct *part; 
    1.64 @@ -112,10 +124,10 @@ int xenolinux_block_ioctl(struct inode *
    1.65      if (!inode)                  return -EINVAL;
    1.66  
    1.67      DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
    1.68 -                  command, (long) argument, inode->i_rdev); 
    1.69 +                  command, (long) argument, dev); 
    1.70    
    1.71 -    gd = xldev_to_gendisk(inode->i_rdev);
    1.72 -    part = &gd->part[MINOR(inode->i_rdev)]; 
    1.73 +    gd = xldev_to_gendisk(dev);
    1.74 +    part = &gd->part[MINOR(dev)]; 
    1.75  
    1.76      switch ( command )
    1.77      {
    1.78 @@ -125,25 +137,26 @@ int xenolinux_block_ioctl(struct inode *
    1.79  
    1.80      case BLKRRPART:                               /* re-read partition table */
    1.81          DPRINTK_IOCTL("   BLKRRPART: %x\n", BLKRRPART); 
    1.82 -	break;
    1.83 +        if ( !capable(CAP_SYS_ADMIN) ) return -EACCES;
    1.84 +        return xenolinux_block_revalidate(dev);
    1.85  
    1.86      case BLKSSZGET:
    1.87 -	switch ( MAJOR(inode->i_rdev) )
    1.88 +	switch ( MAJOR(dev) )
    1.89          {
    1.90  	case XLIDE_MAJOR: 
    1.91  	    DPRINTK_IOCTL("   BLKSSZGET: %x 0x%x\n", BLKSSZGET, 
    1.92 -			  xlide_hwsect(MINOR(inode->i_rdev)));
    1.93 -	    return xlide_hwsect(MINOR(inode->i_rdev)); 
    1.94 +			  xlide_hwsect(MINOR(dev)));
    1.95 +	    return xlide_hwsect(MINOR(dev)); 
    1.96  
    1.97  	case XLSCSI_MAJOR: 
    1.98  	    DPRINTK_IOCTL("   BLKSSZGET: %x 0x%x\n", BLKSSZGET,
    1.99 -			  xlscsi_hwsect(MINOR(inode->i_rdev)));
   1.100 -	    return xlscsi_hwsect(MINOR(inode->i_rdev)); 
   1.101 +			  xlscsi_hwsect(MINOR(dev)));
   1.102 +	    return xlscsi_hwsect(MINOR(dev)); 
   1.103  
   1.104          case XLVIRT_MAJOR:
   1.105  	    DPRINTK_IOCTL("   BLKSSZGET: %x 0x%x\n", BLKSSZGET, 
   1.106 -			  xlsegment_hwsect(MINOR(inode->i_rdev)));
   1.107 -	    return xlsegment_hwsect(MINOR(inode->i_rdev)); 
   1.108 +			  xlsegment_hwsect(MINOR(dev)));
   1.109 +	    return xlsegment_hwsect(MINOR(dev)); 
   1.110  
   1.111  	default: 
   1.112  	    printk(KERN_ALERT "BLKSSZGET ioctl() on bogus disk!\n"); 
   1.113 @@ -202,10 +215,33 @@ int xenolinux_block_check(kdev_t dev)
   1.114  
   1.115  int xenolinux_block_revalidate(kdev_t dev)
   1.116  {
   1.117 -    DPRINTK("xenolinux_block_revalidate\n"); 
   1.118 +    struct gendisk *gd = xldev_to_gendisk(dev);
   1.119 +    xl_disk_t *disk = xldev_to_xldisk(dev);
   1.120 +    unsigned long flags;
   1.121 +    int i;
   1.122 +    
   1.123 +    spin_lock_irqsave(&io_request_lock, flags);
   1.124 +    if ( disk->usage > 1 )
   1.125 +    {
   1.126 +        spin_unlock_irqrestore(&io_request_lock, flags);
   1.127 +        return -EBUSY;
   1.128 +    }
   1.129 +    spin_unlock_irqrestore(&io_request_lock, flags);
   1.130 +
   1.131 +    for ( i = 0; i < (1 << PARTN_SHIFT); i++ )
   1.132 +    {
   1.133 +        invalidate_device(dev + i, 1);
   1.134 +        gd->part[dev + i].start_sect = 0;
   1.135 +        gd->part[dev + i].nr_sects = 0;
   1.136 +    }
   1.137 +
   1.138 +    grok_partitions(gd, MINOR(dev) >> PARTN_SHIFT,
   1.139 +                    1 << PARTN_SHIFT, disk->capacity);
   1.140 +
   1.141      return 0;
   1.142  }
   1.143  
   1.144 +
   1.145  /*
   1.146   * hypervisor_request
   1.147   *
     2.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h	Fri Mar 07 01:38:49 2003 +0000
     2.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.h	Fri Mar 07 11:29:57 2003 +0000
     2.3 @@ -35,6 +35,16 @@
     2.4  #define DPRINTK_IOCTL(_f, _a...) ((void)0)
     2.5  #endif
     2.6  
     2.7 +/*
     2.8 + * We have one of these per XL-IDE, XL-SCSI, and XL-VIRT device.
     2.9 + * They hang in an array off the gendisk structure. We may end up putting
    2.10 + * all kinds of interesting stuff here :-)
    2.11 + */
    2.12 +typedef struct xl_disk {
    2.13 +    int usage;
    2.14 +    unsigned long capacity;
    2.15 +} xl_disk_t;
    2.16 +
    2.17  /* Generic layer. */
    2.18  extern int xenolinux_control_msg(int operration, char *buffer);
    2.19  extern int xenolinux_block_open(struct inode *inode, struct file *filep);
     3.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c	Fri Mar 07 01:38:49 2003 +0000
     3.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c	Fri Mar 07 11:29:57 2003 +0000
     3.3 @@ -78,6 +78,8 @@ int xlide_init(xen_disk_info_t *xdi)
     3.4      for ( i = 0; i < xdi->count; i++ )
     3.5          if ( xdi->disks[i].type == XEN_DISK_IDE ) units++;
     3.6  
     3.7 +    if ( units == 0 ) return 0;
     3.8 +
     3.9      /* Construct an appropriate gendisk structure. */
    3.10      minors    = units * (1<<IDE_PARTN_BITS);
    3.11      gd        = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
    3.12 @@ -88,7 +90,7 @@ int xlide_init(xen_disk_info_t *xdi)
    3.13      gd->minor_shift  = IDE_PARTN_BITS; 
    3.14      gd->max_p	     = 1<<IDE_PARTN_BITS;
    3.15      gd->nr_real	     = units;           
    3.16 -    gd->real_devices = NULL;          
    3.17 +    gd->real_devices = kmalloc(units * sizeof(xl_disk_t), GFP_KERNEL);
    3.18      gd->next	     = NULL;            
    3.19      gd->fops         = &xlide_block_fops;
    3.20      gd->de_arr       = kmalloc(sizeof(*gd->de_arr) * units, GFP_KERNEL);
    3.21 @@ -97,14 +99,17 @@ int xlide_init(xen_disk_info_t *xdi)
    3.22      memset(gd->part,  0, minors * sizeof(struct hd_struct));
    3.23      memset(gd->de_arr, 0, sizeof(*gd->de_arr) * units);
    3.24      memset(gd->flags, 0, sizeof(*gd->flags) * units);
    3.25 +    memset(gd->real_devices, 0, sizeof(xl_disk_t) * units);
    3.26      xlide_gendisk = gd;
    3.27      add_gendisk(gd);
    3.28 -
    3.29 +    
    3.30      /* Now register each disk in turn. */
    3.31      disk = 0;
    3.32      for ( i = 0; i < xdi->count; i++ )
    3.33      {
    3.34          if ( xdi->disks[i].type != XEN_DISK_IDE ) continue;
    3.35 +        ((xl_disk_t *)gd->real_devices)[disk].capacity =
    3.36 +            xdi->disks[i].capacity;
    3.37          register_disk(gd, 
    3.38                        MKDEV(XLIDE_MAJOR, disk<<IDE_PARTN_BITS), 
    3.39                        1<<IDE_PARTN_BITS, 
    3.40 @@ -112,7 +117,7 @@ int xlide_init(xen_disk_info_t *xdi)
    3.41                        xdi->disks[i].capacity);
    3.42          disk++;
    3.43      }
    3.44 -   
    3.45 +
    3.46      printk(KERN_ALERT 
    3.47  	   "XenoLinux Virtual IDE Device Driver installed [device: %d]\n",
    3.48  	   XLIDE_MAJOR);
     4.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c	Fri Mar 07 01:38:49 2003 +0000
     4.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c	Fri Mar 07 11:29:57 2003 +0000
     4.3 @@ -79,6 +79,8 @@ int xlscsi_init(xen_disk_info_t *xdi)
     4.4      for ( i = 0; i < xdi->count; i++ )
     4.5          if ( xdi->disks[i].type == XEN_DISK_SCSI ) units++;
     4.6  
     4.7 +    if ( units == 0 ) return 0;
     4.8 +
     4.9      /* Construct an appropriate gendisk structure. */
    4.10      minors    = units * (1<<SCSI_PARTN_BITS);
    4.11      gd        = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
    4.12 @@ -89,7 +91,7 @@ int xlscsi_init(xen_disk_info_t *xdi)
    4.13      gd->minor_shift  = SCSI_PARTN_BITS; 
    4.14      gd->max_p	     = 1<<SCSI_PARTN_BITS;
    4.15      gd->nr_real	     = units;           
    4.16 -    gd->real_devices = NULL;          
    4.17 +    gd->real_devices = kmalloc(units * sizeof(xl_disk_t), GFP_KERNEL);
    4.18      gd->next	     = NULL;            
    4.19      gd->fops         = &xlscsi_block_fops;
    4.20      gd->de_arr       = kmalloc(sizeof(*gd->de_arr) * units, GFP_KERNEL);
    4.21 @@ -98,6 +100,7 @@ int xlscsi_init(xen_disk_info_t *xdi)
    4.22      memset(gd->part,  0, minors * sizeof(struct hd_struct));
    4.23      memset(gd->de_arr, 0, sizeof(*gd->de_arr) * units);
    4.24      memset(gd->flags, 0, sizeof(*gd->flags) * units);
    4.25 +    memset(gd->real_devices, 0, sizeof(xl_disk_t) * units);
    4.26      xlscsi_gendisk = gd;
    4.27      add_gendisk(gd);
    4.28  
    4.29 @@ -106,6 +109,8 @@ int xlscsi_init(xen_disk_info_t *xdi)
    4.30      for ( i = 0; i < xdi->count; i++ )
    4.31      {
    4.32          if ( xdi->disks[i].type != XEN_DISK_SCSI ) continue;
    4.33 +        ((xl_disk_t *)gd->real_devices)[disk].capacity =
    4.34 +            xdi->disks[i].capacity;
    4.35          register_disk(gd,
    4.36                        MKDEV(XLSCSI_MAJOR, disk<<SCSI_PARTN_BITS), 
    4.37                        1<<SCSI_PARTN_BITS, 
     5.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c	Fri Mar 07 01:38:49 2003 +0000
     5.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c	Fri Mar 07 11:29:57 2003 +0000
     5.3 @@ -96,6 +96,8 @@ int __init xlseg_init(void)
     5.4      for ( i = 0; i < xdi->count; i++ )
     5.5          if ( xdi->disks[i].type == XEN_DISK_VIRTUAL ) units++;
     5.6  
     5.7 +    if ( units == 0 ) return 0;
     5.8 +
     5.9      /* Construct an appropriate gendisk structure. */
    5.10      minors    = units * (1<<VIRT_PARTN_BITS);
    5.11      gd        = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
    5.12 @@ -106,7 +108,7 @@ int __init xlseg_init(void)
    5.13      gd->minor_shift  = VIRT_PARTN_BITS; 
    5.14      gd->max_p	     = 1<<VIRT_PARTN_BITS;
    5.15      gd->nr_real	     = units;           
    5.16 -    gd->real_devices = NULL;          
    5.17 +    gd->real_devices = kmalloc(units * sizeof(xl_disk_t), GFP_KERNEL);
    5.18      gd->next	     = NULL;            
    5.19      gd->fops         = &xlsegment_block_fops;
    5.20      gd->de_arr       = kmalloc(sizeof(*gd->de_arr) * units, GFP_KERNEL);
    5.21 @@ -115,6 +117,7 @@ int __init xlseg_init(void)
    5.22      memset(gd->part,  0, minors * sizeof(struct hd_struct));
    5.23      memset(gd->de_arr, 0, sizeof(*gd->de_arr) * units);
    5.24      memset(gd->flags, 0, sizeof(*gd->flags) * units);
    5.25 +    memset(gd->real_devices, 0, sizeof(xl_disk_t) * units);
    5.26      xlsegment_gendisk = gd;
    5.27      add_gendisk(gd);
    5.28  
    5.29 @@ -123,6 +126,8 @@ int __init xlseg_init(void)
    5.30      for ( i = 0; i < xdi->count; i++ )
    5.31      {
    5.32          if ( xdi->disks[i].type != XEN_DISK_VIRTUAL ) continue;
    5.33 +        ((xl_disk_t *)gd->real_devices)[disk].capacity =
    5.34 +            xdi->disks[i].capacity;
    5.35          register_disk(gd, 
    5.36                        MKDEV(XLVIRT_MAJOR, disk<<VIRT_PARTN_BITS), 
    5.37                        1<<VIRT_PARTN_BITS,