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);
{
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)
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");
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 **************************/
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;
}
*
*/
-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);
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;
}
/* 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);
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);
open: cciss_open,
release: cciss_release,
ioctl: cciss_ioctl,
- revalidate: frevalidate_logvol,
+ revalidate: cciss_revalidate,
};
#include "cciss_scsi.c" /* For SCSI tape support */
return(0);
}
- case BLKRRPART:
- return revalidate_logvol(inode->i_rdev, 1);
case CCISS_GETPCIINFO:
{
cciss_pci_info_struct pciinfo;
}
+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
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
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);
open: ida_open,
release: ida_release,
ioctl: ida_ioctl,
- revalidate: frevalidate_logvol,
+ revalidate: ida_revalidate,
};
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)))
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
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()
}
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;
}
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)
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);
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)
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;
}
/*
*/
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,
if (copy_to_user((void *) arg, &geo, sizeof(geo)))
return -EFAULT;
return 0;
-
- default:
- return -EINVAL;
}
- return -ENOTTY; /* unknown command */
+ return -EINVAL;
}
/*
-----------------------------------------------------------------------------------
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)
{
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);
static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
-static int revalidate_hddisk(kdev_t, int);
-
#define TIMEOUT_VALUE (6*HZ)
#define HD_DELAY 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:
return -EINVAL;
}
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];
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)
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 = {
.ioctl = idetape_blkdev_ioctl,
.open = idetape_blkdev_open,
.release = idetape_blkdev_release,
- .check_media_change = NULL,
- .revalidate = idetape_revalidate,
};
.release = ide_release,
.ioctl = ata_ioctl,
.check_media_change = ide_check_media_change,
- .revalidate = ata_revalidate
+ .revalidate = ide_revalidate
}};
EXPORT_SYMBOL(ide_fops);
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.
*/
* 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)
}
}
-EXPORT_SYMBOL(unregister_ata_driver);
-
EXPORT_SYMBOL(ide_hwifs);
EXPORT_SYMBOL(ide_lock);
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);
open: ftl_open,
release: ftl_close,
ioctl: ftl_ioctl,
+ revalidate: ftl_revalidate,
};
/*======================================================================
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 */
/*======================================================================
======================================================================*/
-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;
}
/*======================================================================
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;
}
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.
*/
{ 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 }
{
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 =
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);
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);
}
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;
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;
}
/**
{
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;
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;
}
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) {
/*
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;
}
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);
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 */
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