From: Andrey Albershteyn <aalbersh@redhat.com>
To: aalbersh@kernel.org, linux-fsdevel@vger.kernel.org,
linux-xfs@vger.kernel.org
Subject: [PATCH v2 1/4] libfrog: add wrappers for file_getattr/file_setattr syscalls
Date: Wed, 27 Aug 2025 17:15:53 +0200 [thread overview]
Message-ID: <20250827-xattrat-syscall-v2-1-82a2d2d5865b@kernel.org> (raw)
In-Reply-To: <20250827-xattrat-syscall-v2-0-82a2d2d5865b@kernel.org>
Add wrappers for new file_getattr/file_setattr inode syscalls which will
be used by xfs_quota and xfs_io.
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
configure.ac | 1 +
include/builddefs.in | 5 +++
include/linux.h | 20 +++++++++
libfrog/Makefile | 2 +
libfrog/file_attr.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++
libfrog/file_attr.h | 35 +++++++++++++++
m4/package_libcdev.m4 | 19 ++++++++
7 files changed, 204 insertions(+)
diff --git a/configure.ac b/configure.ac
index 195ee6dddf61..a3206d53e7e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,7 @@ AC_PACKAGE_NEED_RCU_INIT
AC_HAVE_PWRITEV2
AC_HAVE_COPY_FILE_RANGE
AC_HAVE_CACHESTAT
+AC_HAVE_FILE_ATTR
AC_NEED_INTERNAL_FSXATTR
AC_NEED_INTERNAL_FSCRYPT_ADD_KEY_ARG
AC_NEED_INTERNAL_FSCRYPT_POLICY_V2
diff --git a/include/builddefs.in b/include/builddefs.in
index 04b4e0880a84..d727b55b854f 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -97,6 +97,7 @@ HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@
HAVE_PWRITEV2 = @have_pwritev2@
HAVE_COPY_FILE_RANGE = @have_copy_file_range@
HAVE_CACHESTAT = @have_cachestat@
+HAVE_FILE_ATTR = @have_file_attr@
NEED_INTERNAL_FSXATTR = @need_internal_fsxattr@
NEED_INTERNAL_FSCRYPT_ADD_KEY_ARG = @need_internal_fscrypt_add_key_arg@
NEED_INTERNAL_FSCRYPT_POLICY_V2 = @need_internal_fscrypt_policy_v2@
@@ -169,6 +170,10 @@ ifeq ($(ENABLE_GETTEXT),yes)
GCFLAGS += -DENABLE_GETTEXT
endif
+ifeq ($(HAVE_FILE_ATTR),yes)
+LCFLAGS += -DHAVE_FILE_ATTR
+endif
+
# Override these if C++ needs other options
SANITIZER_CXXFLAGS = $(SANITIZER_CFLAGS)
GCXXFLAGS = $(GCFLAGS)
diff --git a/include/linux.h b/include/linux.h
index 6e83e073aa2e..993789f01b3a 100644
--- a/include/linux.h
+++ b/include/linux.h
@@ -16,6 +16,7 @@
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <inttypes.h>
#include <malloc.h>
#include <getopt.h>
@@ -202,6 +203,25 @@ struct fsxattr {
};
#endif
+/*
+ * Use FILE_ATTR_SIZE_VER0 (linux/fs.h) instead of build system HAVE_FILE_ATTR
+ * as this header could be included in other places where HAVE_FILE_ATTR is not
+ * defined (e.g. xfstests's conftest.c in ./configure)
+ */
+#ifndef FILE_ATTR_SIZE_VER0
+/*
+ * We need to define file_attr if it's missing to know how to convert it to
+ * fsxattr
+ */
+struct file_attr {
+ __u32 fa_xflags;
+ __u32 fa_extsize;
+ __u32 fa_nextents;
+ __u32 fa_projid;
+ __u32 fa_cowextsize;
+};
+#endif
+
#ifndef FS_IOC_FSGETXATTR
/*
* Flags for the fsx_xflags field
diff --git a/libfrog/Makefile b/libfrog/Makefile
index 560bad417ee4..268fa26638d7 100644
--- a/libfrog/Makefile
+++ b/libfrog/Makefile
@@ -24,6 +24,7 @@ fsproperties.c \
fsprops.c \
getparents.c \
histogram.c \
+file_attr.c \
list_sort.c \
linux.c \
logging.c \
@@ -55,6 +56,7 @@ fsprops.h \
getparents.h \
handle_priv.h \
histogram.h \
+file_attr.h \
logging.h \
paths.h \
projects.h \
diff --git a/libfrog/file_attr.c b/libfrog/file_attr.c
new file mode 100644
index 000000000000..1d42895477ae
--- /dev/null
+++ b/libfrog/file_attr.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Red Hat, Inc.
+ * All Rights Reserved.
+ */
+
+#include "file_attr.h"
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <asm/types.h>
+#include <fcntl.h>
+
+static void
+file_attr_to_fsxattr(
+ const struct file_attr *fa,
+ struct fsxattr *fsxa)
+{
+ memset(fsxa, 0, sizeof(struct fsxattr));
+
+ fsxa->fsx_xflags = fa->fa_xflags;
+ fsxa->fsx_extsize = fa->fa_extsize;
+ fsxa->fsx_nextents = fa->fa_nextents;
+ fsxa->fsx_projid = fa->fa_projid;
+ fsxa->fsx_cowextsize = fa->fa_cowextsize;
+
+}
+
+static void
+fsxattr_to_file_attr(
+ const struct fsxattr *fsxa,
+ struct file_attr *fa)
+{
+ memset(fa, 0, sizeof(struct file_attr));
+
+ fa->fa_xflags = fsxa->fsx_xflags;
+ fa->fa_extsize = fsxa->fsx_extsize;
+ fa->fa_nextents = fsxa->fsx_nextents;
+ fa->fa_projid = fsxa->fsx_projid;
+ fa->fa_cowextsize = fsxa->fsx_cowextsize;
+}
+
+int
+xfrog_file_getattr(
+ const int dfd,
+ const char *path,
+ const struct stat *stat,
+ struct file_attr *fa,
+ const unsigned int at_flags)
+{
+ int error;
+ int fd;
+ struct fsxattr fsxa;
+
+#ifdef HAVE_FILE_ATTR
+ error = syscall(__NR_file_getattr, dfd, path, fa,
+ sizeof(struct file_attr), at_flags);
+ if (error && errno != ENOSYS)
+ return error;
+
+ if (!error)
+ return error;
+#endif
+
+ if (SPECIAL_FILE(stat->st_mode)) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ fd = open(path, O_RDONLY|O_NOCTTY);
+ if (fd == -1)
+ return fd;
+
+ error = ioctl(fd, FS_IOC_FSGETXATTR, &fsxa);
+ close(fd);
+ if (error)
+ return error;
+
+ fsxattr_to_file_attr(&fsxa, fa);
+
+ return error;
+}
+
+int
+xfrog_file_setattr(
+ const int dfd,
+ const char *path,
+ const struct stat *stat,
+ struct file_attr *fa,
+ const unsigned int at_flags)
+{
+ int error;
+ int fd;
+ struct fsxattr fsxa;
+
+#ifdef HAVE_FILE_ATTR
+ error = syscall(__NR_file_setattr, dfd, path, fa,
+ sizeof(struct file_attr), at_flags);
+ if (error && errno != ENOSYS)
+ return error;
+
+ if (!error)
+ return error;
+#endif
+
+ if (SPECIAL_FILE(stat->st_mode)) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ fd = open(path, O_RDONLY|O_NOCTTY);
+ if (fd == -1)
+ return fd;
+
+ file_attr_to_fsxattr(fa, &fsxa);
+
+ error = ioctl(fd, FS_IOC_FSSETXATTR, fa);
+ close(fd);
+
+ return error;
+}
diff --git a/libfrog/file_attr.h b/libfrog/file_attr.h
new file mode 100644
index 000000000000..ad33241bbffa
--- /dev/null
+++ b/libfrog/file_attr.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Red Hat, Inc.
+ * All Rights Reserved.
+ */
+#ifndef __LIBFROG_FILE_ATTR_H__
+#define __LIBFROG_FILE_ATTR_H__
+
+#include "linux.h"
+#include <sys/stat.h>
+
+#define SPECIAL_FILE(x) \
+ (S_ISCHR((x)) \
+ || S_ISBLK((x)) \
+ || S_ISFIFO((x)) \
+ || S_ISLNK((x)) \
+ || S_ISSOCK((x)))
+
+int
+xfrog_file_getattr(
+ const int dfd,
+ const char *path,
+ const struct stat *stat,
+ struct file_attr *fa,
+ const unsigned int at_flags);
+
+int
+xfrog_file_setattr(
+ const int dfd,
+ const char *path,
+ const struct stat *stat,
+ struct file_attr *fa,
+ const unsigned int at_flags);
+
+#endif /* __LIBFROG_FILE_ATTR_H__ */
diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4
index b77ac1a7580a..6a267dab7ab7 100644
--- a/m4/package_libcdev.m4
+++ b/m4/package_libcdev.m4
@@ -274,3 +274,22 @@ AC_DEFUN([AC_PACKAGE_CHECK_LTO],
AC_SUBST(lto_cflags)
AC_SUBST(lto_ldflags)
])
+
+#
+# Check if we have a file_getattr/file_setattr system call (Linux)
+#
+AC_DEFUN([AC_HAVE_FILE_ATTR],
+ [ AC_MSG_CHECKING([for file_getattr/file_setattr syscalls])
+ AC_LINK_IFELSE(
+ [ AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <sys/syscall.h>
+#include <unistd.h>
+ ]], [[
+syscall(__NR_file_getattr, 0, 0, 0, 0, 0);
+ ]])
+ ], have_file_attr=yes
+ AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
+ AC_SUBST(have_file_attr)
+ ])
--
2.49.0
next prev parent reply other threads:[~2025-08-27 15:16 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-27 15:14 Tests for file_getattr()/file_setattr() and xfsprogs update Andrey Albershteyn
2025-08-27 15:15 ` [PATCH v2 0/4] xfsprogs: utilize file_getattr() and file_setattr() Andrey Albershteyn
2025-08-27 15:15 ` Andrey Albershteyn [this message]
2025-08-28 14:34 ` [PATCH v2 1/4] libfrog: add wrappers for file_getattr/file_setattr syscalls Darrick J. Wong
2025-08-27 15:15 ` [PATCH v2 2/4] xfs_quota: utilize file_setattr to set prjid on special files Andrey Albershteyn
2025-08-28 14:39 ` Darrick J. Wong
2025-08-29 15:42 ` Andrey Albershteyn
2025-08-27 15:15 ` [PATCH v2 3/4] xfs_io: make ls/chattr work with " Andrey Albershteyn
2025-08-28 14:40 ` Darrick J. Wong
2025-08-27 15:15 ` [PATCH v2 4/4] xfs_db: use file_setattr to copy attributes on special files with rdump Andrey Albershteyn
2025-08-28 14:41 ` Darrick J. Wong
2025-08-27 15:16 ` [PATCH v2 0/3] Test file_getattr and file_setattr syscalls Andrey Albershteyn
2025-08-27 15:16 ` [PATCH v2 1/3] file_attr: introduce program to set/get fsxattr Andrey Albershteyn
2025-08-28 14:49 ` Darrick J. Wong
2025-08-27 15:16 ` [PATCH v2 2/3] generic: introduce test to test file_getattr/file_setattr syscalls Andrey Albershteyn
2025-08-28 14:50 ` Darrick J. Wong
2025-08-27 15:16 ` [PATCH v2 3/3] xfs: test quota's project ID on special files Andrey Albershteyn
2025-08-28 14:51 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250827-xattrat-syscall-v2-1-82a2d2d5865b@kernel.org \
--to=aalbersh@redhat.com \
--cc=aalbersh@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).