Skip to content

Commit 6624165

Browse files
committed
Merge patch series "fs: introduce file_getattr and file_setattr syscalls"
Andrey Albershteyn <[email protected]> says: This patchset introduced two new syscalls file_getattr() and file_setattr(). These syscalls are similar to FS_IOC_FSSETXATTR ioctl() except they use *at() semantics. Therefore, there's no need to open the file to get a fd. These syscalls allow userspace to set filesystem inode attributes on special files. One of the usage examples is XFS quota projects. XFS has project quotas which could be attached to a directory. All new inodes in these directories inherit project ID set on parent directory. The project is created from userspace by opening and calling FS_IOC_FSSETXATTR on each inode. This is not possible for special files such as FIFO, SOCK, BLK etc. Therefore, some inodes are left with empty project ID. Those inodes then are not shown in the quota accounting but still exist in the directory. This is not critical but in the case when special files are created in the directory with already existing project quota, these new inodes inherit extended attributes. This creates a mix of special files with and without attributes. Moreover, special files with attributes don't have a possibility to become clear or change the attributes. This, in turn, prevents userspace from re-creating quota project on these existing files. An xfstests test generic/766 with basic coverage is at: https://github.com/alberand/xfstests/commits/b4/file-attr/ NAME file_getattr/file_setattr - get/set filesystem inode attributes SYNOPSIS #include <sys/syscall.h> /* Definition of SYS_* constants */ #include <unistd.h> long syscall(SYS_file_getattr, int dirfd, const char *pathname, struct fsx_fileattr *fsx, size_t size, unsigned int at_flags); long syscall(SYS_file_setattr, int dirfd, const char *pathname, struct fsx_fileattr *fsx, size_t size, unsigned int at_flags); Note: glibc doesn't provide for file_getattr()/file_setattr(), use syscall(2) instead. DESCRIPTION The file_getattr()/file_setattr() are used to set extended file attributes. These syscalls take dirfd in conjunction with the pathname argument. The syscall then operates on inode opened according to openat(2) semantics. This is an alternative to FS_IOC_FSGETXATTR/FS_IOC_FSSETXATTR ioctl with a difference that file don't need to be open as file can be referenced with a path instead of fd. By having this one can manipulated filesystem inode attributes not only on regular files but also on special ones. This is not possible with FS_IOC_FSSETXATTR ioctl as ioctl() can not be called on special files directly for the filesystem inode. at_flags can be set to AT_SYMLINK_NOFOLLOW or AT_EMPTY_PATH. RETURN VALUE On success, 0 is returned. On error, -1 is returned, and errno is set to indicate the error. ERRORS EINVAL Invalid at_flag specified (only AT_SYMLINK_NOFOLLOW and AT_EMPTY_PATH is supported). EINVAL Size was smaller than any known version of struct fsx_fileattr. EINVAL Invalid combination of parameters provided in fsx_fileattr for this type of file. E2BIG Size of input argument struct fsx_fileattr is too big. EBADF Invalid file descriptor was provided. EPERM No permission to change this file. EOPNOTSUPP Filesystem does not support setting attributes on this type of inode HISTORY Added in Linux 6.16. EXAMPLE Create directory and file "mkdir ./dir && touch ./dir/foo" and then execute the following program: #include <fcntl.h> #include <errno.h> #include <string.h> #include <linux/fs.h> #include <stdio.h> #include <sys/syscall.h> #include <unistd.h> #if !defined(SYS_file_getattr) && defined(__x86_64__) #define SYS_file_getattr 468 #define SYS_file_setattr 469 struct fsx_fileattr { __u32 fsx_xflags; __u32 fsx_extsize; __u32 fsx_nextents; __u32 fsx_projid; __u32 fsx_cowextsize; }; #endif int main(int argc, char **argv) { int dfd; int error; struct fsx_fileattr fsx; dfd = open("./dir", O_RDONLY); if (dfd == -1) { printf("can not open ./dir"); return dfd; } error = syscall(SYS_file_getattr, dfd, "./foo", &fsx, sizeof(struct fsx_fileattr), 0); if (error) { printf("can not call SYS_file_getattr: %s", strerror(errno)); return error; } printf("./dir/foo flags: %d\n", fsx.fsx_xflags); fsx.fsx_xflags |= FS_XFLAG_NODUMP; error = syscall(SYS_file_setattr, dfd, "./foo", &fsx, sizeof(struct fsx_fileattr), 0); if (error) { printf("can not call SYS_file_setattr: %s", strerror(errno)); return error; } printf("./dir/foo flags: %d\n", fsx.fsx_xflags); return error; } SEE ALSO ioctl(2), ioctl_iflags(2), ioctl_xfs_fsgetxattr(2), openat(2) * patches from https://lore.kernel.org/[email protected]: fs: introduce file_getattr and file_setattr syscalls fs: prepare for extending file_get/setattr() fs: make vfs_fileattr_[get|set] return -EOPNOSUPP selinux: implement inode_file_[g|s]etattr hooks lsm: introduce new hooks for setting/getting inode fsxattr fs: split fileattr related helpers into separate file Link: https://lore.kernel.org/[email protected] Signed-off-by: Christian Brauner <[email protected]>
2 parents 19272b3 + be7efb2 commit 6624165

