diff options
| author | Alexander Viro <viro@math.psu.edu> | 2002-08-10 02:21:36 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-08-10 02:21:36 -0700 |
| commit | 814bd2ba199743fb93045459f28f521036671b86 (patch) | |
| tree | 703864fc6ac162e26356e2166f4562609b7f8d3e | |
| parent | 5c2f64032dc44de9ce42a9c52dbe675f6cafba1d (diff) | |
[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().
| -rw-r--r-- | drivers/acorn/block/fd1772.c | 26 | ||||
| -rw-r--r-- | drivers/block/acsi.c | 4 | ||||
| -rw-r--r-- | drivers/block/amiflop.c | 2 | ||||
| -rw-r--r-- | drivers/block/ataflop.c | 23 | ||||
| -rw-r--r-- | drivers/block/floppy.c | 22 | ||||
| -rw-r--r-- | drivers/block/swim3.c | 2 | ||||
| -rw-r--r-- | drivers/block/swim_iop.c | 2 | ||||
| -rw-r--r-- | drivers/cdrom/cdrom.c | 2 | ||||
| -rw-r--r-- | drivers/cdrom/sonycd535.c | 4 | ||||
| -rw-r--r-- | drivers/ide/ide-disk.c | 2 | ||||
| -rw-r--r-- | drivers/ide/ide-floppy.c | 2 | ||||
| -rw-r--r-- | drivers/ide/ide-pmac.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/sr.c | 2 | ||||
| -rw-r--r-- | fs/block_dev.c | 71 | ||||
| -rw-r--r-- | fs/super.c | 2 | ||||
| -rw-r--r-- | include/linux/fs.h | 3 | ||||
| -rw-r--r-- | kernel/ksyms.c | 1 |
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); |
