mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	fs: introduce file_getattr and file_setattr syscalls
Introduce file_getattr() and file_setattr() syscalls to manipulate inode extended attributes. The syscalls takes pair of file descriptor and pathname. Then it operates on inode opened accroding to openat() semantics. The struct file_attr is passed to obtain/change extended attributes. This is an alternative to FS_IOC_FSSETXATTR ioctl with a difference that file don't need to be open as we can reference it with a path instead of fd. By having this we can manipulated inode extended attributes not only on regular files but also on special ones. This is not possible with FS_IOC_FSSETXATTR ioctl as with special files we can not call ioctl() directly on the filesystem inode using fd. This patch adds two new syscalls which allows userspace to get/set extended inode attributes on special files by using parent directory and a path - *at() like syscall. CC: linux-api@vger.kernel.org CC: linux-fsdevel@vger.kernel.org CC: linux-xfs@vger.kernel.org Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org> Link: https://lore.kernel.org/20250630-xattrat-syscall-v6-6-c4e3bc35227b@kernel.org Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
		
							parent
							
								
									276e136bff
								
							
						
					
					
						commit
						be7efb2d20
					
				
					 21 changed files with 218 additions and 1 deletions
				
			
		| 
						 | 
					@ -507,3 +507,5 @@
 | 
				
			||||||
575	common	listxattrat			sys_listxattrat
 | 
					575	common	listxattrat			sys_listxattrat
 | 
				
			||||||
576	common	removexattrat			sys_removexattrat
 | 
					576	common	removexattrat			sys_removexattrat
 | 
				
			||||||
577	common	open_tree_attr			sys_open_tree_attr
 | 
					577	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					578	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					579	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,3 +482,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -479,3 +479,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -467,3 +467,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,3 +473,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -406,3 +406,5 @@
 | 
				
			||||||
465	n32	listxattrat			sys_listxattrat
 | 
					465	n32	listxattrat			sys_listxattrat
 | 
				
			||||||
466	n32	removexattrat			sys_removexattrat
 | 
					466	n32	removexattrat			sys_removexattrat
 | 
				
			||||||
467	n32	open_tree_attr			sys_open_tree_attr
 | 
					467	n32	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	n32	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	n32	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -382,3 +382,5 @@
 | 
				
			||||||
465	n64	listxattrat			sys_listxattrat
 | 
					465	n64	listxattrat			sys_listxattrat
 | 
				
			||||||
466	n64	removexattrat			sys_removexattrat
 | 
					466	n64	removexattrat			sys_removexattrat
 | 
				
			||||||
467	n64	open_tree_attr			sys_open_tree_attr
 | 
					467	n64	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	n64	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	n64	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,3 +455,5 @@
 | 
				
			||||||
465	o32	listxattrat			sys_listxattrat
 | 
					465	o32	listxattrat			sys_listxattrat
 | 
				
			||||||
466	o32	removexattrat			sys_removexattrat
 | 
					466	o32	removexattrat			sys_removexattrat
 | 
				
			||||||
467	o32	open_tree_attr			sys_open_tree_attr
 | 
					467	o32	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	o32	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	o32	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -466,3 +466,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -558,3 +558,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -470,3 +470,5 @@
 | 
				
			||||||
465  common	listxattrat		sys_listxattrat			sys_listxattrat
 | 
					465  common	listxattrat		sys_listxattrat			sys_listxattrat
 | 
				
			||||||
466  common	removexattrat		sys_removexattrat		sys_removexattrat
 | 
					466  common	removexattrat		sys_removexattrat		sys_removexattrat
 | 
				
			||||||
467  common	open_tree_attr		sys_open_tree_attr		sys_open_tree_attr
 | 
					467  common	open_tree_attr		sys_open_tree_attr		sys_open_tree_attr
 | 
				
			||||||
 | 
					468  common	file_getattr		sys_file_getattr		sys_file_getattr
 | 
				
			||||||
 | 
					469  common	file_setattr		sys_file_setattr		sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -471,3 +471,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -513,3 +513,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,3 +473,5 @@
 | 
				
			||||||
465	i386	listxattrat		sys_listxattrat
 | 
					465	i386	listxattrat		sys_listxattrat
 | 
				
			||||||
466	i386	removexattrat		sys_removexattrat
 | 
					466	i386	removexattrat		sys_removexattrat
 | 
				
			||||||
467	i386	open_tree_attr		sys_open_tree_attr
 | 
					467	i386	open_tree_attr		sys_open_tree_attr
 | 
				
			||||||
 | 
					468	i386	file_getattr		sys_file_getattr
 | 
				
			||||||
 | 
					469	i386	file_setattr		sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -391,6 +391,8 @@
 | 
				
			||||||
