[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:
Al Viro
2007-10-08 13:24:05 -04:00
parent e5eb8caa83
commit 572c489215
8 changed files with 30 additions and 51 deletions

View File

@@ -844,9 +844,8 @@ struct block_device *open_by_devnum(dev_t dev, fmode_t mode)
{
struct block_device *bdev = bdget(dev);
int err = -ENOMEM;
int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY;
if (bdev)
err = blkdev_get(bdev, mode, flags);
err = blkdev_get(bdev, mode);
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);
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);
/*
@@ -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)
*/
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 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 perm = 0;
if (file->f_mode & FMODE_READ)
if (mode & FMODE_READ)
perm |= MAY_READ;
if (file->f_mode & FMODE_WRITE)
if (mode & FMODE_WRITE)
perm |= MAY_WRITE;
/*
* 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;
}
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;
file->f_mapping = bdev->bd_inode->i_mapping;
lock_kernel();
@@ -1034,7 +1023,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
if (!partno) {
struct backing_dev_info *bdi;
if (disk->fops->open) {
ret = disk->fops->open(bdev, file->f_mode);
ret = disk->fops->open(bdev, mode);
if (ret)
goto out_clear;
}
@@ -1054,7 +1043,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
if (!whole)
goto out_clear;
BUG_ON(for_part);
ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1);
ret = __blkdev_get(whole, mode, 1);
if (ret)
goto out_clear;
bdev->bd_contains = whole;
@@ -1075,7 +1064,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
disk = NULL;
if (bdev->bd_contains == bdev) {
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)
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_inode->i_data.backing_dev_info = &default_backing_dev_info;
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;
out_unlock_bdev:
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;
}
static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags,
int for_part)
int blkdev_get(struct block_device *bdev, fmode_t mode)
{
/*
* 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);
return __blkdev_get(bdev, mode, 0);
}
EXPORT_SYMBOL(blkdev_get);
@@ -1149,15 +1119,24 @@ static int blkdev_open(struct inode * inode, struct file * filp)
*/
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);
if (bdev == NULL)
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)
return res;
if (!(filp->f_flags & O_EXCL) )
if (!(filp->f_mode & FMODE_EXCL))
return 0;
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))
return bdev;
error = blkdev_get(bdev, mode, 0);
error = blkdev_get(bdev, mode);
if (error)
return ERR_PTR(error);
error = -EACCES;