Skip to content

Commit 9b1bb01

Browse files
author
Miklos Szeredi
committed
f2fs: convert to fileattr
Use the fileattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 4db5c2e commit 9b1bb01

3 files changed

Lines changed: 43 additions & 178 deletions

File tree

fs/f2fs/f2fs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,6 +3194,9 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
31943194
int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
31953195
void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
31963196
int f2fs_precache_extents(struct inode *inode);
3197+
int f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
3198+
int f2fs_fileattr_set(struct user_namespace *mnt_userns,
3199+
struct dentry *dentry, struct fileattr *fa);
31973200
long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
31983201
long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
31993202
int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid);

fs/f2fs/file.c

Lines changed: 38 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/file.h>
2323
#include <linux/nls.h>
2424
#include <linux/sched/signal.h>
25+
#include <linux/fileattr.h>
2526

2627
#include "f2fs.h"
2728
#include "node.h"
@@ -990,6 +991,8 @@ const struct inode_operations f2fs_file_inode_operations = {
990991
.set_acl = f2fs_set_acl,
991992
.listxattr = f2fs_listxattr,
992993
.fiemap = f2fs_fiemap,
994+
.fileattr_get = f2fs_fileattr_get,
995+
.fileattr_set = f2fs_fileattr_set,
993996
};
994997

995998
static int fill_zero(struct inode *inode, pgoff_t index,
@@ -1871,13 +1874,16 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
18711874
return 0;
18721875
}
18731876

1874-
/* FS_IOC_GETFLAGS and FS_IOC_SETFLAGS support */
1877+
/* FS_IOC_[GS]ETFLAGS and FS_IOC_FS[GS]ETXATTR support */
18751878

18761879
/*
18771880
* To make a new on-disk f2fs i_flag gettable via FS_IOC_GETFLAGS, add an entry
18781881
* for it to f2fs_fsflags_map[], and add its FS_*_FL equivalent to
18791882
* F2FS_GETTABLE_FS_FL. To also make it settable via FS_IOC_SETFLAGS, also add
18801883
* its FS_*_FL equivalent to F2FS_SETTABLE_FS_FL.
1884+
*
1885+
* Translating flags to fsx_flags value used by FS_IOC_FSGETXATTR and
1886+
* FS_IOC_FSSETXATTR is done by the VFS.
18811887
*/
18821888

18831889
static const struct {
@@ -1952,67 +1958,6 @@ static inline u32 f2fs_fsflags_to_iflags(u32 fsflags)
19521958
return iflags;
19531959
}
19541960

1955-
static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
1956-
{
1957-
struct inode *inode = file_inode(filp);
1958-
struct f2fs_inode_info *fi = F2FS_I(inode);
1959-
u32 fsflags = f2fs_iflags_to_fsflags(fi->i_flags);
1960-
1961-
if (IS_ENCRYPTED(inode))
1962-
fsflags |= FS_ENCRYPT_FL;
1963-
if (IS_VERITY(inode))
1964-
fsflags |= FS_VERITY_FL;
1965-
if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
1966-
fsflags |= FS_INLINE_DATA_FL;
1967-
if (is_inode_flag_set(inode, FI_PIN_FILE))
1968-
fsflags |= FS_NOCOW_FL;
1969-
1970-
fsflags &= F2FS_GETTABLE_FS_FL;
1971-
1972-
return put_user(fsflags, (int __user *)arg);
1973-
}
1974-
1975-
static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
1976-
{
1977-
struct inode *inode = file_inode(filp);
1978-
struct f2fs_inode_info *fi = F2FS_I(inode);
1979-
u32 fsflags, old_fsflags;
1980-
u32 iflags;
1981-
int ret;
1982-
1983-
if (!inode_owner_or_capable(&init_user_ns, inode))
1984-
return -EACCES;
1985-
1986-
if (get_user(fsflags, (int __user *)arg))
1987-
return -EFAULT;
1988-
1989-
if (fsflags & ~F2FS_GETTABLE_FS_FL)
1990-
return -EOPNOTSUPP;
1991-
fsflags &= F2FS_SETTABLE_FS_FL;
1992-
1993-
iflags = f2fs_fsflags_to_iflags(fsflags);
1994-
if (f2fs_mask_flags(inode->i_mode, iflags) != iflags)
1995-
return -EOPNOTSUPP;
1996-
1997-
ret = mnt_want_write_file(filp);
1998-
if (ret)
1999-
return ret;
2000-
2001-
inode_lock(inode);
2002-
2003-
old_fsflags = f2fs_iflags_to_fsflags(fi->i_flags);
2004-
ret = vfs_ioc_setflags_prepare(inode, old_fsflags, fsflags);
2005-
if (ret)
2006-
goto out;
2007-
2008-
ret = f2fs_setflags_common(inode, iflags,
2009-
f2fs_fsflags_to_iflags(F2FS_SETTABLE_FS_FL));
2010-
out:
2011-
inode_unlock(inode);
2012-
mnt_drop_write_file(filp);
2013-
return ret;
2014-
}
2015-
20161961
static int f2fs_ioc_getversion(struct file *filp, unsigned long arg)
20171962
{
20181963
struct inode *inode = file_inode(filp);
@@ -3019,9 +2964,8 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
30192964
return err;
30202965
}
30212966

3022-
static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
2967+
static int f2fs_ioc_setproject(struct inode *inode, __u32 projid)
30232968
{
3024-
struct inode *inode = file_inode(filp);
30252969
struct f2fs_inode_info *fi = F2FS_I(inode);
30262970
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
30272971
struct page *ipage;
@@ -3082,131 +3026,63 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid)
30823026
return 0;
30833027
}
30843028

3085-
static int f2fs_ioc_setproject(struct file *filp, __u32 projid)
3029+
static int f2fs_ioc_setproject(struct inode *inode, __u32 projid)
30863030
{
30873031
if (projid != F2FS_DEF_PROJID)
30883032
return -EOPNOTSUPP;
30893033
return 0;
30903034
}
30913035
#endif
30923036

3093-
/* FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR support */
3094-
3095-
/*
3096-
* To make a new on-disk f2fs i_flag gettable via FS_IOC_FSGETXATTR and settable
3097-
* via FS_IOC_FSSETXATTR, add an entry for it to f2fs_xflags_map[], and add its
3098-
* FS_XFLAG_* equivalent to F2FS_SUPPORTED_XFLAGS.
3099-
*/
3100-
3101-
static const struct {
3102-
u32 iflag;
3103-
u32 xflag;
3104-
} f2fs_xflags_map[] = {
3105-
{ F2FS_SYNC_FL, FS_XFLAG_SYNC },
3106-
{ F2FS_IMMUTABLE_FL, FS_XFLAG_IMMUTABLE },
3107-
{ F2FS_APPEND_FL, FS_XFLAG_APPEND },
3108-
{ F2FS_NODUMP_FL, FS_XFLAG_NODUMP },
3109-
{ F2FS_NOATIME_FL, FS_XFLAG_NOATIME },
3110-
{ F2FS_PROJINHERIT_FL, FS_XFLAG_PROJINHERIT },
3111-
};
3112-
3113-
#define F2FS_SUPPORTED_XFLAGS ( \
3114-
FS_XFLAG_SYNC | \
3115-
FS_XFLAG_IMMUTABLE | \
3116-
FS_XFLAG_APPEND | \
3117-
FS_XFLAG_NODUMP | \
3118-
FS_XFLAG_NOATIME | \
3119-
FS_XFLAG_PROJINHERIT)
3120-
3121-
/* Convert f2fs on-disk i_flags to FS_IOC_FS{GET,SET}XATTR flags */
3122-
static inline u32 f2fs_iflags_to_xflags(u32 iflags)
3123-
{
3124-
u32 xflags = 0;
3125-
int i;
3126-
3127-
for (i = 0; i < ARRAY_SIZE(f2fs_xflags_map); i++)
3128-
if (iflags & f2fs_xflags_map[i].iflag)
3129-
xflags |= f2fs_xflags_map[i].xflag;
3130-
3131-
return xflags;
3132-
}
3133-
3134-
/* Convert FS_IOC_FS{GET,SET}XATTR flags to f2fs on-disk i_flags */
3135-
static inline u32 f2fs_xflags_to_iflags(u32 xflags)
3136-
{
3137-
u32 iflags = 0;
3138-
int i;
3139-
3140-
for (i = 0; i < ARRAY_SIZE(f2fs_xflags_map); i++)
3141-
if (xflags & f2fs_xflags_map[i].xflag)
3142-
iflags |= f2fs_xflags_map[i].iflag;
3143-
3144-
return iflags;
3145-
}
3146-
3147-
static void f2fs_fill_fsxattr(struct inode *inode, struct fsxattr *fa)
3037+
int f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
31483038
{
3039+
struct inode *inode = d_inode(dentry);
31493040
struct f2fs_inode_info *fi = F2FS_I(inode);
3041+
u32 fsflags = f2fs_iflags_to_fsflags(fi->i_flags);
31503042

3151-
simple_fill_fsxattr(fa, f2fs_iflags_to_xflags(fi->i_flags));
3043+
if (IS_ENCRYPTED(inode))
3044+
fsflags |= FS_ENCRYPT_FL;
3045+
if (IS_VERITY(inode))
3046+
fsflags |= FS_VERITY_FL;
3047+
if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
3048+
fsflags |= FS_INLINE_DATA_FL;
3049+
if (is_inode_flag_set(inode, FI_PIN_FILE))
3050+
fsflags |= FS_NOCOW_FL;
3051+
3052+
fileattr_fill_flags(fa, fsflags & F2FS_GETTABLE_FS_FL);
31523053

31533054
if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)))
31543055
fa->fsx_projid = from_kprojid(&init_user_ns, fi->i_projid);
3155-
}
31563056