465	common	listxattrat		sys_listxattrat
 | 
					465	common	listxattrat		sys_listxattrat
 | 
				
			||||||
466	common	removexattrat		sys_removexattrat
 | 
					466	common	removexattrat		sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr		sys_open_tree_attr
 | 
					467	common	open_tree_attr		sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr		sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr		sys_file_setattr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Due to a historical design error, certain syscalls are numbered differently
 | 
					# Due to a historical design error, certain syscalls are numbered differently
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -438,3 +438,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										152
									
								
								fs/file_attr.c
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								fs/file_attr.c
									
									
									
									
									
								
							| 
						 | 
					@ -4,6 +4,10 @@
 | 
				
			||||||
#include <linux/fscrypt.h>
 | 
					#include <linux/fscrypt.h>
 | 
				
			||||||
#include <linux/fileattr.h>
 | 
					#include <linux/fileattr.h>
 | 
				
			||||||
#include <linux/export.h>
 | 
					#include <linux/export.h>
 | 
				
			||||||
 | 
					#include <linux/syscalls.h>
 | 
				
			||||||
 | 
					#include <linux/namei.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * fileattr_fill_xflags - initialize fileattr with xflags
 | 
					 * fileattr_fill_xflags - initialize fileattr with xflags
 | 
				
			||||||
