Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 572c4892 authored by Al Viro's avatar Al Viro
Browse files

[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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e5eb8caa
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -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;


+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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
+22 −43
Original line number Original line Diff line number Diff line
@@ -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;
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
Loading