[PATCH] sanitize blkdev_get() and friends
* get rid of fake struct file/struct dentry in __blkdev_get() * merge __blkdev_get() and do_open() * get rid of flags argument of blkdev_get() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
e5eb8caa83
Коммит
572c489215
|
@ -2332,7 +2332,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
|
||||||
* so bdget() can't fail.
|
* so bdget() can't fail.
|
||||||
*/
|
*/
|
||||||
bdget(pd->bdev->bd_dev);
|
bdget(pd->bdev->bd_dev);
|
||||||
if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY)))
|
if ((ret = blkdev_get(pd->bdev, FMODE_READ)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((ret = bd_claim(pd->bdev, pd)))
|
if ((ret = bd_claim(pd->bdev, pd)))
|
||||||
|
@ -2765,7 +2765,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
|
||||||
bdev = bdget(dev);
|
bdev = bdget(dev);
|
||||||
if (!bdev)
|
if (!bdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
ret = blkdev_get(bdev, FMODE_READ, O_RDONLY | O_NONBLOCK);
|
ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ static int raw_open(struct inode *inode, struct file *filp)
|
||||||
if (!bdev)
|
if (!bdev)
|
||||||
goto out;
|
goto out;
|
||||||
igrab(bdev->bd_inode);
|
igrab(bdev->bd_inode);
|
||||||
err = blkdev_get(bdev, filp->f_mode, 0);
|
err = blkdev_get(bdev, filp->f_mode);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = bd_claim(bdev, raw_open);
|
err = bd_claim(bdev, raw_open);
|
||||||
|
|
|
@ -99,7 +99,7 @@ int dasd_scan_partitions(struct dasd_block *block)
|
||||||
struct block_device *bdev;
|
struct block_device *bdev;
|
||||||
|
|
||||||
bdev = bdget_disk(block->gdp, 0);
|
bdev = bdget_disk(block->gdp, 0);
|
||||||
if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0)
|
if (!bdev || blkdev_get(bdev, FMODE_READ) < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
/*
|
/*
|
||||||
* See fs/partition/check.c:register_disk,rescan_partitions
|
* See fs/partition/check.c:register_disk,rescan_partitions
|
||||||
|
|
|
@ -844,9 +844,8 @@ struct block_device *open_by_devnum(dev_t dev, fmode_t mode)
|
||||||
{
|
{
|
||||||
struct block_device *bdev = bdget(dev);
|
struct block_device *bdev = bdget(dev);
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY;
|
|
||||||
if (bdev)
|
if (bdev)
|
||||||
err = blkdev_get(bdev, mode, flags);
|
err = blkdev_get(bdev, mode);
|
||||||
return err ? ERR_PTR(err) : bdev;
|
return err ? ERR_PTR(err) : bdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,8 +974,6 @@ void bd_set_size(struct block_device *bdev, loff_t size)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bd_set_size);
|
EXPORT_SYMBOL(bd_set_size);
|
||||||
|
|
||||||
static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags,
|
|
||||||
int for_part);
|
|
||||||
static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
|
static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -986,7 +983,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
|
||||||
* mutex_lock_nested(whole->bd_mutex, 1)
|
* mutex_lock_nested(whole->bd_mutex, 1)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
|
||||||
{
|
{
|
||||||
struct gendisk *disk;
|
struct gendisk *disk;
|
||||||
struct hd_struct *part = NULL;
|
struct hd_struct *part = NULL;
|
||||||
|
@ -994,9 +991,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
int partno;
|
int partno;
|
||||||
int perm = 0;
|
int perm = 0;
|
||||||
|
|
||||||
if (file->f_mode & FMODE_READ)
|
if (mode & FMODE_READ)
|
||||||
perm |= MAY_READ;
|
perm |= MAY_READ;
|
||||||
if (file->f_mode & FMODE_WRITE)
|
if (mode & FMODE_WRITE)
|
||||||
perm |= MAY_WRITE;
|
perm |= MAY_WRITE;
|
||||||
/*
|
/*
|
||||||
* hooks: /n/, see "layering violations".
|
* hooks: /n/, see "layering violations".
|
||||||
|
@ -1007,15 +1004,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->f_flags & O_NDELAY)
|
|
||||||
file->f_mode |= FMODE_NDELAY;
|
|
||||||
if (file->f_flags & O_EXCL)
|
|
||||||
file->f_mode |= FMODE_EXCL;
|
|
||||||
if ((file->f_flags & O_ACCMODE) == 3)
|
|
||||||
file->f_mode |= FMODE_WRITE_IOCTL;
|
|
||||||
|
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
file->f_mapping = bdev->bd_inode->i_mapping;
|
|
||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
|
|
||||||
|
@ -1034,7 +1023,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
if (!partno) {
|
if (!partno) {
|
||||||
struct backing_dev_info *bdi;
|
struct backing_dev_info *bdi;
|
||||||
if (disk->fops->open) {
|
if (disk->fops->open) {
|
||||||
ret = disk->fops->open(bdev, file->f_mode);
|
ret = disk->fops->open(bdev, mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_clear;
|
goto out_clear;
|
||||||
}
|
}
|
||||||
|
@ -1054,7 +1043,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
if (!whole)
|
if (!whole)
|
||||||
goto out_clear;
|
goto out_clear;
|
||||||
BUG_ON(for_part);
|
BUG_ON(for_part);
|
||||||
ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1);
|
ret = __blkdev_get(whole, mode, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_clear;
|
goto out_clear;
|
||||||
bdev->bd_contains = whole;
|
bdev->bd_contains = whole;
|
||||||
|
@ -1075,7 +1064,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
disk = NULL;
|
disk = NULL;
|
||||||
if (bdev->bd_contains == bdev) {
|
if (bdev->bd_contains == bdev) {
|
||||||
if (bdev->bd_disk->fops->open) {
|
if (bdev->bd_disk->fops->open) {
|
||||||
ret = bdev->bd_disk->fops->open(bdev, file->f_mode);
|
ret = bdev->bd_disk->fops->open(bdev, mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock_bdev;
|
goto out_unlock_bdev;
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1084,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
bdev->bd_part = NULL;
|
bdev->bd_part = NULL;
|
||||||
bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
|
bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
|
||||||
if (bdev != bdev->bd_contains)
|
if (bdev != bdev->bd_contains)
|
||||||
__blkdev_put(bdev->bd_contains, file->f_mode, 1);
|
__blkdev_put(bdev->bd_contains, mode, 1);
|
||||||
bdev->bd_contains = NULL;
|
bdev->bd_contains = NULL;
|
||||||
out_unlock_bdev:
|
out_unlock_bdev:
|
||||||
mutex_unlock(&bdev->bd_mutex);
|
mutex_unlock(&bdev->bd_mutex);
|
||||||
|
@ -1111,28 +1100,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags,
|
int blkdev_get(struct block_device *bdev, fmode_t mode)
|
||||||
int for_part)
|
|
||||||
{
|
{
|
||||||
/*
|
return __blkdev_get(bdev, mode, 0);
|
||||||
* This crockload is due to bad choice of ->open() type.
|
|
||||||
* It will go away.
|
|
||||||
* For now, block device ->open() routine must _not_
|
|
||||||
* examine anything in 'inode' argument except ->i_rdev.
|
|
||||||
*/
|
|
||||||
struct file fake_file = {};
|
|
||||||
struct dentry fake_dentry = {};
|
|
||||||
fake_file.f_mode = mode;
|
|
||||||
fake_file.f_flags = flags;
|
|
||||||
fake_file.f_path.dentry = &fake_dentry;
|
|
||||||
fake_dentry.d_inode = bdev->bd_inode;
|
|
||||||
|
|
||||||
return do_open(bdev, &fake_file, for_part);
|
|
||||||
}
|
|
||||||
|
|
||||||
int blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags)
|
|
||||||
{
|
|
||||||
return __blkdev_get(bdev, mode, flags, 0);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blkdev_get);
|
EXPORT_SYMBOL(blkdev_get);
|
||||||
|
|
||||||
|
@ -1149,15 +1119,24 @@ static int blkdev_open(struct inode * inode, struct file * filp)
|
||||||
*/
|
*/
|
||||||
filp->f_flags |= O_LARGEFILE;
|
filp->f_flags |= O_LARGEFILE;
|
||||||
|
|
||||||
|
if (filp->f_flags & O_NDELAY)
|
||||||
|
filp->f_mode |= FMODE_NDELAY;
|
||||||
|
if (filp->f_flags & O_EXCL)
|
||||||
|
filp->f_mode |= FMODE_EXCL;
|
||||||
|
if ((filp->f_flags & O_ACCMODE) == 3)
|
||||||
|
filp->f_mode |= FMODE_WRITE_IOCTL;
|
||||||
|
|
||||||
bdev = bd_acquire(inode);
|
bdev = bd_acquire(inode);
|
||||||
if (bdev == NULL)
|
if (bdev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
res = do_open(bdev, filp, 0);
|
filp->f_mapping = bdev->bd_inode->i_mapping;
|
||||||
|
|
||||||
|
res = blkdev_get(bdev, filp->f_mode);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (!(filp->f_flags & O_EXCL) )
|
if (!(filp->f_mode & FMODE_EXCL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(res = bd_claim(bdev, filp)))
|
if (!(res = bd_claim(bdev, filp)))
|
||||||
|
@ -1327,7 +1306,7 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h
|
||||||
if (IS_ERR(bdev))
|
if (IS_ERR(bdev))
|
||||||
return bdev;
|
return bdev;
|
||||||
|
|
||||||
error = blkdev_get(bdev, mode, 0);
|
error = blkdev_get(bdev, mode);
|
||||||
if (error)
|
if (error)
|
||||||
return ERR_PTR(error);
|
return ERR_PTR(error);
|
||||||
error = -EACCES;
|
error = -EACCES;
|
||||||
|
|
|
@ -1268,7 +1268,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
reg->hr_bdev = I_BDEV(filp->f_mapping->host);
|
reg->hr_bdev = I_BDEV(filp->f_mapping->host);
|
||||||
ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, 0);
|
ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
reg->hr_bdev = NULL;
|
reg->hr_bdev = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -485,7 +485,7 @@ void register_disk(struct gendisk *disk)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
bdev->bd_invalidated = 1;
|
bdev->bd_invalidated = 1;
|
||||||
err = blkdev_get(bdev, FMODE_READ, 0);
|
err = blkdev_get(bdev, FMODE_READ);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
blkdev_put(bdev, FMODE_READ);
|
blkdev_put(bdev, FMODE_READ);
|
||||||
|
|
|
@ -1722,7 +1722,7 @@ extern int blkdev_driver_ioctl(struct inode *inode, struct file *file,
|
||||||
struct gendisk *disk, unsigned cmd,
|
struct gendisk *disk, unsigned cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
|
extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
|
||||||
extern int blkdev_get(struct block_device *, fmode_t, unsigned);
|
extern int blkdev_get(struct block_device *, fmode_t);
|
||||||
extern int blkdev_put(struct block_device *, fmode_t);
|
extern int blkdev_put(struct block_device *, fmode_t);
|
||||||
extern int bd_claim(struct block_device *, void *);
|
extern int bd_claim(struct block_device *, void *);
|
||||||
extern void bd_release(struct block_device *);
|
extern void bd_release(struct block_device *);
|
||||||
|
|
|
@ -172,7 +172,7 @@ static int swsusp_swap_check(void) /* This is called before saving image */
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
root_swap = res;
|
root_swap = res;
|
||||||
res = blkdev_get(resume_bdev, FMODE_WRITE, O_RDWR);
|
res = blkdev_get(resume_bdev, FMODE_WRITE);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче