]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] partition table flush/read cleanup
authorAlexander Viro <viro@math.psu.edu>
Sat, 10 Aug 2002 09:21:49 +0000 (02:21 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Sat, 10 Aug 2002 09:21:49 +0000 (02:21 -0700)
Big One.  Flushing/rereading partition tables is taken from
->revalidate() for partitioned devices; now it's done in the
caller (check_disk_change()).  BLKRRPART handling also moved
out of drivers - they are still allowed to override it (DAC960
and i2o are the only remaining ones), but common case is handled
in fs/block_dev.c.

Note: we are still only shifting stuff - bd_sem deadlocks in
check_disk_change() are still there.  However, now we have all
relevant code outside of drivers and that will allow to fix the
thing (see next patches).

25 files changed:
drivers/acorn/block/mfmhd.c
drivers/block/acsi.c
drivers/block/blkpg.c
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/paride/pd.c
drivers/block/ps2esdi.c
drivers/block/umem.c
drivers/block/xd.c
drivers/block/xd.h
drivers/ide/hd.c
drivers/ide/ide-cd.c
drivers/ide/ide-tape.c
drivers/ide/ide.c
drivers/ide/ioctl.c
drivers/ide/main.c
drivers/mtd/ftl.c
drivers/mtd/nftlcore.c
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/xpram.c
drivers/scsi/sd.c
fs/block_dev.c
fs/devfs/base.c
include/linux/fs.h
include/linux/ide.h

index 06fb336666e208a4da8703fd7214050af4c16d0f..c124dabac6966bed7b8717db9be41ee674b660c6 100644 (file)
@@ -226,7 +226,6 @@ static char *Copy_buffer;
 static void mfm_seek(void);
 static void mfm_rerequest(void);
 static void mfm_request(void);
-static int mfm_reread_partitions(kdev_t dev);
 static void mfm_specify (void);
 static void issue_request(int dev, unsigned int block, unsigned int nsect,
                          struct request *req);
@@ -1165,40 +1164,30 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a
 {
        struct hd_geometry *geo = (struct hd_geometry *) arg;
        kdev_t dev;
-       int device, major, minor, err;
+       int device, minor, err;
 
        if (!inode || !(dev = inode->i_rdev))
                return -EINVAL;
 
-       major = major(dev);
        minor = minor(dev);
 
        device = DEVICE_NR(minor(inode->i_rdev)), err;
        if (device >= mfm_drives)
                return -EINVAL;
 
-       switch (cmd) {
-       case HDIO_GETGEO:
-               if (!arg)
-                       return -EINVAL;
-               if (put_user (mfm_info[device].heads, &geo->heads))
-                       return -EFAULT;
-               if (put_user (mfm_info[device].sectors, &geo->sectors))
-                       return -EFAULT;
-               if (put_user (mfm_info[device].cylinders, &geo->cylinders))
-                       return -EFAULT;
-               if (put_user (mfm[minor].start_sect, &geo->start))
-                       return -EFAULT;
-               return 0;
-
-       case BLKRRPART:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EACCES;
-               return mfm_reread_partitions(dev);
-
-       default:
+       if (cmd != HDIO_GETGEO)
                return -EINVAL;
-       }
+       if (!arg)
+               return -EINVAL;
+       if (put_user (mfm_info[device].heads, &geo->heads))
+               return -EFAULT;
+       if (put_user (mfm_info[device].sectors, &geo->sectors))
+               return -EFAULT;
+       if (put_user (mfm_info[device].cylinders, &geo->cylinders))
+               return -EFAULT;
+       if (put_user (mfm[minor].start_sect, &geo->start))
+               return -EFAULT;
+       return 0;
 }
 
 static int mfm_open(struct inode *inode, struct file *file)
@@ -1396,25 +1385,6 @@ int mfm_init (void)
        return 0;
 }
 
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed MFM disk, and then re-read the new partition table.
- */
-static int mfm_reread_partitions(kdev_t dev)
-{
-       unsigned int unit = DEVICE_NR(minor(dev));
-       kdev_t device = mk_kdev(MAJOR_NR, unit << mfm_gendisk.minor_shift);
-       int err = dev_lock_part(device);
-       if (err)
-               return err;
-       wipe_partitions(device);
-       /* Divide by 2, since sectors are 2 times smaller than usual ;-) */
-       grok_partitions(device, mfm_info[unit].heads *
-                   mfm_info[unit].cylinders * mfm_info[unit].sectors / 2);
-       dev_unlock_part(device);
-       return 0;
-}
-
 #ifdef MODULE
 
 MODULE_LICENSE("GPL");
index de86813ad9a764ef4ec4bb258da2029bf63f2624..b5f21ae4bed02d3f08ff5558ad32d98ff3fe8e43 100644 (file)
@@ -369,7 +369,6 @@ static void acsi_prevent_removal( int target, int flag );
 static int acsi_change_blk_size( int target, int lun);
 static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
 static void acsi_geninit(void);
-static int revalidate_acsidisk( kdev_t dev, int maxusage );
 static int acsi_revalidate (kdev_t);
 
 /************************* End of Prototypes **************************/
@@ -1108,19 +1107,12 @@ static int acsi_ioctl( struct inode *inode, struct file *file,
                put_user(get_start_sect(inode->i_bdev), &geo->start);
                return 0;
          }