3157-
static int f2fs_ioc_fsgetxattr(struct file *filp, unsigned long arg)
3158-
{
3159-
struct inode *inode = file_inode(filp);
3160-
struct fsxattr fa;
3161-
3162-
f2fs_fill_fsxattr(inode, &fa);
3163-
3164-
if (copy_to_user((struct fsxattr __user *)arg, &fa, sizeof(fa)))
3165-
return -EFAULT;
31663057
return 0;
31673058
}
31683059

3169-
static int f2fs_ioc_fssetxattr(struct file *filp, unsigned long arg)
3060+
int f2fs_fileattr_set(struct user_namespace *mnt_userns,
3061+
struct dentry *dentry, struct fileattr *fa)
31703062
{
3171-
struct inode *inode = file_inode(filp);
3172-
struct fsxattr fa, old_fa;
3063+
struct inode *inode = d_inode(dentry);
3064+
u32 fsflags = fa->flags, mask = F2FS_SETTABLE_FS_FL;
31733065
u32 iflags;
31743066
int err;
31753067

3176-
if (copy_from_user(&fa, (struct fsxattr __user *)arg, sizeof(fa)))
3177-
return -EFAULT;
3178-
3179-
/* Make sure caller has proper permission */
3180-
if (!inode_owner_or_capable(&init_user_ns, inode))
3181-
return -EACCES;
3182-
3183-
if (fa.fsx_xflags & ~F2FS_SUPPORTED_XFLAGS)
3068+
if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
3069+
return -EIO;
3070+
if (!f2fs_is_checkpoint_ready(F2FS_I_SB(inode)))
3071+
return -ENOSPC;
3072+
if (fsflags & ~F2FS_GETTABLE_FS_FL)
31843073
return -EOPNOTSUPP;
3074+
fsflags &= F2FS_SETTABLE_FS_FL;
3075+
if (!fa->flags_valid)
3076+
mask &= FS_COMMON_FL;
31853077

3186-
iflags = f2fs_xflags_to_iflags(fa.fsx_xflags);
3078+
iflags = f2fs_fsflags_to_iflags(fsflags);
31873079
if (f2fs_mask_flags(inode->i_mode, iflags) != iflags)
31883080
return -EOPNOTSUPP;
31893081

3190-
err = mnt_want_write_file(filp);
3191-
if (err)
3192-
return err;
3193-
3194-
inode_lock(inode);
3195-
3196-
f2fs_fill_fsxattr(inode, &old_fa);
3197-
err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa);
3198-
if (err)
3199-
goto out;
3200-
3201-
err = f2fs_setflags_common(inode, iflags,
3202-
f2fs_xflags_to_iflags(F2FS_SUPPORTED_XFLAGS));
3203-
if (err)
3204-
goto out;
3082+
err = f2fs_setflags_common(inode, iflags, f2fs_fsflags_to_iflags(mask));
3083+
if (!err)
3084+
err = f2fs_ioc_setproject(inode, fa->fsx_projid);
32053085

