mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
raw: don't keep unopened block device around
Turn binding into a normal dev_t as the struct block device doesn't buy us anything and use blkdev_open_by_dev to actually open it. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
0fc66c9d63
commit
5a56ad7882
@ -28,7 +28,8 @@
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
struct raw_device_data {
|
||||
struct block_device *binding;
|
||||
dev_t binding;
|
||||
struct block_device *bdev;
|
||||
int inuse;
|
||||
};
|
||||
|
||||
@ -73,14 +74,15 @@ static int raw_open(struct inode *inode, struct file *filp)
|
||||
/*
|
||||
* All we need to do on open is check that the device is bound.
|
||||
*/
|
||||
bdev = raw_devices[minor].binding;
|
||||
err = -ENODEV;
|
||||
if (!bdev)
|
||||
if (!raw_devices[minor].binding)
|
||||
goto out;
|
||||
bdgrab(bdev);
|
||||
err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open);
|
||||
if (err)
|
||||
bdev = blkdev_get_by_dev(raw_devices[minor].binding,
|
||||
filp->f_mode | FMODE_EXCL, raw_open);
|
||||
if (IS_ERR(bdev)) {
|
||||
err = PTR_ERR(bdev);
|
||||
goto out;
|
||||
}
|
||||
err = set_blocksize(bdev, bdev_logical_block_size(bdev));
|
||||
if (err)
|
||||
goto out1;
|
||||
@ -90,6 +92,7 @@ static int raw_open(struct inode *inode, struct file *filp)
|
||||
file_inode(filp)->i_mapping =
|
||||
bdev->bd_inode->i_mapping;
|
||||
filp->private_data = bdev;
|
||||
raw_devices[minor].bdev = bdev;
|
||||
mutex_unlock(&raw_mutex);
|
||||
return 0;
|
||||
|
||||
@ -110,7 +113,7 @@ static int raw_release(struct inode *inode, struct file *filp)
|
||||
struct block_device *bdev;
|
||||
|
||||
mutex_lock(&raw_mutex);
|
||||
bdev = raw_devices[minor].binding;
|
||||
bdev = raw_devices[minor].bdev;
|
||||
if (--raw_devices[minor].inuse == 0)
|
||||
/* Here inode->i_mapping == bdev->bd_inode->i_mapping */
|
||||
inode->i_mapping = &inode->i_data;
|
||||
@ -133,6 +136,7 @@ raw_ioctl(struct file *filp, unsigned int command, unsigned long arg)
|
||||
static int bind_set(int number, u64 major, u64 minor)
|
||||
{
|
||||
dev_t dev = MKDEV(major, minor);
|
||||
dev_t raw = MKDEV(RAW_MAJOR, number);
|
||||
struct raw_device_data *rawdev;
|
||||
int err = 0;
|
||||
|
||||
@ -166,25 +170,17 @@ static int bind_set(int number, u64 major, u64 minor)
|
||||
mutex_unlock(&raw_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (rawdev->binding) {
|
||||
bdput(rawdev->binding);
|
||||
if (rawdev->binding)
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
rawdev->binding = dev;
|
||||
if (!dev) {
|
||||
/* unbind */
|
||||
rawdev->binding = NULL;
|
||||
device_destroy(raw_class, MKDEV(RAW_MAJOR, number));
|
||||
device_destroy(raw_class, raw);
|
||||
} else {
|
||||
rawdev->binding = bdget(dev);
|
||||
if (rawdev->binding == NULL) {
|
||||
err = -ENOMEM;
|
||||
} else {
|
||||
dev_t raw = MKDEV(RAW_MAJOR, number);
|
||||
__module_get(THIS_MODULE);
|
||||
device_destroy(raw_class, raw);
|
||||
device_create(raw_class, NULL, raw, NULL,
|
||||
"raw%d", number);
|
||||
}
|
||||
__module_get(THIS_MODULE);
|
||||
device_destroy(raw_class, raw);
|
||||
device_create(raw_class, NULL, raw, NULL, "raw%d", number);
|
||||
}
|
||||
mutex_unlock(&raw_mutex);
|
||||
return err;
|
||||
@ -192,18 +188,9 @@ static int bind_set(int number, u64 major, u64 minor)
|
||||
|
||||
static int bind_get(int number, dev_t *dev)
|
||||
{
|
||||
struct raw_device_data *rawdev;
|
||||
struct block_device *bdev;
|
||||
|
||||
if (number <= 0 || number >= max_raw_minors)
|
||||
return -EINVAL;
|
||||
|
||||
rawdev = &raw_devices[number];
|
||||
|
||||
mutex_lock(&raw_mutex);
|
||||
bdev = rawdev->binding;
|
||||
*dev = bdev ? bdev->bd_dev : 0;
|
||||
mutex_unlock(&raw_mutex);
|
||||
*dev = raw_devices[number].binding;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user