-               
          case SCSI_IOCTL_GET_IDLUN:
                /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
                put_user( acsi_info[dev].target | (acsi_info[dev].lun << 8),
                                  &((Scsi_Idlun *) arg)->dev_id );
                put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
                return 0;
-               
-         case BLKRRPART: /* Re-read partition tables */
-               if (!capable(CAP_SYS_ADMIN)) 
-                       return -EACCES;
-               return revalidate_acsidisk(inode->i_rdev, 1);
-
          default:
                return -EINVAL;
        }
@@ -1809,20 +1801,11 @@ void cleanup_module(void)
  *
  */
 
-static int revalidate_acsidisk(kdev_t dev, int maxusage )
+static int acsi_revalidate(kdev_t dev)
 {
        int unit = DEVICE_NR(minor(dev));
        struct acsi_info_struct *aip = &acsi_info[unit];
-       kdev_t device = mk_kdev(MAJOR_NR, unit<<4);
-       int res = dev_lock_part(device);
-
-       if (res < 0)
-               return res;
-
-       res = wipe_partitions(device);
-
        stdma_lock( NULL, NULL );
-
        if (acsi_devinit(aip) != DEV_SUPPORTED) {
                printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n",
                       aip->target, aip->lun);
@@ -1834,16 +1817,6 @@ static int revalidate_acsidisk(kdev_t dev, int maxusage )
 
        ENABLE_IRQ();
        stdma_release();
-
-       if (!res)
-               grok_partitions(device, aip->size);
-
-       dev_unlock_part(device);
-       return res;
-}
-
-
-static int acsi_revalidate (kdev_t dev)
-{
-  return revalidate_acsidisk (dev, 0);
+       acsi_part[minor(dev)].nr_sects = aip->size;
+       return 0;
 }
index 15e028f28074f727c102056b80030b6a94e9765e..1d13a84a991920249834518145c49d6053420621 100644 (file)
@@ -269,12 +269,6 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg)
                        /* size in bytes */
                        ullval = bdev->bd_inode->i_size;
                        return put_user(ullval, (u64 *) arg);
-#if 0
-               case BLKRRPART: /* Re-read partition tables */
-                       if (!capable(CAP_SYS_ADMIN)) 
-                               return -EACCES;
-                       return reread_partitions(dev, 1);
-#endif
 
                case BLKPG:
                        return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg);
index f8a34fe2bb8596bf46c4e66ecca433853cebc8fe..df07b097193d150c925f63e57c1271313384858d 100644 (file)
@@ -106,7 +106,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
 static int revalidate_allvol(kdev_t dev);
 static int revalidate_logvol(kdev_t dev, int maxusage);
-static int frevalidate_logvol(kdev_t dev);
+static int cciss_revalidate(kdev_t dev);
 static int deregister_disk(int ctlr, int logvol);
 static int register_new_disk(kdev_t dev, int cltr);
 
@@ -130,7 +130,7 @@ static struct block_device_operations cciss_fops  = {
        open:                   cciss_open, 
        release:                cciss_release,
         ioctl:                 cciss_ioctl,
-       revalidate:             frevalidate_logvol,
+       revalidate:             cciss_revalidate,
 };
 
 #include "cciss_scsi.c"                /* For SCSI tape support */
@@ -437,8 +437,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                 return(0);
        }
 
-       case BLKRRPART:
-               return revalidate_logvol(inode->i_rdev, 1);
        case CCISS_GETPCIINFO:
        {
                cciss_pci_info_struct pciinfo;
@@ -724,6 +722,15 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
        
 }
 