| 
						 | 
					@ -90,6 +94,19 @@ int vfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(vfs_fileattr_get);
 | 
					EXPORT_SYMBOL(vfs_fileattr_get);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void fileattr_to_file_attr(const struct fileattr *fa,
 | 
				
			||||||
 | 
									  struct file_attr *fattr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__u32 mask = FS_XFLAGS_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(fattr, 0, sizeof(struct file_attr));
 | 
				
			||||||
 | 
						fattr->fa_xflags = fa->fsx_xflags & mask;
 | 
				
			||||||
 | 
						fattr->fa_extsize = fa->fsx_extsize;
 | 
				
			||||||
 | 
						fattr->fa_nextents = fa->fsx_nextents;
 | 
				
			||||||
 | 
						fattr->fa_projid = fa->fsx_projid;
 | 
				
			||||||
 | 
						fattr->fa_cowextsize = fa->fsx_cowextsize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * copy_fsxattr_to_user - copy fsxattr to userspace.
 | 
					 * copy_fsxattr_to_user - copy fsxattr to userspace.
 | 
				
			||||||
 * @fa:		fileattr pointer
 | 
					 * @fa:		fileattr pointer
 | 
				
			||||||
| 
						 | 
					@ -116,6 +133,23 @@ int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(copy_fsxattr_to_user);
 | 
					EXPORT_SYMBOL(copy_fsxattr_to_user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int file_attr_to_fileattr(const struct file_attr *fattr,
 | 
				
			||||||
 | 
									 struct fileattr *fa)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__u32 mask = FS_XFLAGS_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fattr->fa_xflags & ~mask)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fileattr_fill_xflags(fa, fattr->fa_xflags);
 | 
				
			||||||
 | 
						fa->fsx_xflags &= ~FS_XFLAG_RDONLY_MASK;
 | 
				
			||||||
 | 
						fa->fsx_extsize = fattr->fa_extsize;
 | 
				
			||||||
 | 
						fa->fsx_projid = fattr->fa_projid;
 | 
				
			||||||
 | 
						fa->fsx_cowextsize = fattr->fa_cowextsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int copy_fsxattr_from_user(struct fileattr *fa,
 | 
					static int copy_fsxattr_from_user(struct fileattr *fa,
 | 
				
			||||||
				  struct fsxattr __user *ufa)
 | 
									  struct fsxattr __user *ufa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -344,3 +378,121 @@ int ioctl_fssetxattr(struct file *file, void __user *argp)
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(ioctl_fssetxattr);
 | 
					EXPORT_SYMBOL(ioctl_fssetxattr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SYSCALL_DEFINE5(file_getattr, int, dfd, const char __user *, filename,
 | 
				
			||||||
 | 
							struct file_attr __user *, ufattr, size_t, usize,
 | 
				
			||||||
 | 
							unsigned int, at_flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct path filepath __free(path_put) = {};
 | 
				
			||||||
 | 
						struct filename *name __free(putname) = NULL;
 | 
				
			||||||
 | 
						unsigned int lookup_flags = 0;
 | 
				
			||||||
 | 
						struct file_attr fattr;
 | 
				
			||||||
 | 
						struct fileattr fa;
 | 
				
			||||||
 | 
						int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BUILD_BUG_ON(sizeof(struct file_attr) < FILE_ATTR_SIZE_VER0);
 | 
				
			||||||
 | 
						BUILD_BUG_ON(sizeof(struct file_attr) != FILE_ATTR_SIZE_LATEST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(at_flags & AT_SYMLINK_NOFOLLOW))
 | 
				
			||||||
 | 
							lookup_flags |= LOOKUP_FOLLOW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (usize > PAGE_SIZE)
 | 
				
			||||||
 | 
							return -E2BIG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (usize < FILE_ATTR_SIZE_VER0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name = getname_maybe_null(filename, at_flags);
 | 
				
			||||||
 | 
						if (IS_ERR(name))
 | 
				
			||||||
 | 
							return PTR_ERR(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!name && dfd >= 0) {
 | 
				
			||||||
 | 
							CLASS(fd, f)(dfd);
 | 
				
			||||||
 | 
							if (fd_empty(f))
 | 
				
			||||||
 | 
								return -EBADF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							filepath = fd_file(f)->f_path;
 | 
				
			||||||
 | 
							path_get(&filepath);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							error = filename_lookup(dfd, name, lookup_flags, &filepath,
 | 
				
			||||||
 | 
										NULL);
 | 
				
			||||||
 | 
							if (error)
 | 
				
			||||||
 | 
								return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						error = vfs_fileattr_get(filepath.dentry, &fa);
 | 
				
			||||||
 | 
						if (error)
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fileattr_to_file_attr(&fa, &fattr);
 | 
				
			||||||
 | 
						error = copy_struct_to_user(ufattr, usize, &fattr,
 | 
				
			||||||
 | 
									    sizeof(struct file_attr), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SYSCALL_DEFINE5(file_setattr, int, dfd, const char __user *, filename,
 | 
				
			||||||
 | 
							struct file_attr __user *, ufattr, size_t, usize,
 | 
				
			||||||
 | 
							unsigned int, at_flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct path filepath __free(path_put) = {};
 | 
				
			||||||
 | 
						struct filename *name __free(putname) = NULL;
 | 
				
			||||||
 | 
						unsigned int lookup_flags = 0;
 | 
				
			||||||
 | 
						struct file_attr fattr;
 | 
				
			||||||
 | 
						struct fileattr fa;
 | 
				
			||||||
 | 
						int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BUILD_BUG_ON(sizeof(struct file_attr) < FILE_ATTR_SIZE_VER0);
 | 
				
			||||||
 | 
						BUILD_BUG_ON(sizeof(struct file_attr) != FILE_ATTR_SIZE_LATEST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(at_flags & AT_SYMLINK_NOFOLLOW))
 | 
				
			||||||
 | 
							lookup_flags |= LOOKUP_FOLLOW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (usize > PAGE_SIZE)
 | 
				
			||||||
 | 
							return -E2BIG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (usize < FILE_ATTR_SIZE_VER0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						error = copy_struct_from_user(&fattr, sizeof(struct file_attr), ufattr,
 | 
				
			||||||
 | 
									      usize);
 | 
				
			||||||
 | 
						if (error)
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						error = file_attr_to_fileattr(&fattr, &fa);
 | 
				
			||||||
 | 
						if (error)
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name = getname_maybe_null(filename, at_flags);
 | 
				
			||||||
 | 
						if (IS_ERR(name))
 | 
				
			||||||
 | 
							return PTR_ERR(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!name && dfd >= 0) {
 | 
				
			||||||
 | 
							CLASS(fd, f)(dfd);
 | 
				
			||||||
 | 
							if (fd_empty(f))
 | 
				
			||||||
 | 
								return -EBADF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							filepath = fd_file(f)->f_path;
 | 
				
			||||||
 | 
							path_get(&filepath);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							error = filename_lookup(dfd, name, lookup_flags, &filepath,
 | 
				
			||||||
 | 
										NULL);
 | 
				
			||||||
 | 
							if (error)
 | 
				
			||||||
 | 
								return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						error = mnt_want_write(filepath.mnt);
 | 
				
			||||||
 | 
						if (!error) {
 | 
				
			||||||
 | 
							error = vfs_fileattr_set(mnt_idmap(filepath.mnt),
 | 
				
			||||||
 | 
										 filepath.dentry, &fa);
 | 
				
			||||||
 | 
							mnt_drop_write(filepath.mnt);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,6 +78,7 @@ struct cachestat;
 | 
				
			||||||
struct statmount;
 | 
					struct statmount;
 | 
				
			||||||
struct mnt_id_req;
 | 
					struct mnt_id_req;
 | 
				
			||||||
struct xattr_args;
 | 
					struct xattr_args;
 | 
				
			||||||
 | 
					struct file_attr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
#include <linux/aio_abi.h>
 | 
					#include <linux/aio_abi.h>
 | 
				
			||||||
| 
						 | 
					@ -371,6 +372,12 @@ asmlinkage long sys_removexattrat(int dfd, const char __user *path,
 | 
				
			||||||
asmlinkage long sys_lremovexattr(const char __user *path,
 | 
					asmlinkage long sys_lremovexattr(const char __user *path,
 | 
				
			||||||
				 const char __user *name);
 | 
									 const char __user *name);
 | 
				
			||||||
asmlinkage long sys_fremovexattr(int fd, const char __user *name);
 | 
					asmlinkage long sys_fremovexattr(int fd, const char __user *name);
 | 
				
			||||||
 | 
					asmlinkage long sys_file_getattr(int dfd, const char __user *filename,
 | 
				
			||||||
 | 
									 struct file_attr __user *attr, size_t usize,
 | 
				
			||||||
 | 
									 unsigned int at_flags);
 | 
				
			||||||
 | 
					asmlinkage long sys_file_setattr(int dfd, const char __user *filename,
 | 
				
			||||||
 | 
									 struct file_attr __user *attr, size_t usize,
 | 
				
			||||||
 | 
									 unsigned int at_flags);
 | 
				
			||||||
asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
 | 
					asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
 | 
				
			||||||
asmlinkage long sys_eventfd2(unsigned int count, int flags);
 | 
					asmlinkage long sys_eventfd2(unsigned int count, int flags);
 | 
				
			||||||
asmlinkage long sys_epoll_create1(int flags);
 | 
					asmlinkage long sys_epoll_create1(int flags);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -852,8 +852,14 @@ __SYSCALL(__NR_removexattrat, sys_removexattrat)
 | 
				
			||||||
#define __NR_open_tree_attr 467
 | 
					#define __NR_open_tree_attr 467
 | 
				
			||||||
__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr)
 | 
					__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* fs/inode.c */
 | 
				
			||||||
 | 
					#define __NR_file_getattr 468
 | 
				
			||||||
 | 
					__SYSCALL(__NR_file_getattr, sys_file_getattr)
 | 
				
			||||||
 | 
					#define __NR_file_setattr 469
 | 
				
			||||||
 | 
					__SYSCALL(__NR_file_setattr, sys_file_setattr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef __NR_syscalls
 | 
					#undef __NR_syscalls
 | 
				
			||||||
#define __NR_syscalls 468
 | 
					#define __NR_syscalls 470
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * 32 bit systems traditionally used different
 | 
					 * 32 bit systems traditionally used different
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,6 +148,24 @@ struct fsxattr {
 | 
				
			||||||
	unsigned char	fsx_pad[8];
 | 
						unsigned char	fsx_pad[8];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Variable size structure for file_[sg]et_attr().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note. This is alternative to the structure 'struct fileattr'/'struct fsxattr'.
 | 
				
			||||||
 | 
					 * As this structure is passed to/from userspace with its size, this can
 | 
				
			||||||
 | 
					 * be versioned based on the size.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct file_attr {
 | 
				
			||||||
 | 
						__u64 fa_xflags;	/* xflags field value (get/set) */
 | 
				
			||||||
 | 
						__u32 fa_extsize;	/* extsize field value (get/set)*/
 | 
				
			||||||
 | 
						__u32 fa_nextents;	/* nextents field value (get)   */
 | 
				
			||||||
 | 
						__u32 fa_projid;	/* project identifier (get/set) */
 | 
				
			||||||
 | 
						__u32 fa_cowextsize;	/* CoW extsize field value (get/set) */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FILE_ATTR_SIZE_VER0 24
 | 
				
			||||||
 | 
					#define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Flags for the fsx_xflags field
 | 
					 * Flags for the fsx_xflags field
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -408,3 +408,5 @@
 | 
				
			||||||
465	common	listxattrat			sys_listxattrat
 | 
					465	common	listxattrat			sys_listxattrat
 | 
				
			||||||
466	common	removexattrat			sys_removexattrat
 | 
					466	common	removexattrat			sys_removexattrat
 | 
				
			||||||
467	common	open_tree_attr			sys_open_tree_attr
 | 
					467	common	open_tree_attr			sys_open_tree_attr
 | 
				
			||||||
 | 
					468	common	file_getattr			sys_file_getattr
 | 
				
			||||||
 | 
					469	common	file_setattr			sys_file_setattr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue