f2fs: use mnt_{want,drop}_write_file in ioctl
In interfaces of ioctl, mnt_{want,drop}_write_file should be used for: - get exclusion against file system freezing which may used by lvm snapshot. - do telling filesystem that a write is about to be performed on it, and make sure that the writes are permitted. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
0080c50764
commit
7fb17fe44b
121
fs/f2fs/file.c
121
fs/f2fs/file.c
|
@ -1307,20 +1307,16 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
|
|||
unsigned int oldflags;
|
||||
int ret;
|
||||
|
||||
if (!inode_owner_or_capable(inode))
|
||||
return -EACCES;
|
||||
|
||||
if (get_user(flags, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!inode_owner_or_capable(inode)) {
|
||||
ret = -EACCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (get_user(flags, (int __user *)arg)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
flags = f2fs_mask_flags(inode->i_mode, flags);
|
||||
|
||||
inode_lock(inode);
|
||||
|
@ -1363,18 +1359,22 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
|
|||
if (!inode_owner_or_capable(inode))
|
||||
return -EACCES;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (f2fs_is_atomic_file(inode))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
ret = f2fs_convert_inline_inode(inode);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
|
||||
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
|
||||
|
||||
if (!get_dirty_pages(inode))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
|
||||
"Unexpected flush for atomic writes: ino=%lu, npages=%u",
|
||||
|
@ -1382,6 +1382,8 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
|
|||
ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
|
||||
if (ret)
|
||||
clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
|
||||
out:
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1393,13 +1395,13 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
|
|||
if (!inode_owner_or_capable(inode))
|
||||
return -EACCES;
|
||||
|
||||
if (f2fs_is_volatile_file(inode))
|
||||
return 0;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (f2fs_is_volatile_file(inode))
|
||||
goto err_out;
|
||||
|
||||
if (f2fs_is_atomic_file(inode)) {
|
||||
clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
|
||||
ret = commit_inmem_pages(inode);
|
||||
|
@ -1423,32 +1425,48 @@ static int f2fs_ioc_start_volatile_write(struct file *filp)
|
|||
if (!inode_owner_or_capable(inode))
|
||||
return -EACCES;
|
||||
|
||||
if (f2fs_is_volatile_file(inode))
|
||||
return 0;
|
||||
|
||||
ret = f2fs_convert_inline_inode(inode);
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (f2fs_is_volatile_file(inode))
|
||||
goto out;
|
||||
|
||||
ret = f2fs_convert_inline_inode(inode);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE);
|
||||
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
|
||||
return 0;
|
||||
out:
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int f2fs_ioc_release_volatile_write(struct file *filp)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
int ret;
|
||||
|
||||
if (!inode_owner_or_capable(inode))
|
||||
return -EACCES;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!f2fs_is_volatile_file(inode))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
if (!f2fs_is_first_block_written(inode))
|
||||
return truncate_partial_data_page(inode, 0, true);
|
||||
if (!f2fs_is_first_block_written(inode)) {
|
||||
ret = truncate_partial_data_page(inode, 0, true);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return punch_hole(inode, 0, F2FS_BLKSIZE);
|
||||
ret = punch_hole(inode, 0, F2FS_BLKSIZE);
|
||||
out:
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int f2fs_ioc_abort_volatile_write(struct file *filp)
|
||||
|
@ -1481,6 +1499,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct super_block *sb = sbi->sb;
|
||||
__u32 in;
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
@ -1488,6 +1507,10 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||
if (get_user(in, (__u32 __user *)arg))
|
||||
return -EFAULT;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (in) {
|
||||
case F2FS_GOING_DOWN_FULLSYNC:
|
||||
sb = freeze_bdev(sb->s_bdev);
|
||||
|
@ -1509,10 +1532,13 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||
f2fs_stop_checkpoint(sbi);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
return 0;
|
||||
out:
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
|
||||
|
@ -1533,9 +1559,14 @@ static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
|
|||
sizeof(range)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
range.minlen = max((unsigned int)range.minlen,
|
||||
q->limits.discard_granularity);
|
||||
ret = f2fs_trim_fs(F2FS_SB(sb), &range);
|
||||
mnt_drop_write_file(filp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1560,13 +1591,21 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
|
|||
{
|
||||
struct fscrypt_policy policy;
|
||||
struct inode *inode = file_inode(filp);
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&policy, (struct fscrypt_policy __user *)arg,
|
||||
sizeof(policy)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
|
||||
return fscrypt_process_policy(inode, &policy);
|
||||
ret = fscrypt_process_policy(inode, &policy);
|
||||
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
|
||||
|
@ -1623,6 +1662,7 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg)
|
|||
struct inode *inode = file_inode(filp);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
__u32 sync;
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
@ -1633,20 +1673,30 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg)
|
|||
if (f2fs_readonly(sbi->sb))
|
||||
return -EROFS;
|
||||
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!sync) {
|
||||
if (!mutex_trylock(&sbi->gc_mutex))
|
||||
return -EBUSY;
|
||||
if (!mutex_trylock(&sbi->gc_mutex)) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&sbi->gc_mutex);
|
||||
}
|
||||
|
||||
return f2fs_gc(sbi, sync);
|
||||
ret = f2fs_gc(sbi, sync);
|
||||
out:
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
@ -1654,7 +1704,14 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
|
|||
if (f2fs_readonly(sbi->sb))
|
||||
return -EROFS;
|
||||
|
||||
return f2fs_sync_fs(sbi->sb, 1);
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = f2fs_sync_fs(sbi->sb, 1);
|
||||
|
||||
mnt_drop_write_file(filp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
|
||||
|
|
Loading…
Reference in New Issue