+static int cciss_revalidate(kdev_t dev)
+{
+        int ctlr = major(dev) - MAJOR_NR;
+       int target = minor(dev) >> NWD_SHIFT;
+        struct gendisk *gdev = &(hba[ctlr]->gendisk);
+       gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blocks;
+       return 0;
+}
+
 /* Borrowed and adapted from sd.c */
 /*
  * FIXME: we are missing the exclusion with ->open() here - it can happen
@@ -762,14 +769,6 @@ leave:
         return res;
 }
 
-static int frevalidate_logvol(kdev_t dev)
-{
-#ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss: frevalidate has been called\n");
-#endif /* CCISS_DEBUG */ 
-       return revalidate_logvol(dev, 0);
-}
-
 /*
  * revalidate_allvol is for online array config utilities.  After a
  * utility reconfigures the drives in the array, it can use this function
index 4a4376ae7384d61d6c417bfa7f714b02d2ea7d89..26eee9bafac4d35629f63c3835c56bfcd481a683 100644 (file)
@@ -153,7 +153,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout);
 
 static void do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
 static void ida_timer(unsigned long tdata);
-static int frevalidate_logvol(kdev_t dev);
+static int ida_revalidate(kdev_t dev);
 static int revalidate_logvol(kdev_t dev, int maxusage);
 static int revalidate_allvol(kdev_t dev);
 
@@ -188,7 +188,7 @@ static struct block_device_operations ida_fops  = {
        open:           ida_open,
        release:        ida_release,
        ioctl:          ida_ioctl,
-       revalidate:     frevalidate_logvol,
+       revalidate:     ida_revalidate,
 };
 
 
@@ -1107,8 +1107,6 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
                                 sizeof(drv_info_t)))
                        return -EFAULT;
                return 0;
-       case BLKRRPART:
-               return revalidate_logvol(inode->i_rdev, 1);
        case IDAPASSTHRU:
                if (!capable(CAP_SYS_RAWIO)) return -EPERM;
                if (copy_from_user(&my_io, io, sizeof(my_io)))
@@ -1441,11 +1439,6 @@ DBG(
        return (IO_OK);
 }
 
-static int frevalidate_logvol(kdev_t dev)
-{
-       return revalidate_logvol(dev, 0);
-}
-
 /*
  * revalidate_allvol is for online array config utilities.  After a
  * utility reconfigures the drives in the array, it can use this function
@@ -1505,6 +1498,15 @@ static int revalidate_allvol(kdev_t dev)
        return 0;
 }
 
+static int ida_revalidate(kdev_t dev)
+{
+        int ctlr = major(dev) - MAJOR_NR;
+       int target = DEVICE_NR(dev);
+        struct gendisk *gdev = &ida_gendisk[ctlr];
+       gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blocks;
+       return 0;
+}
+
 /* Borrowed and adapted from sd.c */
 /*
  * FIXME: exclusion with ->open()
index 0865400c35bc4053e155212f541688132cc04149..6d6b1ab6a7c424d3882c2e652a6808913d752372 100644 (file)
@@ -404,10 +404,6 @@ static int pd_ioctl(struct inode *inode,struct file *file,
                }
                put_user(get_start_sect(inode->i_bdev), (long *)&geo->start);
                return 0;
-           case BLKRRPART:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EACCES;
-               return pd_revalidate(inode->i_rdev);
            default:
                return -EINVAL;
        }
@@ -439,23 +435,13 @@ static int pd_check_media( kdev_t dev)
 static int pd_revalidate(kdev_t dev)
 {
        int unit = DEVICE_NR(dev);
-       kdev_t device = mk_kdev(MAJOR_NR, unit << PD_BITS);
-       int res;
-
        if ((unit >= PD_UNITS) || !PD.present)
                return -ENODEV;
-
-       res = dev_lock_part(device);
-       if (res < 0)
-               return res;
-       res = wipe_partitions(device);
-
-       if (res == 0 && pd_identify(unit))
-               grok_partitions(device, PD.capacity);
-
-       dev_unlock_part(device);
-        return res;
+       if (pd_identify(unit))
+               pd_hd[minor(dev)].nr_sects = PD.capacity;
+       else
+               pd_hd[minor(dev)].nr_sects = 0;
+        return 0;
 }
 
 #define        WR(c,r,v)       pi_write_regr(PI,c,r,v)
index 61bf283ec808f0feec63f3758623eeb79610640e..cd0c28556f92491b3491a83ad354c089a839efd5 100644 (file)
@@ -95,8 +95,6 @@ static int ps2esdi_open(struct inode *inode, struct file *file);
 static int ps2esdi_ioctl(struct inode *inode, struct file *file,
                         u_int cmd, u_long arg);
 
-static int ps2esdi_reread_partitions(kdev_t dev);
-
 static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
 
 static void dump_cmd_complete_status(u_int int_ret_code);
@@ -1080,53 +1078,18 @@ static int ps2esdi_open(struct inode *inode, struct file *file)
 static int ps2esdi_ioctl(struct inode *inode,
                         struct file *file, u_int cmd, u_long arg)
 {
-
        struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
        int dev = DEVICE_NR(inode->i_rdev), err;
 
-       if (inode && (dev < ps2esdi_drives))
-               switch (cmd) {
-               case HDIO_GETGEO:
-                       if (arg) {
-                               if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
-                                       return (err);
-                               put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
-                               put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
-                               put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
-                               put_user(get_start_sect(inode->b_rdev),
-                                           (long *) &geometry->start);
-
-                               return 0;
-                       }
-                       break;
-
-               case BLKRRPART:
-                        if (!capable(CAP_SYS_ADMIN)) 
-                               return -EACCES;
-                       return (ps2esdi_reread_partitions(inode->i_rdev));
-               }
-       return (-EINVAL);
-}
-
-
-
-static int ps2esdi_reread_partitions(kdev_t dev)
-{
-       int target = DEVICE_NR(dev);
-       kdev_t device = mk_kdev(MAJOR_NR, target << 6);
-       int res = dev_lock_part(device);
-
-       if (res < 0)
-               return res;
-
-       res = wipe_partitions(device);
-       if (res == 0)
-               grok_partitions(device, ps2esdi_info[target].head
-                               * ps2esdi_info[target].cyl
-                               * ps2esdi_info[target].sect);
-       dev_unlock_part(device);
-       return res;
+       if (cmd != HDIO_GETGEO)
+               return -EINVAL;
+       if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
+               return (err);
+       put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
+       put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
+       put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
+       put_user(get_start_sect(inode->b_rdev), (long *) &geometry->start);
+       return 0;
 }
 
 static void ps2esdi_reset_timer(unsigned long unused)
index 58d6fc51fd381f50787458851cd1d9b29effa7cc..e81e9c08b0fbbb9fabdd4ba201c4893f340404ea 100644 (file)
@@ -818,14 +818,7 @@ static void del_battery_timer(void)
 static int mm_revalidate(kdev_t i_rdev)
 {
        int card_number = DEVICE_NR(i_rdev);
-       kdev_t device = mk_kdev(MAJOR_NR, card_number << MM_SHIFT);
-       int res = dev_lock_part(device);
-       if (res < 0)
-               return res;
-       wipe_partitions(device);
-       printk(KERN_INFO "mm partition check: (%d)\n", card_number);
-       grok_partitions(device, cards[card_number].mm_size << 1);
-       dev_unlock_part(device);
+       mm_partitions[minor(i_rdev)] = cards[card_number].mm_size << 1;
        return 0;
 }
 /*
@@ -835,22 +828,10 @@ static int mm_revalidate(kdev_t i_rdev)
 */
 static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
 {
-       int err, size, card_number;
-       struct hd_geometry geo;
-       unsigned int minor;
-
-       if (!i)
-               return -EINVAL;
-
-       minor       = minor(i->i_rdev);
-       card_number = (minor >> MM_SHIFT);
-
-
-       switch(cmd) {
-       case BLKRRPART:
-               return (mm_revalidate(i->i_rdev));
-
-       case HDIO_GETGEO:
+       if (cmd == case HDIO_GETGEO) {
+               unsigned int minor = minor(i->i_rdev);
+               int err, size, card_number = (minor >> MM_SHIFT);
+               struct hd_geometry geo;
                /*
                 * get geometry: we have to fake one...  trim the size to a
                 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
@@ -867,12 +848,9 @@ static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned
                if (copy_to_user((void *) arg, &geo, sizeof(geo)))
                        return -EFAULT;
                return 0;
-
-       default:
-               return -EINVAL;
        }
 
-       return -ENOTTY; /* unknown command */
+       return -EINVAL;
 }
 /*
 -----------------------------------------------------------------------------------
index e45b10702cd639615fedc2ee9bdfcd460b15b8c7..8c8f3652bba65b547539a89ac4732e6bfbb95287 100644 (file)
@@ -330,37 +330,11 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
                        return put_user(!nodma, (long *) arg);
                case HDIO_GET_MULTCOUNT:
                        return put_user(xd_maxsectors, (long *) arg);
-               case BLKRRPART:
-                       if (!capable(CAP_SYS_ADMIN)) 
-                               return -EACCES;
-                       return xd_reread_partitions(inode->i_rdev);
-
                default:
                        return -EINVAL;
        }
 }
 
-/* xd_reread_partitions: rereads the partition table from a drive */
-static int xd_reread_partitions(kdev_t dev)
-{
-       int target = DEVICE_NR(dev);
-       kdev_t device = mk_kdev(MAJOR_NR, target << 6);
-       int res = dev_lock_part(device);
-       
-       if (res < 0)
-               return 0;
-
-       res = wipe_partitions(device);
-       if (!res)
-               grok_partitions(device, xd_info[target].heads
-                               * xd_info[target].cylinders
-                               * xd_info[target].sectors);
-
-       dev_unlock_part(device);
-
-       return res;
-}
-
 /* xd_readwrite: handle a read/write request */
 static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count)
 {
index 3df2d4e984102e0d353478ce7fdf3b707c724a29..fe0f419da4608d608ae803a601b39006127f8373 100644 (file)
@@ -113,7 +113,6 @@ static void xd_geninit (void);
 static int xd_open (struct inode *inode,struct file *file);
 static void do_xd_request (request_queue_t * q);
 static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
-static int xd_reread_partitions (kdev_t dev);
 static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count);
 static void xd_recalibrate (u_char drive);
 
index 750648bfb34db3b301d028d540d1f64938afa39e..148b10bf981c31a6282bc91ed9ac557d80d9ebcc 100644 (file)
 
 static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
 
-static int revalidate_hddisk(kdev_t, int);
-
 #define TIMEOUT_VALUE  (6*HZ)
 #define        HD_DELAY        0
 
@@ -683,11 +681,6 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                        return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
                }
 
-               case BLKRRPART: /* Re-read partition tables */
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EACCES;
-                       return revalidate_hddisk(inode->i_rdev, 1);
-
                default:
                        return -EINVAL;
        }
@@ -879,32 +872,6 @@ int __init hd_init(void)
        return 0;
 }
 
-#define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl)
-/* We assume that the BIOS parameters do not change, so the disk capacity
-   will not change */
-
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed disk, and then re-read the new partition table.
- * If we are revalidating a disk because of a media change, then we
- * enter with usage == 0.  If we are using an ioctl, we automatically have
- * usage == 1 (we need an open channel to use an ioctl :-), so this
- * is our limit.
- */
-static int revalidate_hddisk(kdev_t dev, int maxusage)
-{
-       int target = DEVICE_NR(dev);
-       kdev_t device = mk_kdev(MAJOR_NR, target << 6);
-       int res = dev_lock_part(device);
-       if (res < 0)
-               return res;
-       res = wipe_partitions(device);
-       if (!res)
-               grok_partitions(device, CAPACITY);
-       dev_unlock_part(device);
-       return res;
-}
-
 static int parse_hd_setup (char *line) {
        int ints[6];
 
index a8023d010d57edb0c26724ec6a58df6d502cd4e7..72a8a173638c20bcfacdd854f6daa0d08aded2fa 100644 (file)
@@ -2875,19 +2875,8 @@ int ide_cdrom_check_media_change(struct ata_device *drive)
 static
 void ide_cdrom_revalidate(struct ata_device *drive)
 {
-       struct cdrom_info *info = drive->driver_data;
-       struct atapi_toc *toc;
        struct request_sense sense;
-
        cdrom_read_toc(drive, &sense);
-
-       if (!CDROM_STATE_FLAGS(drive)->toc_valid)
-               return;
-
-       toc = info->toc;
-
-       /* for general /dev/cdrom like mounting, one big disc */
-       drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
 }
 
 static sector_t ide_cdrom_capacity(struct ata_device *drive)
index b8392e7a0cdd0c7ecbc9b36f133ad0093a75f435..f500b0c3ca57918ead92c9f74dd407f0ae99d2fa 100644 (file)
@@ -5537,13 +5537,6 @@ static int idetape_cleanup(struct ata_device *drive)
        return 0;
 }
 
