[PATCH] switch loop
ioctl doesn't need BKL here Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
a4af9b48cb
commit
bb21488482
|
@ -652,8 +652,8 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
|
||||||
* This can only work if the loop device is used read-only, and if the
|
* This can only work if the loop device is used read-only, and if the
|
||||||
* new backing store is the same size and type as the old backing store.
|
* new backing store is the same size and type as the old backing store.
|
||||||
*/
|
*/
|
||||||
static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
|
static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
||||||
struct block_device *bdev, unsigned int arg)
|
unsigned int arg)
|
||||||
{
|
{
|
||||||
struct file *file, *old_file;
|
struct file *file, *old_file;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
@ -712,7 +712,7 @@ static inline int is_loop_device(struct file *file)
|
||||||
return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
|
return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
|
static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
||||||
struct block_device *bdev, unsigned int arg)
|
struct block_device *bdev, unsigned int arg)
|
||||||
{
|
{
|
||||||
struct file *file, *f;
|
struct file *file, *f;
|
||||||
|
@ -740,7 +740,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
|
||||||
while (is_loop_device(f)) {
|
while (is_loop_device(f)) {
|
||||||
struct loop_device *l;
|
struct loop_device *l;
|
||||||
|
|
||||||
if (f->f_mapping->host->i_rdev == lo_file->f_mapping->host->i_rdev)
|
if (f->f_mapping->host->i_bdev == bdev)
|
||||||
goto out_putf;
|
goto out_putf;
|
||||||
|
|
||||||
l = f->f_mapping->host->i_bdev->bd_disk->private_data;
|
l = f->f_mapping->host->i_bdev->bd_disk->private_data;
|
||||||
|
@ -786,7 +786,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
|
||||||
goto out_putf;
|
goto out_putf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(lo_file->f_mode & FMODE_WRITE))
|
if (!(mode & FMODE_WRITE))
|
||||||
lo_flags |= LO_FLAGS_READ_ONLY;
|
lo_flags |= LO_FLAGS_READ_ONLY;
|
||||||
|
|
||||||
set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);
|
set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);
|
||||||
|
@ -918,8 +918,10 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
|
||||||
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
|
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
|
||||||
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
|
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
|
||||||
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
|
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
|
||||||
|
if (bdev)
|
||||||
invalidate_bdev(bdev);
|
invalidate_bdev(bdev);
|
||||||
set_capacity(lo->lo_disk, 0);
|
set_capacity(lo->lo_disk, 0);
|
||||||
|
if (bdev)
|
||||||
bd_set_size(bdev, 0);
|
bd_set_size(bdev, 0);
|
||||||
mapping_set_gfp_mask(filp->f_mapping, gfp);
|
mapping_set_gfp_mask(filp->f_mapping, gfp);
|
||||||
lo->lo_state = Lo_unbound;
|
lo->lo_state = Lo_unbound;
|
||||||
|
@ -1137,22 +1139,22 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lo_ioctl(struct inode * inode, struct file * file,
|
static int lo_ioctl(struct block_device *bdev, fmode_t mode,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
|
struct loop_device *lo = bdev->bd_disk->private_data;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mutex_lock(&lo->lo_ctl_mutex);
|
mutex_lock(&lo->lo_ctl_mutex);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case LOOP_SET_FD:
|
case LOOP_SET_FD:
|
||||||
err = loop_set_fd(lo, file, inode->i_bdev, arg);
|
err = loop_set_fd(lo, mode, bdev, arg);
|
||||||
break;
|
break;
|
||||||
case LOOP_CHANGE_FD:
|
case LOOP_CHANGE_FD:
|
||||||
err = loop_change_fd(lo, file, inode->i_bdev, arg);
|
err = loop_change_fd(lo, bdev, arg);
|
||||||
break;
|
break;
|
||||||
case LOOP_CLR_FD:
|
case LOOP_CLR_FD:
|
||||||
err = loop_clr_fd(lo, inode->i_bdev);
|
err = loop_clr_fd(lo, bdev);
|
||||||
break;
|
break;
|
||||||
case LOOP_SET_STATUS:
|
case LOOP_SET_STATUS:
|
||||||
err = loop_set_status_old(lo, (struct loop_info __user *) arg);
|
err = loop_set_status_old(lo, (struct loop_info __user *) arg);
|
||||||
|
@ -1292,10 +1294,10 @@ loop_get_status_compat(struct loop_device *lo,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,
|
||||||
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct inode *inode = file->f_path.dentry->d_inode;
|
struct loop_device *lo = bdev->bd_disk->private_data;
|
||||||
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
@ -1317,7 +1319,7 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
|
||||||
arg = (unsigned long) compat_ptr(arg);
|
arg = (unsigned long) compat_ptr(arg);
|
||||||
case LOOP_SET_FD:
|
case LOOP_SET_FD:
|
||||||
case LOOP_CHANGE_FD:
|
case LOOP_CHANGE_FD:
|
||||||
err = lo_ioctl(inode, file, cmd, arg);
|
err = lo_ioctl(bdev, mode, cmd, arg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = -ENOIOCTLCMD;
|
err = -ENOIOCTLCMD;
|
||||||
|
@ -1327,9 +1329,9 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int lo_open(struct inode *inode, struct file *file)
|
static int lo_open(struct block_device *bdev, fmode_t mode)
|
||||||
{
|
{
|
||||||
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
|
struct loop_device *lo = bdev->bd_disk->private_data;
|
||||||
|
|
||||||
mutex_lock(&lo->lo_ctl_mutex);
|
mutex_lock(&lo->lo_ctl_mutex);
|
||||||
lo->lo_refcnt++;
|
lo->lo_refcnt++;
|
||||||
|
@ -1338,15 +1340,15 @@ static int lo_open(struct inode *inode, struct file *file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lo_release(struct inode *inode, struct file *file)
|
static int lo_release(struct gendisk *disk, fmode_t mode)
|
||||||
{
|
{
|
||||||
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
|
struct loop_device *lo = disk->private_data;
|
||||||
|
|
||||||
mutex_lock(&lo->lo_ctl_mutex);
|
mutex_lock(&lo->lo_ctl_mutex);
|
||||||
--lo->lo_refcnt;
|
--lo->lo_refcnt;
|
||||||
|
|
||||||
if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt)
|
if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt)
|
||||||
loop_clr_fd(lo, inode->i_bdev);
|
loop_clr_fd(lo, NULL);
|
||||||
|
|
||||||
mutex_unlock(&lo->lo_ctl_mutex);
|
mutex_unlock(&lo->lo_ctl_mutex);
|
||||||
|
|
||||||
|
@ -1355,11 +1357,11 @@ static int lo_release(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
static struct block_device_operations lo_fops = {
|
static struct block_device_operations lo_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.__open = lo_open,
|
.open = lo_open,
|
||||||
.__release = lo_release,
|
.release = lo_release,
|
||||||
.__ioctl = lo_ioctl,
|
.ioctl = lo_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.__compat_ioctl = lo_compat_ioctl,
|
.compat_ioctl = lo_compat_ioctl,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue