summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acorn/block/fd1772.c26
-rw-r--r--drivers/block/acsi.c4
-rw-r--r--drivers/block/amiflop.c2
-rw-r--r--drivers/block/ataflop.c23
-rw-r--r--drivers/block/floppy.c22
-rw-r--r--drivers/block/swim3.c2
-rw-r--r--drivers/block/swim_iop.c2
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/cdrom/sonycd535.c4
-rw-r--r--drivers/ide/ide-disk.c2
-rw-r--r--drivers/ide/ide-floppy.c2
-rw-r--r--drivers/ide/ide-pmac.c2
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--fs/block_dev.c71
-rw-r--r--fs/super.c2
-rw-r--r--include/linux/fs.h3
-rw-r--r--kernel/ksyms.c1
18 files changed, 76 insertions, 98 deletions
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index 0174e6880c67..208eb48a5576 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -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);
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 3316fcd57208..de86813ad9a7 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -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 );
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 933f28be4d69..e5b8e0e83010 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -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;
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 91e1382b49c9..e21105a8b421 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -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);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 97e1b16e16fa..8105827611a1 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -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);
}
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index dff2ddec1fa3..43c2ce1ff7aa 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -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;
}
diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
index ad0a73046b3e..927bcf6e041a 100644
--- a/drivers/block/swim_iop.c
+++ b/drivers/block/swim_iop.c
@@ -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;
}
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 7b6dbbee9d95..8976f062b11c 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -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;
}
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
index b244be024ec7..6344f18b175c 100644
--- a/drivers/cdrom/sonycd535.c
+++ b/drivers/cdrom/sonycd535.c
@@ -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
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 58499ebbfa4e..1d05083bbfc5 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -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
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 56d076b902ff..5220ed1c3b26 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -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))
{
diff --git a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c
index 4630dbc4fe5d..4c5a3dbab4c8 100644
--- a/drivers/ide/ide-pmac.c
+++ b/drivers/ide/ide-pmac.c
@@ -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. */
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 911deaf7e380..1a3d5ccc3b6c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -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.
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index c2fdb067a7fc..a4cc0f40d948 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -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 */
}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 5723ad522ee5..f5b1016fd052 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -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 @@ out2:
}
}
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();
diff --git a/fs/super.c b/fs/super.c
index 2fc157c3fb27..e5232d531047 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -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;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 66aea391ce29..b0d9ffe25088 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -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 *);
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 2cfdac0db08e..82bec97409d0 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -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);