Commit 816ab591 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] partition table flush/read cleanup

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).
parent fc4dfb65
...@@ -226,7 +226,6 @@ static char *Copy_buffer; ...@@ -226,7 +226,6 @@ static char *Copy_buffer;
static void mfm_seek(void); static void mfm_seek(void);
static void mfm_rerequest(void); static void mfm_rerequest(void);
static void mfm_request(void); static void mfm_request(void);
static int mfm_reread_partitions(kdev_t dev);
static void mfm_specify (void); static void mfm_specify (void);
static void issue_request(int dev, unsigned int block, unsigned int nsect, static void issue_request(int dev, unsigned int block, unsigned int nsect,
struct request *req); struct request *req);
...@@ -1165,20 +1164,19 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a ...@@ -1165,20 +1164,19 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a
{ {
struct hd_geometry *geo = (struct hd_geometry *) arg; struct hd_geometry *geo = (struct hd_geometry *) arg;
kdev_t dev; kdev_t dev;
int device, major, minor, err; int device, minor, err;
if (!inode || !(dev = inode->i_rdev)) if (!inode || !(dev = inode->i_rdev))
return -EINVAL; return -EINVAL;
major = major(dev);
minor = minor(dev); minor = minor(dev);
device = DEVICE_NR(minor(inode->i_rdev)), err; device = DEVICE_NR(minor(inode->i_rdev)), err;
if (device >= mfm_drives) if (device >= mfm_drives)
return -EINVAL; return -EINVAL;
switch (cmd) { if (cmd != HDIO_GETGEO)
case HDIO_GETGEO: return -EINVAL;
if (!arg) if (!arg)
return -EINVAL; return -EINVAL;
if (put_user (mfm_info[device].heads, &geo->heads)) if (put_user (mfm_info[device].heads, &geo->heads))
...@@ -1190,15 +1188,6 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a ...@@ -1190,15 +1188,6 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a
if (put_user (mfm[minor].start_sect, &geo->start)) if (put_user (mfm[minor].start_sect, &geo->start))
return -EFAULT; return -EFAULT;
return 0; return 0;
case BLKRRPART:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return mfm_reread_partitions(dev);
default:
return -EINVAL;
}
} }
static int mfm_open(struct inode *inode, struct file *file) static int mfm_open(struct inode *inode, struct file *file)
...@@ -1396,25 +1385,6 @@ int mfm_init (void) ...@@ -1396,25 +1385,6 @@ int mfm_init (void)
return 0; 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 #ifdef MODULE
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -369,7 +369,6 @@ static void acsi_prevent_removal( int target, int flag ); ...@@ -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_change_blk_size( int target, int lun);
static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd ); static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
static void acsi_geninit(void); static void acsi_geninit(void);
static int revalidate_acsidisk( kdev_t dev, int maxusage );
static int acsi_revalidate (kdev_t); static int acsi_revalidate (kdev_t);
/************************* End of Prototypes **************************/ /************************* End of Prototypes **************************/
...@@ -1108,19 +1107,12 @@ static int acsi_ioctl( struct inode *inode, struct file *file, ...@@ -1108,19 +1107,12 @@ static int acsi_ioctl( struct inode *inode, struct file *file,
put_user(get_start_sect(inode->i_bdev), &geo->start); put_user(get_start_sect(inode->i_bdev), &geo->start);
return 0; return 0;
} }
case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_IDLUN:
/* SCSI compatible GET_IDLUN call to get target's ID and LUN number */ /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
put_user( acsi_info[dev].target | (acsi_info[dev].lun << 8), put_user( acsi_info[dev].target | (acsi_info[dev].lun << 8),
&((Scsi_Idlun *) arg)->dev_id ); &((Scsi_Idlun *) arg)->dev_id );
put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id ); put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
return 0; return 0;
case BLKRRPART: /* Re-read partition tables */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return revalidate_acsidisk(inode->i_rdev, 1);
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -1809,20 +1801,11 @@ void cleanup_module(void) ...@@ -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)); int unit = DEVICE_NR(minor(dev));
struct acsi_info_struct *aip = &acsi_info[unit]; 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 ); stdma_lock( NULL, NULL );
if (acsi_devinit(aip) != DEV_SUPPORTED) { if (acsi_devinit(aip) != DEV_SUPPORTED) {
printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n", printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n",
aip->target, aip->lun); aip->target, aip->lun);
...@@ -1834,16 +1817,6 @@ static int revalidate_acsidisk(kdev_t dev, int maxusage ) ...@@ -1834,16 +1817,6 @@ static int revalidate_acsidisk(kdev_t dev, int maxusage )
ENABLE_IRQ(); ENABLE_IRQ();
stdma_release(); stdma_release();
acsi_part[minor(dev)].nr_sects = aip->size;
if (!res) return 0;
grok_partitions(device, aip->size);
dev_unlock_part(device);
return res;
}
static int acsi_revalidate (kdev_t dev)
{
return revalidate_acsidisk (dev, 0);
} }
...@@ -269,12 +269,6 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg) ...@@ -269,12 +269,6 @@ int blk_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long arg)
/* size in bytes */ /* size in bytes */
ullval = bdev->bd_inode->i_size; ullval = bdev->bd_inode->i_size;
return put_user(ullval, (u64 *) arg); 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: case BLKPG:
return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg); return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg);
......
...@@ -106,7 +106,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -106,7 +106,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
static int revalidate_allvol(kdev_t dev); static int revalidate_allvol(kdev_t dev);
static int revalidate_logvol(kdev_t dev, int maxusage); 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 deregister_disk(int ctlr, int logvol);
static int register_new_disk(kdev_t dev, int cltr); static int register_new_disk(kdev_t dev, int cltr);
...@@ -130,7 +130,7 @@ static struct block_device_operations cciss_fops = { ...@@ -130,7 +130,7 @@ static struct block_device_operations cciss_fops = {
open: cciss_open, open: cciss_open,
release: cciss_release, release: cciss_release,
ioctl: cciss_ioctl, ioctl: cciss_ioctl,
revalidate: frevalidate_logvol, revalidate: cciss_revalidate,
}; };
#include "cciss_scsi.c" /* For SCSI tape support */ #include "cciss_scsi.c" /* For SCSI tape support */
...@@ -437,8 +437,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -437,8 +437,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
return(0); return(0);
} }
case BLKRRPART:
return revalidate_logvol(inode->i_rdev, 1);
case CCISS_GETPCIINFO: case CCISS_GETPCIINFO:
{ {
cciss_pci_info_struct pciinfo; cciss_pci_info_struct pciinfo;
...@@ -724,6 +722,15 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, ...@@ -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 */ /* Borrowed and adapted from sd.c */
/* /*
* FIXME: we are missing the exclusion with ->open() here - it can happen * FIXME: we are missing the exclusion with ->open() here - it can happen
...@@ -762,14 +769,6 @@ static int revalidate_logvol(kdev_t dev, int maxusage) ...@@ -762,14 +769,6 @@ static int revalidate_logvol(kdev_t dev, int maxusage)
return res; 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 * revalidate_allvol is for online array config utilities. After a
* utility reconfigures the drives in the array, it can use this function * utility reconfigures the drives in the array, it can use this function
......
...@@ -153,7 +153,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout); ...@@ -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 do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
static void ida_timer(unsigned long tdata); 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_logvol(kdev_t dev, int maxusage);
static int revalidate_allvol(kdev_t dev); static int revalidate_allvol(kdev_t dev);
...@@ -188,7 +188,7 @@ static struct block_device_operations ida_fops = { ...@@ -188,7 +188,7 @@ static struct block_device_operations ida_fops = {
open: ida_open, open: ida_open,
release: ida_release, release: ida_release,
ioctl: ida_ioctl, 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, ...@@ -1107,8 +1107,6 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
sizeof(drv_info_t))) sizeof(drv_info_t)))
return -EFAULT; return -EFAULT;
return 0; return 0;
case BLKRRPART:
return revalidate_logvol(inode->i_rdev, 1);
case IDAPASSTHRU: case IDAPASSTHRU:
if (!capable(CAP_SYS_RAWIO)) return -EPERM; if (!capable(CAP_SYS_RAWIO)) return -EPERM;
if (copy_from_user(&my_io, io, sizeof(my_io))) if (copy_from_user(&my_io, io, sizeof(my_io)))
...@@ -1441,11 +1439,6 @@ DBG( ...@@ -1441,11 +1439,6 @@ DBG(
return (IO_OK); 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 * revalidate_allvol is for online array config utilities. After a
* utility reconfigures the drives in the array, it can use this function * utility reconfigures the drives in the array, it can use this function
...@@ -1505,6 +1498,15 @@ static int revalidate_allvol(kdev_t dev) ...@@ -1505,6 +1498,15 @@ static int revalidate_allvol(kdev_t dev)
return 0; 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 */ /* Borrowed and adapted from sd.c */
/* /*
* FIXME: exclusion with ->open() * FIXME: exclusion with ->open()
......
...@@ -404,10 +404,6 @@ static int pd_ioctl(struct inode *inode,struct file *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); put_user(get_start_sect(inode->i_bdev), (long *)&geo->start);
return 0; return 0;
case BLKRRPART:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return pd_revalidate(inode->i_rdev);
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -439,23 +435,13 @@ static int pd_check_media( kdev_t dev) ...@@ -439,23 +435,13 @@ static int pd_check_media( kdev_t dev)
static int pd_revalidate(kdev_t dev) static int pd_revalidate(kdev_t dev)
{ {
int unit = DEVICE_NR(dev); int unit = DEVICE_NR(dev);
kdev_t device = mk_kdev(MAJOR_NR, unit << PD_BITS);
int res;
if ((unit >= PD_UNITS) || !PD.present) if ((unit >= PD_UNITS) || !PD.present)
return -ENODEV; return -ENODEV;
if (pd_identify(unit))
res = dev_lock_part(device); pd_hd[minor(dev)].nr_sects = PD.capacity;
if (res < 0) else
return res; pd_hd[minor(dev)].nr_sects = 0;
res = wipe_partitions(device); return 0;
if (res == 0 && pd_identify(unit))
grok_partitions(device, PD.capacity);
dev_unlock_part(device);
return res;
} }
#define WR(c,r,v) pi_write_regr(PI,c,r,v) #define WR(c,r,v) pi_write_regr(PI,c,r,v)
......
...@@ -95,8 +95,6 @@ static int ps2esdi_open(struct inode *inode, struct file *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, static int ps2esdi_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg); 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 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); 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) ...@@ -1080,53 +1078,18 @@ static int ps2esdi_open(struct inode *inode, struct file *file)
static int ps2esdi_ioctl(struct inode *inode, static int ps2esdi_ioctl(struct inode *inode,
struct file *file, u_int cmd, u_long arg) struct file *file, u_int cmd, u_long arg)
{ {
struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg; struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
int dev = DEVICE_NR(inode->i_rdev), err; int dev = DEVICE_NR(inode->i_rdev), err;
if (inode && (dev < ps2esdi_drives)) if (cmd != HDIO_GETGEO)
switch (cmd) { return -EINVAL;
case HDIO_GETGEO:
if (arg) {
if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry)))) if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
return (err); return (err);
put_user(ps2esdi_info[dev].head, (char *) &geometry->heads); put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors); put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders); put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
put_user(get_start_sect(inode->b_rdev), put_user(get_start_sect(inode->b_rdev), (long *) &geometry->start);
(long *) &geometry->start);
return 0; 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;
} }
static void ps2esdi_reset_timer(unsigned long unused) static void ps2esdi_reset_timer(unsigned long unused)
......
...@@ -818,14 +818,7 @@ static void del_battery_timer(void) ...@@ -818,14 +818,7 @@ static void del_battery_timer(void)
static int mm_revalidate(kdev_t i_rdev) static int mm_revalidate(kdev_t i_rdev)
{ {
int card_number = DEVICE_NR(i_rdev); int card_number = DEVICE_NR(i_rdev);
kdev_t device = mk_kdev(MAJOR_NR, card_number << MM_SHIFT); mm_partitions[minor(i_rdev)] = cards[card_number].mm_size << 1;
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);
return 0; return 0;
} }
/* /*
...@@ -835,22 +828,10 @@ static int mm_revalidate(kdev_t i_rdev) ...@@ -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) static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
{ {
int err, size, card_number; if (cmd == case HDIO_GETGEO) {
unsigned int minor = minor(i->i_rdev);
int err, size, card_number = (minor >> MM_SHIFT);
struct hd_geometry geo; 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:
/* /*
* get geometry: we have to fake one... trim the size to a * get geometry: we have to fake one... trim the size to a
* multiple of 2048 (1M): tell we have 32 sectors, 64 heads, * 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 ...@@ -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))) if (copy_to_user((void *) arg, &geo, sizeof(geo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
default:
return -EINVAL;
} }
return -ENOTTY; /* unknown command */ return -EINVAL;
} }
/* /*
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
......
...@@ -330,37 +330,11 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) ...@@ -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); return put_user(!nodma, (long *) arg);
case HDIO_GET_MULTCOUNT: case HDIO_GET_MULTCOUNT:
return put_user(xd_maxsectors, (long *) arg); return put_user(xd_maxsectors, (long *) arg);
case BLKRRPART:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return xd_reread_partitions(inode->i_rdev);
default: default:
return -EINVAL; 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 */ /* 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) static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count)
{ {
......
...@@ -113,7 +113,6 @@ static void xd_geninit (void); ...@@ -113,7 +113,6 @@ static void xd_geninit (void);
static int xd_open (struct inode *inode,struct file *file); static int xd_open (struct inode *inode,struct file *file);
static void do_xd_request (request_queue_t * q); 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_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 int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count);
static void xd_recalibrate (u_char drive); static void xd_recalibrate (u_char drive);
......
...@@ -108,8 +108,6 @@ ...@@ -108,8 +108,6 @@
static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED; static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
static int revalidate_hddisk(kdev_t, int);
#define TIMEOUT_VALUE (6*HZ) #define TIMEOUT_VALUE (6*HZ)
#define HD_DELAY 0 #define HD_DELAY 0
...@@ -683,11 +681,6 @@ static int hd_ioctl(struct inode * inode, struct file * file, ...@@ -683,11 +681,6 @@ static int hd_ioctl(struct inode * inode, struct file * file,
return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 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: default:
return -EINVAL; return -EINVAL;
} }
...@@ -879,32 +872,6 @@ int __init hd_init(void) ...@@ -879,32 +872,6 @@ int __init hd_init(void)
return 0; 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) { static int parse_hd_setup (char *line) {
int ints[6]; int ints[6];
......
...@@ -2875,19 +2875,8 @@ int ide_cdrom_check_media_change(struct ata_device *drive) ...@@ -2875,19 +2875,8 @@ int ide_cdrom_check_media_change(struct ata_device *drive)
static static
void ide_cdrom_revalidate(struct ata_device *drive) void ide_cdrom_revalidate(struct ata_device *drive)
{ {
struct cdrom_info *info = drive->driver_data;
struct atapi_toc *toc;
struct request_sense sense; struct request_sense sense;
cdrom_read_toc(drive, &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) static sector_t ide_cdrom_capacity(struct ata_device *drive)
......
...@@ -5537,13 +5537,6 @@ static int idetape_cleanup(struct ata_device *drive) ...@@ -5537,13 +5537,6 @@ static int idetape_cleanup(struct ata_device *drive)
return 0; 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 void idetape_attach(struct ata_device *);
static struct ata_operations idetape_driver = { static struct ata_operations idetape_driver = {
...@@ -5556,8 +5549,6 @@ static struct ata_operations idetape_driver = { ...@@ -5556,8 +5549,6 @@ static struct ata_operations idetape_driver = {
.ioctl = idetape_blkdev_ioctl, .ioctl = idetape_blkdev_ioctl,
.open = idetape_blkdev_open, .open = idetape_blkdev_open,
.release = idetape_blkdev_release, .release = idetape_blkdev_release,
.check_media_change = NULL,
.revalidate = idetape_revalidate,
}; };
......
...@@ -1106,7 +1106,7 @@ struct block_device_operations ide_fops[] = {{ ...@@ -1106,7 +1106,7 @@ struct block_device_operations ide_fops[] = {{
.release = ide_release, .release = ide_release,
.ioctl = ata_ioctl, .ioctl = ata_ioctl,
.check_media_change = ide_check_media_change, .check_media_change = ide_check_media_change,
.revalidate = ata_revalidate .revalidate = ide_revalidate
}}; }};
EXPORT_SYMBOL(ide_fops); EXPORT_SYMBOL(ide_fops);
......
...@@ -349,9 +349,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned ...@@ -349,9 +349,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case CDROMCLOSETRAY: case CDROMCLOSETRAY:
return block_ioctl(inode->i_bdev, cmd, arg); 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 /* Now check whatever this particular ioctl has a device type
* specific implementation. * specific implementation.
*/ */
......
...@@ -260,40 +260,25 @@ struct ata_device *get_info_ptr(kdev_t i_rdev) ...@@ -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 * usage == 1 (we need an open channel to use an ioctl :-), so this
* is our limit. * 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; 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; return -ENODEV;
MOD_INC_USE_COUNT;
res = dev_lock_part(device);
if (res < 0) {
MOD_DEC_USE_COUNT;
return res;
}
res = wipe_partitions(device);
if (!res) {
if (ata_ops(drive) && ata_ops(drive)->revalidate) { if (ata_ops(drive) && ata_ops(drive)->revalidate) {
ata_get(ata_ops(drive)); 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_ops(drive)->revalidate(drive);
ata_put(ata_ops(drive)); ata_put(ata_ops(drive));
} else
grok_partitions(device, ata_capacity(drive));
} }
channel = drive->channel;
dev_unlock_part(device); unit = drive - channel->drives;
MOD_DEC_USE_COUNT; disk = channel->gd[unit];
return res; disk->part[0].nr_sects = ata_capacity(drive);
return 0;
} }
void ide_driver_module(void) void ide_driver_module(void)
...@@ -1139,8 +1124,6 @@ void unregister_ata_driver(struct ata_operations *driver) ...@@ -1139,8 +1124,6 @@ void unregister_ata_driver(struct ata_operations *driver)
} }
} }
EXPORT_SYMBOL(unregister_ata_driver);
EXPORT_SYMBOL(ide_hwifs); EXPORT_SYMBOL(ide_hwifs);
EXPORT_SYMBOL(ide_lock); EXPORT_SYMBOL(ide_lock);
......
...@@ -184,6 +184,7 @@ static int ftl_ioctl(struct inode *inode, struct file *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 int ftl_open(struct inode *inode, struct file *file);
static release_t ftl_close(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_reread_partitions(kdev_t dev);
static int ftl_revalidate(kdev_t dev);
static void ftl_erase_callback(struct erase_info *done); static void ftl_erase_callback(struct erase_info *done);
...@@ -192,6 +193,7 @@ static struct block_device_operations ftl_blk_fops = { ...@@ -192,6 +193,7 @@ static struct block_device_operations ftl_blk_fops = {
open: ftl_open, open: ftl_open,
release: ftl_close, release: ftl_close,
ioctl: ftl_ioctl, ioctl: ftl_ioctl,
revalidate: ftl_revalidate,
}; };
/*====================================================================== /*======================================================================
...@@ -1106,8 +1108,8 @@ static int ftl_ioctl(struct inode *inode, struct file *file, ...@@ -1106,8 +1108,8 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
if (!part) if (!part)
return -ENODEV; /* How? */ return -ENODEV; /* How? */
switch (cmd) { if (cmd != HDIO_GETGEO)
case HDIO_GETGEO: return -EINVAL;
ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo)); ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
if (ret) return ret; if (ret) return ret;
/* Sort of arbitrary: round size down to 4K boundary */ /* Sort of arbitrary: round size down to 4K boundary */
...@@ -1116,15 +1118,7 @@ static int ftl_ioctl(struct inode *inode, struct file *file, ...@@ -1116,15 +1118,7 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
put_user(8, (char *)&geo->sectors); put_user(8, (char *)&geo->sectors);
put_user((sect>>3), (short *)&geo->cylinders); put_user((sect>>3), (short *)&geo->cylinders);
put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start); put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
break; return 0;
case BLKRRPART:
ret = ftl_reread_partitions(inode->i_rdev);
break;
default:
ret = -EINVAL;
}
return ret;
} /* ftl_ioctl */ } /* ftl_ioctl */
/*====================================================================== /*======================================================================
...@@ -1133,22 +1127,14 @@ static int ftl_ioctl(struct inode *inode, struct file *file, ...@@ -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); int unit = minor(dev) >> 4;
partition_t *part = myparts[minor >> 4]; partition_t *part = myparts[unit];
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); scan_header(part);
grok_partitions(device, part->disk->part[0].nr_sects =
le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE); le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
} return 0;
dev_unlock_part(device);
return res;
} }
/*====================================================================== /*======================================================================
......
...@@ -799,21 +799,6 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd ...@@ -799,21 +799,6 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd
if (nftl->mtd->sync) if (nftl->mtd->sync)
nftl->mtd->sync(nftl->mtd); nftl->mtd->sync(nftl->mtd);
return 0; 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: default:
return -EINVAL; return -EINVAL;
} }
......
...@@ -447,31 +447,6 @@ static int dasd_ioctl_set_ro(void *inp, int no, long args) ...@@ -447,31 +447,6 @@ static int dasd_ioctl_set_ro(void *inp, int no, long args)
return 0; 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. * Return disk geometry.
*/ */
...@@ -516,7 +491,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = ...@@ -516,7 +491,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
{ BIODASDPRRD, dasd_ioctl_read_profile }, { BIODASDPRRD, dasd_ioctl_read_profile },
{ BIODASDPRRST, dasd_ioctl_reset_profile }, { BIODASDPRRST, dasd_ioctl_reset_profile },
{ BLKROSET, dasd_ioctl_set_ro }, { BLKROSET, dasd_ioctl_set_ro },
{ BLKRRPART, dasd_ioctl_rr_partition },
{ DASDAPIVER, dasd_ioctl_api_version }, { DASDAPIVER, dasd_ioctl_api_version },
{ HDIO_GETGEO, dasd_ioctl_getgeo }, { HDIO_GETGEO, dasd_ioctl_getgeo },
{ -1, NULL } { -1, NULL }
......
...@@ -334,18 +334,11 @@ static int xpram_ioctl (struct inode *inode, struct file *filp, ...@@ -334,18 +334,11 @@ static int xpram_ioctl (struct inode *inode, struct file *filp,
{ {
struct hd_geometry *geo; struct hd_geometry *geo;
unsigned long size; unsigned long size;
int idx; int idx = minor(inode->i_rdev);
if ((!inode) || kdev_none(inode->i_rdev))
return -EINVAL;
idx = minor(inode->i_rdev);
if (idx >= xpram_devs) if (idx >= xpram_devs)
return -ENODEV; return -ENODEV;
switch (cmd) { if (cmd != HDIO_GETGEO)
case BLKRRPART:
/* re-read partition table: can't do it */
return -EINVAL; return -EINVAL;
case HDIO_GETGEO:
/* /*
* get geometry: we have to fake one... trim the size to a * get geometry: we have to fake one... trim the size to a
* multiple of 64 (32k): tell we have 16 sectors, 4 heads, * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
...@@ -360,9 +353,7 @@ static int xpram_ioctl (struct inode *inode, struct file *filp, ...@@ -360,9 +353,7 @@ static int xpram_ioctl (struct inode *inode, struct file *filp,
put_user(16, &geo->sectors); put_user(16, &geo->sectors);
put_user(4, &geo->start); put_user(4, &geo->start);
return 0; return 0;
default: }
return -EINVAL;
}
} }
static struct block_device_operations xpram_devops = static struct block_device_operations xpram_devops =
......
...@@ -91,7 +91,7 @@ static Scsi_Disk ** sd_dsk_arr; ...@@ -91,7 +91,7 @@ static Scsi_Disk ** sd_dsk_arr;
static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED; static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED;
static int check_scsidisk_media_change(kdev_t); 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); 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, ...@@ -243,12 +243,6 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
case BLKRRPART: /* Re-read partition tables */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
return revalidate_scsidisk(dev, 1);
default: default:
return scsi_ioctl(sdp, cmd, (void *) arg); return scsi_ioctl(sdp, cmd, (void *) arg);
} }
...@@ -600,7 +594,7 @@ static struct block_device_operations sd_fops = ...@@ -600,7 +594,7 @@ static struct block_device_operations sd_fops =
release: sd_release, release: sd_release,
ioctl: sd_ioctl, ioctl: sd_ioctl,
check_media_change: check_scsidisk_media_change, check_media_change: check_scsidisk_media_change,
revalidate: fop_revalidate_scsidisk revalidate: sd_revalidate
}; };
static struct gendisk **sd_disks; static struct gendisk **sd_disks;
...@@ -1387,50 +1381,17 @@ static int sd_attach(Scsi_Device * sdp) ...@@ -1387,50 +1381,17 @@ static int sd_attach(Scsi_Device * sdp)
return 0; return 0;
} }
/** static int sd_revalidate(kdev_t dev)
* 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)
{ {
int dsk_nr = DEVICE_NR(dev); int dsk_nr = DEVICE_NR(dev);
Scsi_Disk * sdkp; Scsi_Disk * sdkp = sd_get_sdisk(dsk_nr);
Scsi_Device * sdp;
kdev_t device = mk_kdev(major(dev), minor(dev) & ~15);
int res;
SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", if (!sdkp || !sdkp->device)
DEVICE_NR(dev)));
sdkp = sd_get_sdisk(dsk_nr);
if ((NULL == sdkp) || (NULL == (sdp = sdkp->device)))
return -ENODEV; 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); sd_init_onedisk(sdkp, dsk_nr);
sd_disks[dsk_nr]->part[0].nr_sects = sdkp->capacity;
grok_partitions(device, sdkp->capacity); return 0;
leave:
dev_unlock_part(device);
return res;
}
static int fop_revalidate_scsidisk(kdev_t dev)
{
return revalidate_scsidisk(dev, 0);
} }
/** /**
......
...@@ -502,6 +502,8 @@ int check_disk_change(struct block_device *bdev) ...@@ -502,6 +502,8 @@ int check_disk_change(struct block_device *bdev)
{ {
struct block_device_operations * bdops = bdev->bd_op; struct block_device_operations * bdops = bdev->bd_op;
kdev_t dev = to_kdev_t(bdev->bd_dev); kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *disk;
struct hd_struct *part;
if (bdops->check_media_change == NULL) if (bdops->check_media_change == NULL)
return 0; return 0;
...@@ -514,8 +516,23 @@ int check_disk_change(struct block_device *bdev) ...@@ -514,8 +516,23 @@ int check_disk_change(struct block_device *bdev)
if (invalidate_device(dev, 0)) if (invalidate_device(dev, 0))
printk("VFS: busy inodes on changed media.\n"); printk("VFS: busy inodes on changed media.\n");
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) if (bdops->revalidate)
bdops->revalidate(dev); bdops->revalidate(dev);
grok_partitions(dev, part[0].nr_sects);
}
}
up(&bdev->bd_part_sem);
}
} else {
if (bdops->revalidate)
bdops->revalidate(dev);
}
return 1; return 1;
} }
...@@ -734,9 +751,38 @@ int blkdev_close(struct inode * inode, struct file * filp) ...@@ -734,9 +751,38 @@ int blkdev_close(struct inode * inode, struct file * filp)
return blkdev_put(inode->i_bdev, BDEV_FILE); 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, static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
unsigned long arg) unsigned long arg)
{ {
struct block_device *bdev = inode->i_bdev;
int ret = -EINVAL; int ret = -EINVAL;
switch (cmd) { switch (cmd) {
/* /*
...@@ -756,21 +802,23 @@ static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ...@@ -756,21 +802,23 @@ static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
case BLKFRASET: case BLKFRASET:
case BLKBSZSET: case BLKBSZSET:
case BLKPG: case BLKPG:
ret = blk_ioctl(inode->i_bdev, cmd, arg); ret = blk_ioctl(bdev, cmd, arg);
break; break;
default: default:
if (inode->i_bdev->bd_op->ioctl) if (bdev->bd_op->ioctl)
ret =inode->i_bdev->bd_op->ioctl(inode, file, cmd, arg); ret =bdev->bd_op->ioctl(inode, file, cmd, arg);
if (ret == -EINVAL) { if (ret == -EINVAL) {
switch (cmd) { switch (cmd) {
case BLKGETSIZE: case BLKGETSIZE:
case BLKGETSIZE64: case BLKGETSIZE64:
case BLKFLSBUF: case BLKFLSBUF:
case BLKROSET: 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; return ret;
} }
......
...@@ -2377,23 +2377,20 @@ static int check_disc_changed (struct devfs_entry *de) ...@@ -2377,23 +2377,20 @@ static int check_disc_changed (struct devfs_entry *de)
int tmp; int tmp;
int retval = 0; int retval = 0;
kdev_t dev = mk_kdev (de->u.fcb.u.device.major, de->u.fcb.u.device.minor); 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; struct block_device_operations *bdops;
extern int warn_no_part; extern int warn_no_part;
if ( !S_ISBLK (de->mode) ) return 0; if ( !S_ISBLK (de->mode) ) return 0;
bdev = bdget(kdev_t_to_nr(dev));
if (!bdev) return 0;
bdops = devfs_get_ops (de); bdops = devfs_get_ops (de);
if (!bdops) return 0; if (!bdops) return 0;
if (bdops->check_media_change == NULL) goto out; bdev->bd_op = bdops;
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");
/* Ugly hack to disable messages about unable to read partition table */ /* Ugly hack to disable messages about unable to read partition table */
tmp = warn_no_part; tmp = warn_no_part;
warn_no_part = 0; warn_no_part = 0;
if (bdops->revalidate) bdops->revalidate (dev); retval = check_disk_change(bdev);
warn_no_part = tmp; warn_no_part = tmp;
out: out:
devfs_put_ops (de); devfs_put_ops (de);
......
...@@ -1307,31 +1307,5 @@ static inline ino_t parent_ino(struct dentry *dentry) ...@@ -1307,31 +1307,5 @@ static inline ino_t parent_ino(struct dentry *dentry)
return res; 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 /* __KERNEL__ */
#endif /* _LINUX_FS_H */ #endif /* _LINUX_FS_H */
...@@ -1161,7 +1161,7 @@ extern int idescsi_init(void); ...@@ -1161,7 +1161,7 @@ extern int idescsi_init(void);
extern int ata_register_device(struct ata_device *, struct ata_operations *); extern int ata_register_device(struct ata_device *, struct ata_operations *);
extern int ata_unregister_device(struct ata_device *drive); 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); extern void ide_driver_module(void);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment