Message ID | 20220713145234.2356641-1-tytso@mit.edu (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mm/shmem: add support for FS_IOC_[SG]ETFLAGS for tmpfs | expand |
On Wed, 13 Jul 2022 10:52:34 -0400 "Theodore Ts'o" <tytso@mit.edu> wrote: > This allows userspace to set flags like FS_APPEND_FL, FS_IMMUTABLE_FL, > FS_NODUMP_FL, etc., like all other standard Linux file systems. > > ... > > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -28,6 +28,7 @@ > #include <linux/ramfs.h> > #include <linux/pagemap.h> > #include <linux/file.h> > +#include <linux/fileattr.h> > #include <linux/mm.h> > #include <linux/random.h> > #include <linux/sched/signal.h> > @@ -1058,6 +1059,15 @@ static int shmem_getattr(struct user_namespace *mnt_userns, > shmem_recalc_inode(inode); > spin_unlock_irq(&info->lock); > } > + if (info->fsflags & EXT2_APPEND_FL) > + stat->attributes |= STATX_ATTR_APPEND; > + if (info->fsflags & EXT2_IMMUTABLE_FL) > + stat->attributes |= STATX_ATTR_IMMUTABLE; > + if (info->fsflags & EXT2_NODUMP_FL) > + stat->attributes |= STATX_ATTR_NODUMP; > + stat->attributes_mask |= (STATX_ATTR_APPEND | > + STATX_ATTR_IMMUTABLE | > + STATX_ATTR_NODUMP); > generic_fillattr(&init_user_ns, inode, stat); > > if (shmem_is_huge(NULL, inode, 0)) hm, how did you even test this? mm/shmem.c: In function 'shmem_getattr': mm/shmem.c:1062:29: error: 'EXT2_APPEND_FL' undeclared (first use in this function); did you mean 'FS_APPEND_FL'? 1062 | if (info->fsflags & EXT2_APPEND_FL) | ^~~~~~~~~~~~~~ | FS_APPEND_FL this --- a/mm/shmem.c~mm-shmem-add-support-for-fs_ioc_etflags-for-tmpfs-fix-2 +++ a/mm/shmem.c @@ -40,6 +40,8 @@ #include <linux/swapfile.h> #include "swap.h" +#include <../fs/ext2/ext2.h> + static struct vfsmount *shm_mnt; #ifdef CONFIG_SHMEM seems quite wrong.
On Wed, Jul 13, 2022 at 12:11:22PM -0700, Andrew Morton wrote: > > hm, how did you even test this? Sorry, I dropped the -a from "git commit --amend -a". A corrected version is coming up... - Ted
Hi Theodore, I love your patch! Yet something to improve: [auto build test ERROR on akpm-mm/mm-everything] url: https://github.com/intel-lab-lkp/linux/commits/Theodore-Ts-o/mm-shmem-add-support-for-FS_IOC_-SG-ETFLAGS-for-tmpfs/20220713-225257 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything config: hexagon-randconfig-r024-20220714 (https://download.01.org/0day-ci/archive/20220715/202207150617.dHbSxB55-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 5e61b9c556267086ef9b743a0b57df302eef831b) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/2a3164ac6dafb6c7a3cd8a1002e89370eec359c1 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Theodore-Ts-o/mm-shmem-add-support-for-FS_IOC_-SG-ETFLAGS-for-tmpfs/20220713-225257 git checkout 2a3164ac6dafb6c7a3cd8a1002e89370eec359c1 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): >> mm/shmem.c:1062:22: error: use of undeclared identifier 'EXT2_APPEND_FL' if (info->fsflags & EXT2_APPEND_FL) ^ >> mm/shmem.c:1064:22: error: use of undeclared identifier 'EXT2_IMMUTABLE_FL' if (info->fsflags & EXT2_IMMUTABLE_FL) ^ >> mm/shmem.c:1066:22: error: use of undeclared identifier 'EXT2_NODUMP_FL' if (info->fsflags & EXT2_NODUMP_FL) ^ >> mm/shmem.c:2840:5: warning: no previous prototype for function 'shmem_fileattr_get' [-Wmissing-prototypes] int shmem_fileattr_get(struct dentry *dentry, struct fileattr *fa) ^ mm/shmem.c:2840:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int shmem_fileattr_get(struct dentry *dentry, struct fileattr *fa) ^ static >> mm/shmem.c:2851:5: warning: no previous prototype for function 'shmem_fileattr_set' [-Wmissing-prototypes] int shmem_fileattr_set(struct user_namespace *mnt_userns, ^ mm/shmem.c:2851:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int shmem_fileattr_set(struct user_namespace *mnt_userns, ^ static 2 warnings and 3 errors generated. vim +/EXT2_APPEND_FL +1062 mm/shmem.c 1049 1050 static int shmem_getattr(struct user_namespace *mnt_userns, 1051 const struct path *path, struct kstat *stat, 1052 u32 request_mask, unsigned int query_flags) 1053 { 1054 struct inode *inode = path->dentry->d_inode; 1055 struct shmem_inode_info *info = SHMEM_I(inode); 1056 1057 if (info->alloced - info->swapped != inode->i_mapping->nrpages) { 1058 spin_lock_irq(&info->lock); 1059 shmem_recalc_inode(inode); 1060 spin_unlock_irq(&info->lock); 1061 } > 1062 if (info->fsflags & EXT2_APPEND_FL) 1063 stat->attributes |= STATX_ATTR_APPEND; > 1064 if (info->fsflags & EXT2_IMMUTABLE_FL) 1065 stat->attributes |= STATX_ATTR_IMMUTABLE; > 1066 if (info->fsflags & EXT2_NODUMP_FL) 1067 stat->attributes |= STATX_ATTR_NODUMP; 1068 stat->attributes_mask |= (STATX_ATTR_APPEND | 1069 STATX_ATTR_IMMUTABLE | 1070 STATX_ATTR_NODUMP); 1071 generic_fillattr(&init_user_ns, inode, stat); 1072 1073 if (shmem_is_huge(NULL, inode, 0)) 1074 stat->blksize = HPAGE_PMD_SIZE; 1075 1076 if (request_mask & STATX_BTIME) { 1077 stat->result_mask |= STATX_BTIME; 1078 stat->btime.tv_sec = info->i_crtime.tv_sec; 1079 stat->btime.tv_nsec = info->i_crtime.tv_nsec; 1080 } 1081 1082 return 0; 1083 } 1084
Hi Theodore, I love your patch! Yet something to improve: [auto build test ERROR on akpm-mm/mm-everything] url: https://github.com/intel-lab-lkp/linux/commits/Theodore-Ts-o/mm-shmem-add-support-for-FS_IOC_-SG-ETFLAGS-for-tmpfs/20220713-225257 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20220715/202207150754.j4ldkYik-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/2a3164ac6dafb6c7a3cd8a1002e89370eec359c1 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Theodore-Ts-o/mm-shmem-add-support-for-FS_IOC_-SG-ETFLAGS-for-tmpfs/20220713-225257 git checkout 2a3164ac6dafb6c7a3cd8a1002e89370eec359c1 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=um SUBARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): mm/shmem.c: In function 'shmem_getattr': >> mm/shmem.c:1062:29: error: 'EXT2_APPEND_FL' undeclared (first use in this function); did you mean 'FS_APPEND_FL'? 1062 | if (info->fsflags & EXT2_APPEND_FL) | ^~~~~~~~~~~~~~ | FS_APPEND_FL mm/shmem.c:1062:29: note: each undeclared identifier is reported only once for each function it appears in >> mm/shmem.c:1064:29: error: 'EXT2_IMMUTABLE_FL' undeclared (first use in this function); did you mean 'FS_IMMUTABLE_FL'? 1064 | if (info->fsflags & EXT2_IMMUTABLE_FL) | ^~~~~~~~~~~~~~~~~ | FS_IMMUTABLE_FL >> mm/shmem.c:1066:29: error: 'EXT2_NODUMP_FL' undeclared (first use in this function); did you mean 'FS_NODUMP_FL'? 1066 | if (info->fsflags & EXT2_NODUMP_FL) | ^~~~~~~~~~~~~~ | FS_NODUMP_FL mm/shmem.c: At top level: >> mm/shmem.c:2840:5: warning: no previous prototype for 'shmem_fileattr_get' [-Wmissing-prototypes] 2840 | int shmem_fileattr_get(struct dentry *dentry, struct fileattr *fa) | ^~~~~~~~~~~~~~~~~~ >> mm/shmem.c:2851:5: warning: no previous prototype for 'shmem_fileattr_set' [-Wmissing-prototypes] 2851 | int shmem_fileattr_set(struct user_namespace *mnt_userns, | ^~~~~~~~~~~~~~~~~~ vim +1062 mm/shmem.c 1049 1050 static int shmem_getattr(struct user_namespace *mnt_userns, 1051 const struct path *path, struct kstat *stat, 1052 u32 request_mask, unsigned int query_flags) 1053 { 1054 struct inode *inode = path->dentry->d_inode; 1055 struct shmem_inode_info *info = SHMEM_I(inode); 1056 1057 if (info->alloced - info->swapped != inode->i_mapping->nrpages) { 1058 spin_lock_irq(&info->lock); 1059 shmem_recalc_inode(inode); 1060 spin_unlock_irq(&info->lock); 1061 } > 1062 if (info->fsflags & EXT2_APPEND_FL) 1063 stat->attributes |= STATX_ATTR_APPEND; > 1064 if (info->fsflags & EXT2_IMMUTABLE_FL) 1065 stat->attributes |= STATX_ATTR_IMMUTABLE; > 1066 if (info->fsflags & EXT2_NODUMP_FL) 1067 stat->attributes |= STATX_ATTR_NODUMP; 1068 stat->attributes_mask |= (STATX_ATTR_APPEND | 1069 STATX_ATTR_IMMUTABLE | 1070 STATX_ATTR_NODUMP); 1071 generic_fillattr(&init_user_ns, inode, stat); 1072 1073 if (shmem_is_huge(NULL, inode, 0)) 1074 stat->blksize = HPAGE_PMD_SIZE; 1075 1076 if (request_mask & STATX_BTIME) { 1077 stat->result_mask |= STATX_BTIME; 1078 stat->btime.tv_sec = info->i_crtime.tv_sec; 1079 stat->btime.tv_nsec = info->i_crtime.tv_nsec; 1080 } 1081 1082 return 0; 1083 } 1084
On Fri, Jul 15, 2022 at 1:01 AM kernel test robot <lkp@intel.com> wrote: > > >> mm/shmem.c:1062:22: error: use of undeclared identifier 'EXT2_APPEND_FL' > if (info->fsflags & EXT2_APPEND_FL) > ^ > >> mm/shmem.c:1064:22: error: use of undeclared identifier 'EXT2_IMMUTABLE_FL' > if (info->fsflags & EXT2_IMMUTABLE_FL) > ^ > >> mm/shmem.c:1066:22: error: use of undeclared identifier 'EXT2_NODUMP_FL' > if (info->fsflags & EXT2_NODUMP_FL) > ^ I suppose this just needs to use FS_APPEND_FL/FS_IMMUTABLE_FL/FS_NODUMP_FL instead of the ext2 alias names? Arnd
On Fri, Jul 15, 2022 at 01:09:04PM +0200, Arnd Bergmann wrote: > On Fri, Jul 15, 2022 at 1:01 AM kernel test robot <lkp@intel.com> wrote: > > > > >> mm/shmem.c:1062:22: error: use of undeclared identifier 'EXT2_APPEND_FL' > > if (info->fsflags & EXT2_APPEND_FL) > > ^ > > >> mm/shmem.c:1064:22: error: use of undeclared identifier 'EXT2_IMMUTABLE_FL' > > if (info->fsflags & EXT2_IMMUTABLE_FL) > > ^ > > >> mm/shmem.c:1066:22: error: use of undeclared identifier 'EXT2_NODUMP_FL' > > if (info->fsflags & EXT2_NODUMP_FL) > > ^ > > I suppose this just needs to use FS_APPEND_FL/FS_IMMUTABLE_FL/FS_NODUMP_FL > instead of the ext2 alias names? The zero day bot was testing the v1 version of the patch. This was fixed in the -v2 and -v3 versions. - Ted
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index a68f982f22d1..1b6c4013f691 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -25,9 +25,20 @@ struct shmem_inode_info { struct simple_xattrs xattrs; /* list of xattrs */ atomic_t stop_eviction; /* hold when working on inode */ struct timespec64 i_crtime; /* file creation time */ + unsigned int fsflags; /* flags for FS_IOC_[SG]ETFLAGS */ struct inode vfs_inode; }; +#define SHMEM_FL_USER_VISIBLE FS_FL_USER_VISIBLE +#define SHMEM_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE +#define SHMEM_FL_INHERITED FS_FL_USER_MODIFIABLE + +/* Flags that are appropriate for regular files (all but dir-specific ones). */ +#define SHMEM_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) + +/* Flags that are appropriate for non-directories/regular files. */ +#define SHMEM_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) + struct shmem_sb_info { unsigned long max_blocks; /* How many blocks are allowed */ struct percpu_counter used_blocks; /* How many are allocated */ diff --git a/mm/shmem.c b/mm/shmem.c index a6f565308133..515a2708d658 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -28,6 +28,7 @@ #include <linux/ramfs.h> #include <linux/pagemap.h> #include <linux/file.h> +#include <linux/fileattr.h> #include <linux/mm.h> #include <linux/random.h> #include <linux/sched/signal.h> @@ -1058,6 +1059,15 @@ static int shmem_getattr(struct user_namespace *mnt_userns, shmem_recalc_inode(inode); spin_unlock_irq(&info->lock); } + if (info->fsflags & EXT2_APPEND_FL) + stat->attributes |= STATX_ATTR_APPEND; + if (info->fsflags & EXT2_IMMUTABLE_FL) + stat->attributes |= STATX_ATTR_IMMUTABLE; + if (info->fsflags & EXT2_NODUMP_FL) + stat->attributes |= STATX_ATTR_NODUMP; + stat->attributes_mask |= (STATX_ATTR_APPEND | + STATX_ATTR_IMMUTABLE | + STATX_ATTR_NODUMP); generic_fillattr(&init_user_ns, inode, stat); if (shmem_is_huge(NULL, inode, 0)) @@ -2272,7 +2282,18 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, +/* Mask out flags that are inappropriate for the given type of inode. */ +static unsigned shmem_mask_flags(umode_t mode, __u32 flags) +{ + if (S_ISDIR(mode)) + return flags; + else if (S_ISREG(mode)) + return flags & SHMEM_REG_FLMASK; + else + return flags & SHMEM_OTHER_FLMASK; +} + +static struct inode *shmem_get_inode(struct super_block *sb, struct inode *dir, umode_t mode, dev_t dev, unsigned long flags) { struct inode *inode; @@ -2297,6 +2318,9 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode info->seals = F_SEAL_SEAL; info->flags = flags & VM_NORESERVE; info->i_crtime = inode->i_mtime; + info->fsflags = (dir == NULL) ? 0 : + SHMEM_I(dir)->fsflags & SHMEM_FL_INHERITED; + info->fsflags = shmem_mask_flags(mode, info->fsflags); INIT_LIST_HEAD(&info->shrinklist); INIT_LIST_HEAD(&info->swaplist); simple_xattrs_init(&info->xattrs); @@ -2813,6 +2837,41 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, return error; } +int shmem_fileattr_get(struct dentry *dentry, struct fileattr *fa) +{ + struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); + + fileattr_fill_flags(fa, info->fsflags & SHMEM_FL_USER_VISIBLE); + + return 0; +} + + + +int shmem_fileattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct fileattr *fa) +{ + struct inode *inode = d_inode(dentry); + struct shmem_inode_info *info = SHMEM_I(inode); + + if (fileattr_has_fsx(fa)) + return -EOPNOTSUPP; + + info->fsflags = (fa->flags & ~SHMEM_FL_USER_MODIFIABLE) | + (fa->flags & SHMEM_FL_USER_MODIFIABLE); + + inode->i_flags &= ~(S_APPEND | S_IMMUTABLE | S_NOATIME); + if (info->fsflags & FS_APPEND_FL) + inode->i_flags |= S_APPEND; + if (info->fsflags & FS_IMMUTABLE_FL) + inode->i_flags |= S_IMMUTABLE; + if (info->fsflags & FS_NOATIME_FL) + inode->i_flags |= S_NOATIME; + + inode->i_ctime = current_time(inode); + return 0; +} + static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) { struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); @@ -3828,6 +3887,8 @@ static const struct inode_operations shmem_inode_operations = { #ifdef CONFIG_TMPFS_XATTR .listxattr = shmem_listxattr, .set_acl = simple_set_acl, + .fileattr_get = shmem_fileattr_get, + .fileattr_set = shmem_fileattr_set, #endif }; @@ -3847,6 +3908,8 @@ static const struct inode_operations shmem_dir_inode_operations = { #endif #ifdef CONFIG_TMPFS_XATTR .listxattr = shmem_listxattr, + .fileattr_get = shmem_fileattr_get, + .fileattr_set = shmem_fileattr_set, #endif #ifdef CONFIG_TMPFS_POSIX_ACL .setattr = shmem_setattr,
This allows userspace to set flags like FS_APPEND_FL, FS_IMMUTABLE_FL, FS_NODUMP_FL, etc., like all other standard Linux file systems. Signed-off-by: Theodore Ts'o <tytso@mit.edu> --- include/linux/shmem_fs.h | 11 +++++++ mm/shmem.c | 65 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-)