-static void idetape_revalidate(struct ata_device *_dummy)
-{
-       /* We don't have to handle any partition information here, which is the
-        * default behaviour of this method.
-        */
-}
-
 static void idetape_attach(struct ata_device *);
 
 static struct ata_operations idetape_driver = {
@@ -5556,8 +5549,6 @@ static struct ata_operations idetape_driver = {
        .ioctl =                idetape_blkdev_ioctl,
        .open =                 idetape_blkdev_open,
        .release =              idetape_blkdev_release,
-       .check_media_change =   NULL,
-       .revalidate =           idetape_revalidate,
 };
 
 
index e5d58dfc4e65cd4d1b3291a193b5d6efb4203df9..50eb0c696d65e281469cafedf6d5c23bc0f21d72 100644 (file)
@@ -1106,7 +1106,7 @@ struct block_device_operations ide_fops[] = {{
        .release =              ide_release,
        .ioctl =                ata_ioctl,
        .check_media_change =   ide_check_media_change,
-       .revalidate =           ata_revalidate
+       .revalidate =           ide_revalidate
 }};
 
 EXPORT_SYMBOL(ide_fops);
index 5ab0adcdcac69ff8e1b580786fab9f88152c5eb0..ad0e49308c73ba53830e4b1e8a6268839909289b 100644 (file)
@@ -349,9 +349,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
                case CDROMCLOSETRAY:
                        return block_ioctl(inode->i_bdev, cmd, arg);
 
-               case BLKRRPART: /* Re-read partition tables */
-                       return ata_revalidate(inode->i_rdev);
-
                /* Now check whatever this particular ioctl has a device type
                 * specific implementation.
                 */
index e952e84c63edd40b93f7b77a1263fda939127d64..98f4a0ba585d215e0be931289dede51c6ab586f6 100644 (file)
@@ -260,40 +260,25 @@ struct ata_device *get_info_ptr(kdev_t i_rdev)
  * usage == 1 (we need an open channel to use an ioctl :-), so this
  * is our limit.
  */
-int ata_revalidate(kdev_t i_rdev)
+int ide_revalidate(kdev_t dev)
 {
-       kdev_t device = mk_kdev(major(i_rdev), minor(i_rdev) & ~PARTN_MASK);
        struct ata_device *drive;
-       int res;
+       struct ata_channel *channel;
+       struct gendisk *disk;
+       int unit;
 
-       if ((drive = get_info_ptr(device)) == NULL)
+       if ((drive = get_info_ptr(dev)) == NULL)
                return -ENODEV;
-
-       MOD_INC_USE_COUNT;
-
-       res = dev_lock_part(device);
-       if (res < 0) {
-               MOD_DEC_USE_COUNT;
-               return res;
+       if (ata_ops(drive) && ata_ops(drive)->revalidate) {
+               ata_get(ata_ops(drive));
+               ata_ops(drive)->revalidate(drive);
+               ata_put(ata_ops(drive));
        }
-
-       res = wipe_partitions(device);
-       if (!res) {
-               if (ata_ops(drive) && ata_ops(drive)->revalidate) {
-                       ata_get(ata_ops(drive));
-
-                       /* This is expected to be a no-op for tapes and SCSI
-                        * based access.
-                        */
-                       ata_ops(drive)->revalidate(drive);
-                       ata_put(ata_ops(drive));
-               } else
-                       grok_partitions(device, ata_capacity(drive));
-       }
-
-       dev_unlock_part(device);
-       MOD_DEC_USE_COUNT;
-       return res;
+       channel = drive->channel;
+       unit = drive - channel->drives;
+       disk = channel->gd[unit];
+       disk->part[0].nr_sects = ata_capacity(drive);
+       return 0;
 }
 
 void ide_driver_module(void)
@@ -1139,8 +1124,6 @@ void unregister_ata_driver(struct ata_operations *driver)
        }
 }
 
-EXPORT_SYMBOL(unregister_ata_driver);
-
 EXPORT_SYMBOL(ide_hwifs);
 EXPORT_SYMBOL(ide_lock);
 
index d2b37e0fb17199dcee4090d06e17d66c725837b8..83e5ba3c3f7f3f0d1957574c0df6fed947c11d63 100644 (file)
@@ -184,6 +184,7 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
 static int ftl_open(struct inode *inode, struct file *file);
 static release_t ftl_close(struct inode *inode, struct file *file);
 static int ftl_reread_partitions(kdev_t dev);
+static int ftl_revalidate(kdev_t dev);
 
 static void ftl_erase_callback(struct erase_info *done);
 
@@ -192,6 +193,7 @@ static struct block_device_operations ftl_blk_fops = {
     open:      ftl_open,
     release:   ftl_close,
     ioctl:     ftl_ioctl,
+    revalidate:        ftl_revalidate,
 };
 
 /*======================================================================
@@ -1106,25 +1108,17 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
     if (!part)
        return -ENODEV; /* How? */
 
