Thread (28 messages) 28 messages, 7 authors, 2025-04-28

Re: [PATCH v4 3/3] fs: introduce getfsxattrat and setfsxattrat syscalls

From: Amir Goldstein <amir73il@gmail.com>
Date: 2025-03-23 08:56:37
Also in: linux-alpha, linux-api, linux-arch, linux-fsdevel, linux-m68k, linux-mips, linux-s390, linux-sh, linux-xfs, linuxppc-dev, lkml, sparclinux

On Fri, Mar 21, 2025 at 8:49 PM Andrey Albershteyn [off-list ref] wrote:
From: Andrey Albershteyn <redacted>

Introduce getfsxattrat and setfsxattrat syscalls to manipulate inode
extended attributes/flags. The syscalls take parent directory fd and
path to the child together with struct fsxattr.

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 <redacted>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
...
+SYSCALL_DEFINE5(setfsxattrat, int, dfd, const char __user *, filename,
+               struct fsxattr __user *, ufsx, size_t, usize,
+               unsigned int, at_flags)
+{
+       struct fileattr fa;
+       struct path filepath;
+       int error;
+       unsigned int lookup_flags = 0;
+       struct filename *name;
+       struct mnt_idmap *idmap;.
+       struct dentry *dentry;
+       struct vfsmount *mnt;
+       struct fsxattr fsx = {};
+
+       BUILD_BUG_ON(sizeof(struct fsxattr) < FSXATTR_SIZE_VER0);
+       BUILD_BUG_ON(sizeof(struct fsxattr) != FSXATTR_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 (at_flags & AT_EMPTY_PATH)
+               lookup_flags |= LOOKUP_EMPTY;
+
+       if (usize > PAGE_SIZE)
+               return -E2BIG;
+
+       if (usize < FSXATTR_SIZE_VER0)
+               return -EINVAL;
+
+       error = copy_struct_from_user(&fsx, sizeof(struct fsxattr), ufsx, usize);
+       if (error)
+               return error;
+
+       fsxattr_to_fileattr(&fsx, &fa);
+
+       name = getname_maybe_null(filename, at_flags);
+       if (!name) {
+               CLASS(fd, f)(dfd);
+
+               if (fd_empty(f))
+                       return -EBADF;
+
+               idmap = file_mnt_idmap(fd_file(f));
+               dentry = file_dentry(fd_file(f));
+               mnt = fd_file(f)->f_path.mnt;
+       } else {
+               error = filename_lookup(dfd, name, lookup_flags, &filepath,
+                                       NULL);
+               if (error)
+                       return error;
+
+               idmap = mnt_idmap(filepath.mnt);
+               dentry = filepath.dentry;
+               mnt = filepath.mnt;
+       }
+
+       error = mnt_want_write(mnt);
+       if (!error) {
+               error = vfs_fileattr_set(idmap, dentry, &fa);
+               if (error == -ENOIOCTLCMD)
+                       error = -EOPNOTSUPP;
This is awkward.
vfs_fileattr_set() should return -EOPNOTSUPP.
ioctl_setflags() could maybe convert it to -ENOIOCTLCMD,
but looking at similar cases ioctl_fiemap(), ioctl_fsfreeze() the
ioctl returns -EOPNOTSUPP.

I don't think it is necessarily a bad idea to start returning
 -EOPNOTSUPP instead of -ENOIOCTLCMD for the ioctl
because that really reflects the fact that the ioctl is now implemented
in vfs and not in the specific fs.

and I think it would not be a bad idea at all to make that change
together with the merge of the syscalls as a sort of hint to userspace
that uses the ioctl, that the sycalls API exists.

Thanks,
Amir.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help