File tree

31 files changed

+658
-316
lines changed

31 files changed

+658
-316
lines changed

arch/alpha/kernel/syscalls/syscall.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,3 +507,5 @@
507507
575 common listxattrat sys_listxattrat
508508
576 common removexattrat sys_removexattrat
509509
577 common open_tree_attr sys_open_tree_attr
510+
578 common file_getattr sys_file_getattr
511+
579 common file_setattr sys_file_setattr

arch/arm/tools/syscall.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,3 +482,5 @@
482482
465 common listxattrat sys_listxattrat
483483
466 common removexattrat sys_removexattrat
484484
467 common open_tree_attr sys_open_tree_attr
485+
468 common file_getattr sys_file_getattr
486+
469 common file_setattr sys_file_setattr

arch/arm64/tools/syscall_32.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,3 +479,5 @@
479479
465 common listxattrat sys_listxattrat
480480
466 common removexattrat sys_removexattrat
481481
467 common open_tree_attr sys_open_tree_attr
482+
468 common file_getattr sys_file_getattr
483+
469 common file_setattr sys_file_setattr

arch/m68k/kernel/syscalls/syscall.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,5 @@
467467
465 common listxattrat sys_listxattrat
468468
466 common removexattrat sys_removexattrat
469469
467 common open_tree_attr sys_open_tree_attr
470+
468 common file_getattr sys_file_getattr
471+
469 common file_setattr sys_file_setattr

arch/microblaze/kernel/syscalls/syscall.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,3 +473,5 @@
473473
465 common listxattrat sys_listxattrat
474474
466 common removexattrat sys_removexattrat
475475
467 common open_tree_attr sys_open_tree_attr
476+
468 common file_getattr sys_file_getattr
477+
469 common file_setattr sys_file_setattr

arch/mips/kernel/syscalls/syscall_n32.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,5 @@
406406
465 n32 listxattrat sys_listxattrat
407407
466 n32 removexattrat sys_removexattrat
408408
467 n32 open_tree_attr sys_open_tree_attr
409+
468 n32 file_getattr sys_file_getattr
410+
469 n32 file_setattr sys_file_setattr

arch/mips/kernel/syscalls/syscall_n64.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,5 @@
382382
465 n64 listxattrat sys_listxattrat
383383
466 n64 removexattrat sys_removexattrat
384384
467 n64 open_tree_attr sys_open_tree_attr
385+
468 n64 file_getattr sys_file_getattr
386+
469 n64 file_setattr sys_file_setattr

arch/mips/kernel/syscalls/syscall_o32.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,5 @@
455455
465 o32 listxattrat sys_listxattrat
456456
466 o32 removexattrat sys_removexattrat
457457
467 o32 open_tree_attr sys_open_tree_attr
458+
468 o32 file_getattr sys_file_getattr
459+
469 o32 file_setattr sys_file_setattr

arch/parisc/kernel/syscalls/syscall.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,5 @@
466466
465 common listxattrat sys_listxattrat
467467
466 common removexattrat sys_removexattrat
468468
467 common open_tree_attr sys_open_tree_attr
469+
468 common file_getattr sys_file_getattr
470+
469 common file_setattr sys_file_setattr

arch/powerpc/kernel/syscalls/syscall.tbl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,3 +558,5 @@
558558
465 common listxattrat sys_listxattrat
559559
466 common removexattrat sys_removexattrat
560560
467 common open_tree_attr sys_open_tree_attr
561+
468 common file_getattr sys_file_getattr
562+
469 common file_setattr sys_file_setattr

0 commit comments

Comments
 (0)