-    switch (cmd) {
-    case HDIO_GETGEO:
-       ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
-       if (ret) return ret;
-       /* Sort of arbitrary: round size down to 4K boundary */
-       sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
-       put_user(1, (char *)&geo->heads);
-       put_user(8, (char *)&geo->sectors);
-       put_user((sect>>3), (short *)&geo->cylinders);
-       put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
-       break;
-    case BLKRRPART:
-       ret = ftl_reread_partitions(inode->i_rdev);
-       break;
-    default:
-       ret = -EINVAL;
-    }
-
-    return ret;
+    if (cmd != HDIO_GETGEO)
+       return -EINVAL;
+    ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
+    if (ret) return ret;
+    /* Sort of arbitrary: round size down to 4K boundary */
+    sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
+    put_user(1, (char *)&geo->heads);
+    put_user(8, (char *)&geo->sectors);
+    put_user((sect>>3), (short *)&geo->cylinders);
+    put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
+    return 0;
 } /* ftl_ioctl */
 
 /*======================================================================
@@ -1133,22 +1127,14 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
 
 ======================================================================*/
 
-static int ftl_reread_partitions(kdev_t dev)
+static int ftl_revalidate(kdev_t dev)
 {
-       int minor = minor(dev);
-       partition_t *part = myparts[minor >> 4];
-       kdev_t device = mk_kdev(MAJOR_NR, minor & ~15);
-       int res = dev_lock_part(device);
-       if (rec < 0)
-               return res;
-       res = wipe_partitions(device);
-       if (!res) {
-               scan_header(part);
-               grok_partitions(device,
-                       le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
-       }
-       dev_unlock_part(device);
-       return res;
+       int unit = minor(dev) >> 4;
+       partition_t *part = myparts[unit];
+       scan_header(part);
+       part->disk->part[0].nr_sects =
+               le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
+       return 0;
 }
 
 /*======================================================================
index 5c3c32ee96cf78d4af0f6d7701939f811dd6701d..2de5c0783fdea79606a4483771d164029e489548 100644 (file)
@@ -799,21 +799,6 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd
                if (nftl->mtd->sync)
                        nftl->mtd->sync(nftl->mtd);
                return 0;
-
-       case BLKRRPART:
-               if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-               {
-               kdev_t device = mk_kdev(MAJOR_NR,
-                       minor(inode->i_rdev) & -(1<<NFTL_PARTN_BITS));
-               res = dev_lock_part(device);
-               if (res < 0)
-                       return res;
-               res = wipe_partitions(device);
-               if (!res)
-                       grok_partitions(device, nftl->nr_sects);
-               dev_unlock_part(device);
-               }
-               return res;
        default:
                return -EINVAL;
        }
index e3705381dac366a5e6865d0ef48ee8cb02670472..db3058b18b5009c6dd17dfa38216a5362b4651a2 100644 (file)
@@ -447,31 +447,6 @@ static int dasd_ioctl_set_ro(void *inp, int no, long args)
        return 0;
 }
 
-/*
- * Reread partition table.
- */
-static int dasd_ioctl_rr_partition(void *inp, int no, long args)
-{
-       dasd_devmap_t *devmap;
-       dasd_device_t *device;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-
-       devmap = dasd_devmap_from_kdev(((struct inode *) inp)->i_rdev);
-       device = (devmap != NULL) ?
-               dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-       if (IS_ERR(device))
-               return PTR_ERR(device);
-       if (atomic_read(&device->open_count) != 1)
-               DEV_MESSAGE(KERN_WARNING, device, "%s",
-                           "BLKRRPART: device is open! expect errors.");
-       dasd_destroy_partitions(device);
-       dasd_setup_partitions(device);
-       dasd_put_device(devmap);
-       return 0;
-}
-
 /*
  * Return disk geometry.
  */
@@ -516,7 +491,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
        { BIODASDPRRD, dasd_ioctl_read_profile },
        { BIODASDPRRST, dasd_ioctl_reset_profile },
        { BLKROSET, dasd_ioctl_set_ro },
-       { BLKRRPART, dasd_ioctl_rr_partition },
        { DASDAPIVER, dasd_ioctl_api_version },
        { HDIO_GETGEO, dasd_ioctl_getgeo },
        { -1, NULL }
index 94c04fccfee75bc209b185adb8b864e809971937..df746ea188b5cb131dd48610dadd2717737eec43 100644 (file)
@@ -334,35 +334,26 @@ static int xpram_ioctl (struct inode *inode, struct file *filp,
 {
        struct hd_geometry *geo;
        unsigned long size;
-       int idx;
-
-       if ((!inode) || kdev_none(inode->i_rdev))
-               return -EINVAL;
-       idx = minor(inode->i_rdev);
+       int idx = minor(inode->i_rdev);
        if (idx >= xpram_devs)
                return -ENODEV;
-       switch (cmd) {
-       case BLKRRPART:
-               /* re-read partition table: can't do it */
+       if (cmd != HDIO_GETGEO)
                return -EINVAL;
-       case HDIO_GETGEO:
-               /*
-                * get geometry: we have to fake one...  trim the size to a
-                * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
-                * whatever cylinders. Tell also that data starts at sector. 4.
-                */
-               geo = (struct hd_geometry *) arg;
-               if (geo == NULL)
-                       return -EINVAL;
-               size = (xpram_pages * 8) & ~0x3f;
-               put_user(size >> 6, &geo->cylinders);
-               put_user(4, &geo->heads);
-               put_user(16, &geo->sectors);
-               put_user(4, &geo->start);
-               return 0;
-       default:
+       /*
+        * get geometry: we have to fake one...  trim the size to a
+        * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
+        * whatever cylinders. Tell also that data starts at sector. 4.
+        */
+       geo = (struct hd_geometry *) arg;
+       if (geo == NULL)
                return -EINVAL;
-       }
+       size = (xpram_pages * 8) & ~0x3f;
+       put_user(size >> 6, &geo->cylinders);
+       put_user(4, &geo->heads);
+       put_user(16, &geo->sectors);
+       put_user(4, &geo->start);
+       return 0;
+}
 }
 
 static struct block_device_operations xpram_devops =
index 3f4257ec9de41083a57382a903c4f618ca9248bf..07e574bdcb4127f444a8bf4b6568dc265cbcb5f7 100644 (file)
@@ -91,7 +91,7 @@ static Scsi_Disk ** sd_dsk_arr;
 static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED;
 
 static int check_scsidisk_media_change(kdev_t);
-static int fop_revalidate_scsidisk(kdev_t);
+static int sd_revalidate(kdev_t);
 
 static void sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr);
 
