|
22 | 22 | #include <linux/file.h> |
23 | 23 | #include <linux/nls.h> |
24 | 24 | #include <linux/sched/signal.h> |
| 25 | +#include <linux/fileattr.h> |
25 | 26 |
|
26 | 27 | #include "f2fs.h" |
27 | 28 | #include "node.h" |
@@ -990,6 +991,8 @@ const struct inode_operations f2fs_file_inode_operations = { |
990 | 991 | .set_acl = f2fs_set_acl, |
991 | 992 | .listxattr = f2fs_listxattr, |
992 | 993 | .fiemap = f2fs_fiemap, |
| 994 | + .fileattr_get = f2fs_fileattr_get, |
| 995 | + .fileattr_set = f2fs_fileattr_set, |
993 | 996 | }; |
994 | 997 |
|
995 | 998 | 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) |
1871 | 1874 | return 0; |
1872 | 1875 | } |
1873 | 1876 |
|
1874 | | -/* FS_IOC_GETFLAGS and FS_IOC_SETFLAGS support */ |
| 1877 | +/* FS_IOC_[GS]ETFLAGS and FS_IOC_FS[GS]ETXATTR support */ |
1875 | 1878 |
|
1876 | 1879 | /* |
1877 | 1880 | * To make a new on-disk f2fs i_flag gettable via FS_IOC_GETFLAGS, add an entry |
1878 | 1881 | * for it to f2fs_fsflags_map[], and add its FS_*_FL equivalent to |
1879 | 1882 | * F2FS_GETTABLE_FS_FL. To also make it settable via FS_IOC_SETFLAGS, also add |
1880 | 1883 | * 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. |
1881 | 1887 | */ |
1882 | 1888 |
|
1883 | 1889 | static const struct { |
@@ -1952,67 +1958,6 @@ static inline u32 f2fs_fsflags_to_iflags(u32 fsflags) |
1952 | 1958 | return iflags; |
1953 | 1959 | } |
1954 | 1960 |
|
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 | | - |
2016 | 1961 | static int f2fs_ioc_getversion(struct file *filp, unsigned long arg) |
2017 | 1962 | { |
2018 | 1963 | struct inode *inode = file_inode(filp); |
@@ -3019,9 +2964,8 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid) |
3019 | 2964 | return err; |
3020 | 2965 | } |
3021 | 2966 |
|
3022 | | -static int f2fs_ioc_setproject(struct file *filp, __u32 projid) |
| 2967 | +static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) |
3023 | 2968 | { |
3024 | | - struct inode *inode = file_inode(filp); |
3025 | 2969 | struct f2fs_inode_info *fi = F2FS_I(inode); |
3026 | 2970 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
3027 | 2971 | struct page *ipage; |
@@ -3082,131 +3026,63 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid) |
3082 | 3026 | return 0; |
3083 | 3027 | } |
3084 | 3028 |
|
3085 | | -static int f2fs_ioc_setproject(struct file *filp, __u32 projid) |
| 3029 | +static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) |
3086 | 3030 | { |
3087 | 3031 | if (projid != F2FS_DEF_PROJID) |
3088 | 3032 | return -EOPNOTSUPP; |
3089 | 3033 | return 0; |
3090 | 3034 | } |
3091 | 3035 | #endif |
3092 | 3036 |
|
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) |
3148 | 3038 | { |
| 3039 | + struct inode *inode = d_inode(dentry); |
3149 | 3040 | struct f2fs_inode_info *fi = F2FS_I(inode); |
| 3041 | + u32 fsflags = f2fs_iflags_to_fsflags(fi->i_flags); |
3150 | 3042 |
|
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); |
3152 | 3053 |
|
3153 | 3054 | if (f2fs_sb_has_project_quota(F2FS_I_SB(inode))) |
3154 | 3055 | fa->fsx_projid = from_kprojid(&init_user_ns, fi->i_projid); |
3155 | | -} |
3156 | 3056 |
|
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; |
3166 | 3057 | return 0; |
3167 | 3058 | } |
3168 | 3059 |
|
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) |
3170 | 3062 | { |
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; |
3173 | 3065 | u32 iflags; |
3174 | 3066 | int err; |
3175 | 3067 |
|
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) |
3184 | 3073 | return -EOPNOTSUPP; |
| 3074 | + fsflags &= F2FS_SETTABLE_FS_FL; |
| 3075 | + if (!fa->flags_valid) |
| 3076 | + mask &= FS_COMMON_FL; |
3185 | 3077 |
|
3186 | | - iflags = f2fs_xflags_to_iflags(fa.fsx_xflags); |
| 3078 | + iflags = f2fs_fsflags_to_iflags(fsflags); |
3187 | 3079 | if (f2fs_mask_flags(inode->i_mode, iflags) != iflags) |
3188 | 3080 | return -EOPNOTSUPP; |
3189 | 3081 |
|
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); |
3205 | 3085 |
|
3206 | | - err = f2fs_ioc_setproject(filp, fa.fsx_projid); |
3207 | | -out: |
3208 | | - inode_unlock(inode); |
3209 | | - mnt_drop_write_file(filp); |
3210 | 3086 | return err; |
3211 | 3087 | } |
3212 | 3088 |
|
@@ -4233,10 +4109,6 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg) |
4233 | 4109 | static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
4234 | 4110 | { |
4235 | 4111 | 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); |
4240 | 4112 | case FS_IOC_GETVERSION: |
4241 | 4113 | return f2fs_ioc_getversion(filp, arg); |
4242 | 4114 | case F2FS_IOC_START_ATOMIC_WRITE: |
@@ -4285,10 +4157,6 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
4285 | 4157 | return f2fs_ioc_flush_device(filp, arg); |
4286 | 4158 | case F2FS_IOC_GET_FEATURES: |
4287 | 4159 | 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); |
4292 | 4160 | case F2FS_IOC_GET_PIN_FILE: |
4293 | 4161 | return f2fs_ioc_get_pin_file(filp, arg); |
4294 | 4162 | case F2FS_IOC_SET_PIN_FILE: |
@@ -4518,12 +4386,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
4518 | 4386 | return -ENOSPC; |
4519 | 4387 |
|
4520 | 4388 | 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; |
4527 | 4389 | case FS_IOC32_GETVERSION: |
4528 | 4390 | cmd = FS_IOC_GETVERSION; |
4529 | 4391 | break; |
@@ -4552,8 +4414,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
4552 | 4414 | case F2FS_IOC_DEFRAGMENT: |
4553 | 4415 | case F2FS_IOC_FLUSH_DEVICE: |
4554 | 4416 | case F2FS_IOC_GET_FEATURES: |
4555 | | - case FS_IOC_FSGETXATTR: |
4556 | | - case FS_IOC_FSSETXATTR: |
4557 | 4417 | case F2FS_IOC_GET_PIN_FILE: |
4558 | 4418 | case F2FS_IOC_SET_PIN_FILE: |
4559 | 4419 | case F2FS_IOC_PRECACHE_EXTENTS: |
|
0 commit comments