check_disk_change() converted to passing struct block_device.
Old variant is still needed for a couple of places; wrapper
is provided (__check_disk_change(kdev)). do_open() logics
with setting ->bd_op sanitized - now we do that before calling
->open().
#endif
set_bit(rdev & 3, &fake_change);
- check_disk_change(rdev);
return 0;
}
static int fd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long param)
{
- int drive, device;
+ struct block_device *bdev = inode->i_bdev;
+ int drive = MINOR(bdev->bd_dev);
- device = inode->i_rdev;
- drive = minor(device);
switch (cmd) {
- case FDFMTBEG:
- return 0;
- /* case FDC1772LRPRM: ??? DAG what does this do??
- unit[drive].disktype = NULL;
- floppy_sizes[drive] = MAX_DISK_SIZE;
- return invalidate_drive (device); */
case FDFMTEND:
case FDFLUSH:
- return invalidate_drive(drive);
- }
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (drive < 0 || drive > 3)
- return -EINVAL;
- switch (cmd) {
+ invalidate_drive(drive);
+ check_disk_change(bdev);
+ case FDFMTBEG:
+ return 0;
default:
return -EINVAL;
}
- return 0;
}
return 0;
if (filp->f_mode & 3) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
if (filp->f_mode & 2) {
if (unit[drive].wpstat) {
floppy_release(inode, filp);
#if 0
aip->changed = 1; /* safety first */
#endif
- check_disk_change( inode->i_rdev );
+ check_disk_change( inode->i_bdev );
if (aip->changed) /* revalidate was not successful (no medium) */
return -ENXIO;
acsi_prevent_removal(device, 1);
access_count[device]++;
if (filp && filp->f_mode) {
- check_disk_change( inode->i_rdev );
+ check_disk_change( inode->i_bdev );
if (filp->f_mode & 2) {
if (aip->read_only) {
acsi_release( inode, filp );
return -ENODEV;
if (filp && filp->f_mode & 3) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
if (filp->f_mode & 2 ) {
int wrprot;
static __inline__ void copy_buffer( void *from, void *to);
static void setup_req_params( int drive );
static void redo_fd_request( void);
-static int invalidate_drive(kdev_t rdev);
static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
cmd, unsigned long param);
static void fd_probe( int drive );
atari_enable_irq( IRQ_MFP_FDC );
}
-
-static int invalidate_drive(kdev_t rdev)
-{
- /* invalidate the buffer track to force a reread */
- BufferDrive = -1;
- set_bit(minor(rdev) & 3, &fake_change);
- check_disk_change(rdev);
- return 0;
-}
-
static int fd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long param)
{
/* MSch: invalidate default_params */
default_params[drive].blocks = 0;
floppy_sizes[drive] = MAX_DISK_SIZE;
- return invalidate_drive (device);
case FDFMTEND:
case FDFLUSH:
- return invalidate_drive(device);
+ /* invalidate the buffer track to force a reread */
+ BufferDrive = -1;
+ set_bit(drive, &fake_change);
+ check_disk_change(inode->i_bdev);
+ return 0;
+ default:
+ return -EINVAL;
}
- return -EINVAL;
}
return 0;
if (filp->f_mode & 3) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
if (filp->f_mode & 2) {
if (UD.wpstat) {
floppy_release(inode, filp);
return ret;
}
-static int invalidate_drive(kdev_t rdev)
+static int invalidate_drive(struct block_device *bdev)
{
/* invalidate the buffer track to force a reread */
- set_bit(DRIVE(rdev), &fake_change);
+ set_bit(DRIVE(to_kdev_t(bdev->bd_dev)), &fake_change);
process_fd_request();
- check_disk_change(rdev);
+ check_disk_change(bdev);
return 0;
}
}
static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
- int drive, int type, kdev_t device)
+ int drive, int type, struct block_device *bdev)
{
int cnt;
for (cnt = 0; cnt < N_DRIVE; cnt++){
if (ITYPE(drive_state[cnt].fd_device) == type &&
drive_state[cnt].fd_ref)
- check_disk_change(
- mk_kdev(FLOPPY_MAJOR,
+ __check_disk_change(
+ MKDEV(FLOPPY_MAJOR,
drive_state[cnt].fd_device));
}
} else {
* mtools often changes the geometry of the disk after
* looking at the boot block */
if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack)
- invalidate_drive(device);
+ invalidate_drive(bdev);
else
process_fd_request();
}
current_type[drive] = NULL;
floppy_sizes[drive] = MAX_DISK_SIZE;
UDRS->keep_data = 0;
- return invalidate_drive(device);
+ return invalidate_drive(inode->i_bdev);
case FDSETPRM:
case FDDEFPRM:
return set_geometry(cmd, & inparam.g,
- drive, type, device);
+ drive, type, inode->i_bdev);
case FDGETPRM:
ECALL(get_floppy_geometry(drive, type,
(struct floppy_struct**)
case FDFMTEND:
case FDFLUSH:
LOCK_FDC(drive,1);
- return invalidate_drive(device);
+ return invalidate_drive(inode->i_bdev);
case FDSETEMSGTRESH:
UDP->max_errors.reporting =
return 0;
if (filp->f_mode & 3) {
UDRS->last_checked = 0;
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
if (UTESTF(FD_DISK_CHANGED))
RETERR(ENXIO);
}
if (err == 0 && (filp->f_flags & O_NDELAY) == 0
&& (filp->f_mode & 3)) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
if (fs->ejected)
err = -ENXIO;
}
if (err == 0 && (filp->f_flags & O_NDELAY) == 0
&& (filp->f_mode & 3)) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
if (fs->ejected)
err = -ENXIO;
}
cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count);
/* Do this on open. Don't wait for mount, because they might
not be mounting, but opening with O_NONBLOCK */
- check_disk_change(dev);
+ check_disk_change(ip->i_bdev);
return ret;
}
sony_inuse = 0;
return -EIO;
}
- if (inode) {
- check_disk_change(inode->i_rdev);
- }
+ check_disk_change(inode->i_bdev);
sony_usage++;
#ifdef LOCK_DOORS
{
MOD_INC_USE_COUNT;
if (drive->removable && drive->usage == 1) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
/*
* Ignore the return code from door_lock, since the open() has
idefloppy_create_prevent_cmd (&pc, 1);
(void) idefloppy_queue_pc_tail (drive, &pc);
}
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
}
else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags))
{
ata_ops(drive)->check_media_change(drive);
/* We kick the VFS too (see fix in ide.c revalidate) */
- check_disk_change(mk_kdev(drive->channel->major, (drive->select.b.unit) << PARTN_BITS));
+ __check_disk_change(MKDEV(drive->channel->major, (drive->select.b.unit) << PARTN_BITS));
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* We re-enable DMA on the drive if it was active. */
sdp->access_count++;
if (sdp->removable) {
- check_disk_change(inode->i_rdev);
+ check_disk_change(inode->i_bdev);
/*
* If the drive is empty, just let the open fail.
{
Scsi_CD *SCp = cdi->handle;
- check_disk_change(cdi->dev);
-
if (minor(cdi->dev) >= sr_template.dev_max || !SCp->device) {
return -ENXIO; /* No such device */
}
* People changing diskettes in the middle of an operation deserve
* to lose :-)
*/
-int check_disk_change(kdev_t dev)
+int check_disk_change(struct block_device *bdev)
{
- int i;
- struct block_device_operations * bdops = NULL;
-
- i = major(dev);
- if (i < MAX_BLKDEV)
- bdops = blkdevs[i].bdops;
- if (bdops == NULL) {
- devfs_handle_t de;
-
- de = devfs_get_handle(NULL, NULL, i, minor(dev),
- DEVFS_SPECIAL_BLK, 0);
- if (de) {
- bdops = devfs_get_ops(de);
- devfs_put_ops(de); /* We're running in owner module */
- devfs_put(de);
- }
- }
- if (bdops == NULL)
- return 0;
+ struct block_device_operations * bdops = bdev->bd_op;
+ kdev_t dev = to_kdev_t(bdev->bd_dev);
+
if (bdops->check_media_change == NULL)
return 0;
if (!bdops->check_media_change(dev))
return 0;
printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
- __bdevname(dev));
+ bdevname(bdev));
if (invalidate_device(dev, 0))
printk("VFS: busy inodes on changed media.\n");
return 1;
}
+int __check_disk_change(dev_t dev)
+{
+ struct block_device *bdev = bdget(dev);
+ int res;
+ if (!bdev)
+ return 0;
+ if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW) < 0)
+ return 0;
+ res = check_disk_change(bdev);
+ blkdev_put(bdev, BDEV_RAW);
+ return res;
+}
+
static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
{
int ret = -ENXIO;
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct module *owner = NULL;
- struct block_device_operations *ops, *current_ops;
+ struct block_device_operations *ops, *old;
lock_kernel();
ops = get_blkfops(major(dev));
}
down(&bdev->bd_sem);
- if (!bdev->bd_op)
- current_ops = ops;
- else
- current_ops = bdev->bd_op;
- if (!current_ops)
- goto out;
+ old = bdev->bd_op;
+ if (!old) {
+ if (!ops)
+ goto out;
+ bdev->bd_op = ops;
+ } else {
+ if (owner)
+ __MOD_DEC_USE_COUNT(owner);
+ }
if (!bdev->bd_contains) {
unsigned minor = minor(dev);
struct gendisk *g = get_gendisk(dev);
}
}
if (bdev->bd_contains == bdev) {
- if (current_ops->open) {
- ret = current_ops->open(inode, file);
+ if (bdev->bd_op->open) {
+ ret = bdev->bd_op->open(inode, file);
if (ret)
goto out2;
}
bdev->bd_contains->bd_part_count++;
up(&bdev->bd_contains->bd_part_sem);
}
- if (!bdev->bd_op)
- bdev->bd_op = ops;
- else if (owner)
- __MOD_DEC_USE_COUNT(owner);
if (!bdev->bd_openers) {
struct blk_dev_struct *p = blk_dev + major(dev);
struct gendisk *g = get_gendisk(dev);
}
}
out1:
- if (owner)
- __MOD_DEC_USE_COUNT(owner);
+ if (!old) {
+ bdev->bd_op = NULL;
+ if (owner)
+ __MOD_DEC_USE_COUNT(owner);
+ }
out:
up(&bdev->bd_sem);
unlock_kernel();
devfs_put_ops (de); /* Decrement module use count now we're safe */
if (error)
goto out;
- check_disk_change(dev);
+ check_disk_change(bdev);
error = -EACCES;
if (!(flags & MS_RDONLY) && bdev_read_only(bdev))
goto out1;
*/
#define bio_data_dir(bio) ((bio)->bi_rw & 1)
-extern int check_disk_change(kdev_t);
+extern int check_disk_change(struct block_device *);
+extern int __check_disk_change(dev_t);
extern int invalidate_inodes(struct super_block *);
extern int invalidate_device(kdev_t, int);
extern void invalidate_inode_pages(struct inode *);
EXPORT_SYMBOL(put_filp);
EXPORT_SYMBOL(files_lock);
EXPORT_SYMBOL(check_disk_change);
+EXPORT_SYMBOL(__check_disk_change);
EXPORT_SYMBOL(__invalidate_buffers);
EXPORT_SYMBOL(invalidate_bdev);
EXPORT_SYMBOL(invalidate_inodes);