Commit 814bd2ba authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] make check_disk_change() use struct block_device

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().
parent 5c2f6403
......@@ -1324,37 +1324,25 @@ static int invalidate_drive(int rdev)
#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;
}
......@@ -1520,7 +1508,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
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);
......
......@@ -1156,7 +1156,7 @@ static int acsi_open( struct inode * inode, struct file * 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);
......@@ -1164,7 +1164,7 @@ static int acsi_open( struct inode * inode, struct file * filp )
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 );
......
......@@ -1621,7 +1621,7 @@ static int floppy_open(struct inode *inode, struct file *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;
......
......@@ -382,7 +382,6 @@ static void finish_fdc_done( int dummy );
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 );
......@@ -1531,16 +1530,6 @@ void do_fd_request(request_queue_t * q)
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)
{
......@@ -1719,12 +1708,16 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
/* 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;
}
......@@ -1901,7 +1894,7 @@ static int floppy_open( struct inode *inode, struct file *filp )
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);
......
......@@ -3308,12 +3308,12 @@ static int raw_cmd_ioctl(int cmd, void *param)
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;
}
......@@ -3324,7 +3324,7 @@ static inline void clear_write_error(int drive)
}
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;
......@@ -3354,8 +3354,8 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
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 {
......@@ -3379,7 +3379,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
* 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();
}
......@@ -3544,11 +3544,11 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
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**)
......@@ -3579,7 +3579,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case FDFMTEND:
case FDFLUSH:
LOCK_FDC(drive,1);
return invalidate_drive(device);
return invalidate_drive(inode->i_bdev);
case FDSETEMSGTRESH:
UDP->max_errors.reporting =
......@@ -3805,7 +3805,7 @@ static int floppy_open(struct inode * inode, struct file * filp)
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);
}
......
......@@ -897,7 +897,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
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;
}
......
......@@ -387,7 +387,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
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;
}
......
......@@ -486,7 +486,7 @@ int cdrom_open(struct inode *ip, struct file *fp)
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;
}
......
......@@ -1402,9 +1402,7 @@ cdu_open(struct inode *inode,
sony_inuse = 0;
return -EIO;
}
if (inode) {
check_disk_change(inode->i_rdev);
}
check_disk_change(inode->i_bdev);
sony_usage++;
#ifdef LOCK_DOORS
......
......@@ -659,7 +659,7 @@ static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_devic
{
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
......
......@@ -1496,7 +1496,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp, struct ata_dev
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))
{
......
......@@ -1558,7 +1558,7 @@ idepmac_wake_device(struct ata_device *drive, int used_dma)
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. */
......
......@@ -501,7 +501,7 @@ static int sd_open(struct inode *inode, struct file *filp)
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.
......
......@@ -402,8 +402,6 @@ static int sr_open(struct cdrom_device_info *cdi, int purpose)
{
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 */
}
......
......@@ -498,34 +498,18 @@ int unregister_blkdev(unsigned int major, const char * name)
* 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");
......@@ -535,12 +519,25 @@ int check_disk_change(kdev_t dev)
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));
......@@ -551,12 +548,15 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
}
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);
......@@ -578,8 +578,8 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
}
}
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;
}
......@@ -588,10 +588,6 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
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);
......@@ -644,8 +640,11 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
}
}
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();
......
......@@ -502,7 +502,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
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;
......
......@@ -1131,7 +1131,8 @@ extern int fs_may_remount_ro(struct super_block *);
*/
#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 *);
......
......@@ -180,6 +180,7 @@ EXPORT_SYMBOL(filp_close);
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);
......
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