ataraid: reload partitiontable
Hi!
Looks like the ataraid driver does not reread the partition table because of the ioctl call is not implemented. I cloned the code from the ide driver. The patch is attached.
The atomic_t stuff might be a bit paranoid, but I was not sure if it is save to use char. (Well, I use it only as a boolean busy flag...)
bye,
Wilfried
drivers/ide/ataraid.c +77 -5
@@ -44,11 +44,15 @@static int ataraid_open (struct inode * inode,struct file * filp);static int ataraid_release (struct inode * inode,struct file * filp);static void ataraid_split_request (request_queue_t *q,int rw,struct buffer_head * bh); +static int ataraid_revalidate (kdev_t dev,int maxusage);struct gendisk ataraid_gendisk;static int ataraid_gendisk_sizes[256 ];static int ataraid_readahead[256 ]; +static atomic_t busy[16 ]; +static unsigned int access_count[16 ]; +static DECLARE_WAIT_QUEUE_HEAD (busy_wait);static struct block_device_operations ataraid_fops = { open: ataraid_open,
@@ -70,6 +74,50 @@atomic_t count; }; +/* reread the partitions table */ +static int ataraid_revalidate (kdev_t dev,int maxusage) +{ +int target; +struct gendisk * gdev; +int max_p; +int start; +int i; +long flags; + + target =DEVICE_NR (dev); + gdev = &ataraid_gendisk; + +save_flags (flags); +cli (); +if (atomic_read (busy+target) || access_count[target] > maxusage) { +restore_flags (flags); +return -EBUSY ; + } +atomic_set (busy+target,1 ); +restore_flags (flags); + + max_p = gdev->max_p; + start = target << gdev->minor_shift; + +for (i=max_p -1 ; i >=0 ; i--) { +int minor = start + i; +invalidate_device (MKDEV (ATAMAJOR , minor),1 ); + gdev->part[minor].start_sect =0 ; + gdev->part[minor].nr_sects =0 ; + } + +#ifdef MAYBE_REINIT +MAYBE_REINIT ; +#endif + +grok_partitions (gdev, target,1 <<SHIFT , + ataraid_gendisk_sizes[MINOR (dev)>>SHIFT ]); + +atomic_set (busy+target,0 ); +wake_up (&busy_wait); +return 0 ; +} +/* stub fops functions */ static int ataraid_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
@@ -78,28 +126,52 @@ minor =MINOR (inode->i_rdev)>>SHIFT ;if ((ataraid_ops[minor])&&(ataraid_ops[minor]->ioctl)) -return (ataraid_ops[minor]->ioctl)(inode,file,cmd,arg); + { +switch (cmd) + { +case BLKRRPART : +if (!capable (CAP_SYS_ADMIN )) +return -EACCES ; +return ataraid_revalidate (inode->i_rdev,1 ); + +default : +return (ataraid_ops[minor]->ioctl)(inode,file,cmd,arg); + } + }return -EINVAL ; }static int ataraid_open (struct inode * inode,struct file * filp) { -int minor; +int minor, target, rc; minor =MINOR (inode->i_rdev)>>SHIFT ; + target =DEVICE_NR (inode->i_rdev);if ((ataraid_ops[minor])&&(ataraid_ops[minor]->open)) -return (ataraid_ops[minor]->open)(inode,filp); + { +while (atomic_read (busy+target)) +sleep_on (&busy_wait); + + rc=(ataraid_ops[minor]->open)(inode,filp); + access_count[target]++; +return rc; + }return -EINVAL ; }static int ataraid_release (struct inode * inode,struct file * filp) { -int minor; +int minor, target, rc; minor =MINOR (inode->i_rdev)>>SHIFT ; + target =DEVICE_NR (inode->i_rdev);if ((ataraid_ops[minor])&&(ataraid_ops[minor]->release)) -return (ataraid_ops[minor]->release)(inode,filp); + { + rc=(ataraid_ops[minor]->release)(inode,filp); + access_count[target]--; +return rc; + }return -EINVAL ; }