3206-
err = f2fs_ioc_setproject(filp, fa.fsx_projid);
3207-
out:
3208-
inode_unlock(inode);
3209-
mnt_drop_write_file(filp);
32103086
return err;
32113087
}
32123088

@@ -4233,10 +4109,6 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
42334109
static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
42344110
{
42354111
switch (cmd) {
4236-
case FS_IOC_GETFLAGS:
4237-
return f2fs_ioc_getflags(filp, arg);
4238-
case FS_IOC_SETFLAGS:
4239-
return f2fs_ioc_setflags(filp, arg);
42404112
case FS_IOC_GETVERSION:
42414113
return f2fs_ioc_getversion(filp, arg);
42424114
case F2FS_IOC_START_ATOMIC_WRITE:
@@ -4285,10 +4157,6 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
42854157
return f2fs_ioc_flush_device(filp, arg);
42864158
case F2FS_IOC_GET_FEATURES:
42874159
return f2fs_ioc_get_features(filp, arg);
4288-
case FS_IOC_FSGETXATTR:
4289-
return f2fs_ioc_fsgetxattr(filp, arg);
4290-
case FS_IOC_FSSETXATTR:
4291-
return f2fs_ioc_fssetxattr(filp, arg);
42924160
case F2FS_IOC_GET_PIN_FILE:
42934161
return f2fs_ioc_get_pin_file(filp, arg);
42944162
case F2FS_IOC_SET_PIN_FILE:
@@ -4518,12 +4386,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
45184386
return -ENOSPC;
45194387

45204388
switch (cmd) {
4521-
case FS_IOC32_GETFLAGS:
4522-
cmd = FS_IOC_GETFLAGS;
4523-
break;
4524-
case FS_IOC32_SETFLAGS:
4525-
cmd = FS_IOC_SETFLAGS;
4526-
break;
45274389
case FS_IOC32_GETVERSION:
45284390
cmd = FS_IOC_GETVERSION;
45294391
break;
@@ -4552,8 +4414,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
45524414
case F2FS_IOC_DEFRAGMENT:
45534415
case F2FS_IOC_FLUSH_DEVICE:
45544416
case F2FS_IOC_GET_FEATURES:
4555-
case FS_IOC_FSGETXATTR:
4556-
case FS_IOC_FSSETXATTR:
45574417
case F2FS_IOC_GET_PIN_FILE:
45584418
case F2FS_IOC_SET_PIN_FILE:
45594419
case F2FS_IOC_PRECACHE_EXTENTS:

fs/f2fs/namei.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,8 @@ const struct inode_operations f2fs_dir_inode_operations = {
13271327
.set_acl = f2fs_set_acl,
13281328
.listxattr = f2fs_listxattr,
13291329
.fiemap = f2fs_fiemap,
1330+
.fileattr_get = f2fs_fileattr_get,
1331+
.fileattr_set = f2fs_fileattr_set,
13301332
};
13311333

13321334
const struct inode_operations f2fs_symlink_inode_operations = {

0 commit comments

Comments
 (0)