@@ -243,12 +243,6 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
                                return -EFAULT;
                        return 0;
                }
-
-               case BLKRRPART: /* Re-read partition tables */
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EACCES;
-                       return revalidate_scsidisk(dev, 1);
-
                default:
                        return scsi_ioctl(sdp, cmd, (void *) arg);
        }
@@ -600,7 +594,7 @@ static struct block_device_operations sd_fops =
        release:                sd_release,
        ioctl:                  sd_ioctl,
        check_media_change:     check_scsidisk_media_change,
-       revalidate:             fop_revalidate_scsidisk
+       revalidate:             sd_revalidate
 };
 
 static struct gendisk **sd_disks;
@@ -1387,50 +1381,17 @@ static int sd_attach(Scsi_Device * sdp)
        return 0;
 }
 
-/**
- *     revalidate_scsidisk - called to flush all partitions and partition 
- *     tables for a changed scsi disk. sd_init_onedisk() is then called
- *     followed by re-reading the new partition table.
- *      @dev: kernel device descriptor (kdev_t)
- *      @maxusage: 0 when called from block level, 1 when called from
- *      sd_ioctl().
- *
- *     Returns 0 if successful; negated errno value otherwise.
- */
-int revalidate_scsidisk(kdev_t dev, int maxusage)
+static int sd_revalidate(kdev_t dev)
 {
        int dsk_nr = DEVICE_NR(dev);
-       Scsi_Disk * sdkp;
-       Scsi_Device * sdp;
-       kdev_t device = mk_kdev(major(dev), minor(dev) & ~15);
-       int res;
+       Scsi_Disk * sdkp = sd_get_sdisk(dsk_nr);
 
-       SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
-                                  DEVICE_NR(dev)));
-       sdkp = sd_get_sdisk(dsk_nr);
-       if ((NULL == sdkp) || (NULL == (sdp = sdkp->device)))
+       if (!sdkp || !sdkp->device)
                return -ENODEV;
 
-       res = dev_lock_part(device);
-       if (res < 0)
-               return res;
-
-       res = wipe_partitions(device);
-       if (res)
-               goto leave;
-
        sd_init_onedisk(sdkp, dsk_nr);
-
-       grok_partitions(device, sdkp->capacity);
-
-leave:
-       dev_unlock_part(device);
-       return res;
-}
-
-static int fop_revalidate_scsidisk(kdev_t dev)
-{
-       return revalidate_scsidisk(dev, 0);
+       sd_disks[dsk_nr]->part[0].nr_sects = sdkp->capacity;
+       return 0;
 }
 
 /**
index f5b1016fd0523b27dede360aa1d36fa3d52bec36..255861a3ce507696a0de935f63f8a022ab1dd125 100644 (file)
@@ -502,6 +502,8 @@ int check_disk_change(struct block_device *bdev)
 {
        struct block_device_operations * bdops = bdev->bd_op;
        kdev_t dev = to_kdev_t(bdev->bd_dev);
+       struct gendisk *disk;
+       struct hd_struct *part;
 
        if (bdops->check_media_change == NULL)
                return 0;
@@ -514,8 +516,23 @@ int check_disk_change(struct block_device *bdev)
        if (invalidate_device(dev, 0))
                printk("VFS: busy inodes on changed media.\n");
 
-       if (bdops->revalidate)
-               bdops->revalidate(dev);
+       disk = get_gendisk(dev);
+       part = disk->part + minor(dev) - disk->first_minor;
+       if (disk && disk->minor_shift) {
+               if (!down_trylock(&bdev->bd_part_sem)) {
+                       if (!bdev->bd_part_count) {
+                               if (wipe_partitions(dev) == 0) {
+                                       if (bdops->revalidate)
+                                               bdops->revalidate(dev);
+                                       grok_partitions(dev, part[0].nr_sects);
+                               }
+                       }
+                       up(&bdev->bd_part_sem);
+               }
+       } else {
+               if (bdops->revalidate)
+                       bdops->revalidate(dev);
+       }
        return 1;
 }
 
@@ -734,9 +751,38 @@ int blkdev_close(struct inode * inode, struct file * filp)
        return blkdev_put(inode->i_bdev, BDEV_FILE);
 }
 
+static int blkdev_reread_part(struct block_device *bdev)
+{
+       kdev_t dev = to_kdev_t(bdev->bd_dev);
+       struct gendisk *disk = get_gendisk(dev);
+       struct hd_struct *part;
+       int res;
+
+       if (!disk)
+               return -EINVAL;
+       part = disk->part + minor(dev) - disk->first_minor;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (down_trylock(&bdev->bd_part_sem));
+               return -EBUSY;
+       if (bdev->bd_part_count) {
+               up(&bdev->bd_part_sem);
+               return -EBUSY;
+       }
+       res = wipe_partitions(dev);
+       if (!res) {
+               if (bdev->bd_op->revalidate)
+                       bdev->bd_op->revalidate(dev);
+               grok_partitions(dev, part[0].nr_sects);
+       }
+       up(&bdev->bd_part_sem);
+       return res;
+}
+
 static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                        unsigned long arg)
 {
+       struct block_device *bdev = inode->i_bdev;
        int ret = -EINVAL;
        switch (cmd) {
        /*
@@ -756,21 +802,23 @@ static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
        case BLKFRASET:
        case BLKBSZSET:
        case BLKPG:
-               ret = blk_ioctl(inode->i_bdev, cmd, arg);
+               ret = blk_ioctl(bdev, cmd, arg);
                break;
        default:
-               if (inode->i_bdev->bd_op->ioctl)
-                       ret =inode->i_bdev->bd_op->ioctl(inode, file, cmd, arg);
+               if (bdev->bd_op->ioctl)
+                       ret =bdev->bd_op->ioctl(inode, file, cmd, arg);
                if (ret == -EINVAL) {
                        switch (cmd) {
                                case BLKGETSIZE:
                                case BLKGETSIZE64:
                                case BLKFLSBUF:
                                case BLKROSET:
-                                       ret = blk_ioctl(inode->i_bdev,cmd,arg);
+                                       ret = blk_ioctl(bdev,cmd,arg);
+                                       break;
+                               case BLKRRPART:
+                                       ret = blkdev_reread_part(bdev);
                        }
                }
-               break;
        }
        return ret;
 }
index 7731d36ef133c0fddb3770efc6ad17367d8286d1..172ef0e9113bf40dc96a62e7b7582b52b3c103f4 100644 (file)
@@ -2377,23 +2377,20 @@ static int check_disc_changed (struct devfs_entry *de)
     int tmp;
     int retval = 0;
     kdev_t dev = mk_kdev (de->u.fcb.u.device.major, de->u.fcb.u.device.minor);
+    struct block_device *bdev;
     struct block_device_operations *bdops;
     extern int warn_no_part;
 
     if ( !S_ISBLK (de->mode) ) return 0;
+    bdev = bdget(kdev_t_to_nr(dev));
+    if (!bdev) return 0;
     bdops = devfs_get_ops (de);
     if (!bdops) return 0;
-    if (bdops->check_media_change == NULL) goto out;
-    if ( !bdops->check_media_change (dev) ) goto out;
-    retval = 1;
-    printk (KERN_DEBUG "VFS: Disk change detected on device %s\n",
-            kdevname (dev) );
-    if ( invalidate_device (dev, 0) )
-       printk (KERN_WARNING "VFS: busy inodes on changed media..\n");
+    bdev->bd_op = bdops;
     /*  Ugly hack to disable messages about unable to read partition table  */
     tmp = warn_no_part;
     warn_no_part = 0;
-    if (bdops->revalidate) bdops->revalidate (dev);
+    retval = check_disk_change(bdev);
     warn_no_part = tmp;
 out:
     devfs_put_ops (de);
index b0d9ffe2508840079d386c791291de5a1cdebea5..9ad9cdf3e6681778fce4c28e5e2adf2ece4d5616 100644 (file)
@@ -1307,31 +1307,5 @@ static inline ino_t parent_ino(struct dentry *dentry)
        return res;
 }
 
-/* NOTE NOTE NOTE: this interface _will_ change in a couple of patches */
-
-static inline int dev_lock_part(kdev_t dev)
-{
-       struct block_device *bdev = bdget(kdev_t_to_nr(dev));
-       if (!bdev)
-               return -ENOMEM;
-       if (!down_trylock(&bdev->bd_part_sem)) {
-               if (!bdev->bd_part_count)
-                       return 0;
-               up(&bdev->bd_part_sem);
-       }
-       bdput(bdev);
-       return -EBUSY;
-}
-
-static inline void dev_unlock_part(kdev_t dev)
-{
-       struct block_device *bdev = bdget(kdev_t_to_nr(dev));
-       if (!bdev)
-               BUG();
-       up(&bdev->bd_part_sem);
-       bdput(bdev);
-       bdput(bdev);
-}
-
 #endif /* __KERNEL__ */
 #endif /* _LINUX_FS_H */
index 6de4ad25531cde33a2e67fc2f8cb4a68d72e76c5..8b6a08364aaa512c00f65334c4ae8b4ed54462ad 100644 (file)
@@ -1161,7 +1161,7 @@ extern int idescsi_init(void);
 
 extern int ata_register_device(struct ata_device *, struct ata_operations *);
 extern int ata_unregister_device(struct ata_device *drive);
-extern int ata_revalidate(kdev_t i_rdev);
+extern int ide_revalidate(kdev_t i_rdev);
 extern void ide_driver_module(void);
 
 #ifdef CONFIG_PCI