From: Yu Watanabe Date: Thu, 27 Feb 2025 17:06:32 +0000 (+0900) Subject: tree-wide: drop workarounds for statx() X-Git-Tag: v258-rc1~1216^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4424e6c811f46bf2c53c9056a058ba277cfdee40;p=thirdparty%2Fsystemd.git tree-wide: drop workarounds for statx() struct statx in glibc header was introduced in glibc-2.28 (fd70af45528d59a00eb3190ef6706cb299488fcd), but at that time, sys/stat.h conflicts with linux/stat.h. Since glibc-2.30 (5dad6ffbb2b76215cfcd38c3001778536ada8e8a), sys/stat.h includes linux/stat.h if exists. Since now our baseline of glibc is 2.31. Hence, we can drop workarounds for struct statx by importing linux/stat.h from newer kernel (v6.14-rc4). --- diff --git a/meson.build b/meson.build index 0865c861ecf..f4fd28410fb 100644 --- a/meson.build +++ b/meson.build @@ -569,14 +569,12 @@ decl_headers = ''' #include #include #include -#include #include ''' foreach decl : ['char16_t', 'char32_t', 'struct mount_attr', - 'struct statx', 'struct dirent64', 'struct sched_attr', ] @@ -595,21 +593,9 @@ foreach decl : ['char16_t', endif endif - if decl == 'struct statx' - if have - want_linux_stat_h = false - else - have = cc.sizeof(decl, - prefix : decl_headers + '#include ', - args : '-D_GNU_SOURCE') > 0 - want_linux_stat_h = have - endif - endif - conf.set10('HAVE_' + decl.underscorify().to_upper(), have) endforeach -conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h) conf.set10('WANT_LINUX_FS_H', want_linux_fs_h) foreach ident : ['secure_getenv', '__secure_getenv'] @@ -640,9 +626,6 @@ foreach ident : [ #include '''], ['bpf', '''#include #include '''], - ['statx', '''#include - #include - #include '''], ['explicit_bzero' , '''#include '''], ['reallocarray', '''#include '''], ['set_mempolicy', '''#include diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c index 17df6a24c90..51db9820f9c 100644 --- a/src/basic/dirent-util.c +++ b/src/basic/dirent-util.c @@ -9,7 +9,7 @@ #include "string-util.h" int dirent_ensure_type(int dir_fd, struct dirent *de) { - STRUCT_STATX_DEFINE(sx); + struct statx sx; int r; assert(dir_fd >= 0); diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 539e8ca9250..2691210d918 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -1087,30 +1087,29 @@ int path_is_root_at(int dir_fd, const char *path) { } int fds_are_same_mount(int fd1, int fd2) { - STRUCT_NEW_STATX_DEFINE(st1); - STRUCT_NEW_STATX_DEFINE(st2); + struct statx sx1 = {}, sx2 = {}; /* explicitly initialize the struct to make msan silent. */ int r; assert(fd1 >= 0); assert(fd2 >= 0); - r = statx_fallback(fd1, "", AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &st1.sx); + r = statx_fallback(fd1, "", AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &sx1); if (r < 0) return r; - r = statx_fallback(fd2, "", AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &st2.sx); + r = statx_fallback(fd2, "", AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &sx2); if (r < 0) return r; /* First, compare inode. If these are different, the fd does not point to the root directory "/". */ - if (!statx_inode_same(&st1.sx, &st2.sx)) + if (!statx_inode_same(&sx1, &sx2)) return false; /* Note, statx() does not provide the mount ID and path_get_mnt_id_at() does not work when an old * kernel is used. In that case, let's assume that we do not have such spurious mount points in an * early boot stage, and silently skip the following check. */ - if (!FLAGS_SET(st1.nsx.stx_mask, STATX_MNT_ID)) { + if (!FLAGS_SET(sx1.stx_mask, STATX_MNT_ID)) { int mntid; r = path_get_mnt_id_at_fallback(fd1, "", &mntid); @@ -1118,11 +1117,11 @@ int fds_are_same_mount(int fd1, int fd2) { return r; assert(mntid >= 0); - st1.nsx.stx_mnt_id = mntid; - st1.nsx.stx_mask |= STATX_MNT_ID; + sx1.stx_mnt_id = mntid; + sx1.stx_mask |= STATX_MNT_ID; } - if (!FLAGS_SET(st2.nsx.stx_mask, STATX_MNT_ID)) { + if (!FLAGS_SET(sx2.stx_mask, STATX_MNT_ID)) { int mntid; r = path_get_mnt_id_at_fallback(fd2, "", &mntid); @@ -1130,11 +1129,11 @@ int fds_are_same_mount(int fd1, int fd2) { return r; assert(mntid >= 0); - st2.nsx.stx_mnt_id = mntid; - st2.nsx.stx_mask |= STATX_MNT_ID; + sx2.stx_mnt_id = mntid; + sx2.stx_mask |= STATX_MNT_ID; } - return statx_mount_same(&st1.nsx, &st2.nsx); + return statx_mount_same(&sx1, &sx2); } const char* accmode_to_string(int flags) { diff --git a/src/basic/linux/stat.h b/src/basic/linux/stat.h new file mode 100644 index 00000000000..2396306c5a3 --- /dev/null +++ b/src/basic/linux/stat.h @@ -0,0 +1,254 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_STAT_H +#define _LINUX_STAT_H + +#include + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#define S_IFMT 00170000 +#define S_IFSOCK 0140000 +#define S_IFLNK 0120000 +#define S_IFREG 0100000 +#define S_IFBLK 0060000 +#define S_IFDIR 0040000 +#define S_IFCHR 0020000 +#define S_IFIFO 0010000 +#define S_ISUID 0004000 +#define S_ISGID 0002000 +#define S_ISVTX 0001000 + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) + +#define S_IRWXU 00700 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 + +#define S_IRWXG 00070 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 + +#define S_IRWXO 00007 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +#endif + +/* + * Timestamp structure for the timestamps in struct statx. + * + * tv_sec holds the number of seconds before (negative) or after (positive) + * 00:00:00 1st January 1970 UTC. + * + * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time. + * + * __reserved is held in case we need a yet finer resolution. + */ +struct statx_timestamp { + __s64 tv_sec; + __u32 tv_nsec; + __s32 __reserved; +}; + +/* + * Structures for the extended file attribute retrieval system call + * (statx()). + * + * The caller passes a mask of what they're specifically interested in as a + * parameter to statx(). What statx() actually got will be indicated in + * st_mask upon return. + * + * For each bit in the mask argument: + * + * - if the datum is not supported: + * + * - the bit will be cleared, and + * + * - the datum will be set to an appropriate fabricated value if one is + * available (eg. CIFS can take a default uid and gid), otherwise + * + * - the field will be cleared; + * + * - otherwise, if explicitly requested: + * + * - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is + * set or if the datum is considered out of date, and + * + * - the field will be filled in and the bit will be set; + * + * - otherwise, if not requested, but available in approximate form without any + * effort, it will be filled in anyway, and the bit will be set upon return + * (it might not be up to date, however, and no attempt will be made to + * synchronise the internal state first); + * + * - otherwise the field and the bit will be cleared before returning. + * + * Items in STATX_BASIC_STATS may be marked unavailable on return, but they + * will have values installed for compatibility purposes so that stat() and + * co. can be emulated in userspace. + */ +struct statx { + /* 0x00 */ + /* What results were written [uncond] */ + __u32 stx_mask; + + /* Preferred general I/O size [uncond] */ + __u32 stx_blksize; + + /* Flags conveying information about the file [uncond] */ + __u64 stx_attributes; + + /* 0x10 */ + /* Number of hard links */ + __u32 stx_nlink; + + /* User ID of owner */ + __u32 stx_uid; + + /* Group ID of owner */ + __u32 stx_gid; + + /* File mode */ + __u16 stx_mode; + __u16 __spare0[1]; + + /* 0x20 */ + /* Inode number */ + __u64 stx_ino; + + /* File size */ + __u64 stx_size; + + /* Number of 512-byte blocks allocated */ + __u64 stx_blocks; + + /* Mask to show what's supported in stx_attributes */ + __u64 stx_attributes_mask; + + /* 0x40 */ + /* Last access time */ + struct statx_timestamp stx_atime; + + /* File creation time */ + struct statx_timestamp stx_btime; + + /* Last attribute change time */ + struct statx_timestamp stx_ctime; + + /* Last data modification time */ + struct statx_timestamp stx_mtime; + + /* 0x80 */ + /* Device ID of special file [if bdev/cdev] */ + __u32 stx_rdev_major; + __u32 stx_rdev_minor; + + /* ID of device containing file [uncond] */ + __u32 stx_dev_major; + __u32 stx_dev_minor; + + /* 0x90 */ + __u64 stx_mnt_id; + + /* Memory buffer alignment for direct I/O */ + __u32 stx_dio_mem_align; + + /* File offset alignment for direct I/O */ + __u32 stx_dio_offset_align; + + /* 0xa0 */ + /* Subvolume identifier */ + __u64 stx_subvol; + + /* Min atomic write unit in bytes */ + __u32 stx_atomic_write_unit_min; + + /* Max atomic write unit in bytes */ + __u32 stx_atomic_write_unit_max; + + /* 0xb0 */ + /* Max atomic write segment count */ + __u32 stx_atomic_write_segments_max; + + /* File offset alignment for direct I/O reads */ + __u32 stx_dio_read_offset_align; + + /* 0xb8 */ + __u64 __spare3[9]; /* Spare space for future expansion */ + + /* 0x100 */ +}; + +/* + * Flags to be stx_mask + * + * Query request/result mask for statx() and struct statx::stx_mask. + * + * These bits should be set in the mask argument of statx() to request + * particular items when calling statx(). + */ +#define STATX_TYPE 0x00000001U /* Want/got stx_mode & S_IFMT */ +#define STATX_MODE 0x00000002U /* Want/got stx_mode & ~S_IFMT */ +#define STATX_NLINK 0x00000004U /* Want/got stx_nlink */ +#define STATX_UID 0x00000008U /* Want/got stx_uid */ +#define STATX_GID 0x00000010U /* Want/got stx_gid */ +#define STATX_ATIME 0x00000020U /* Want/got stx_atime */ +#define STATX_MTIME 0x00000040U /* Want/got stx_mtime */ +#define STATX_CTIME 0x00000080U /* Want/got stx_ctime */ +#define STATX_INO 0x00000100U /* Want/got stx_ino */ +#define STATX_SIZE 0x00000200U /* Want/got stx_size */ +#define STATX_BLOCKS 0x00000400U /* Want/got stx_blocks */ +#define STATX_BASIC_STATS 0x000007ffU /* The stuff in the normal stat struct */ +#define STATX_BTIME 0x00000800U /* Want/got stx_btime */ +#define STATX_MNT_ID 0x00001000U /* Got stx_mnt_id */ +#define STATX_DIOALIGN 0x00002000U /* Want/got direct I/O alignment info */ +#define STATX_MNT_ID_UNIQUE 0x00004000U /* Want/got extended stx_mount_id */ +#define STATX_SUBVOL 0x00008000U /* Want/got stx_subvol */ +#define STATX_WRITE_ATOMIC 0x00010000U /* Want/got atomic_write_* fields */ +#define STATX_DIO_READ_ALIGN 0x00020000U /* Want/got dio read alignment info */ + +#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */ + +/* + * This is deprecated, and shall remain the same value in the future. To avoid + * confusion please use the equivalent (STATX_BASIC_STATS | STATX_BTIME) + * instead. + */ +#define STATX_ALL 0x00000fffU + +/* + * Attributes to be found in stx_attributes and masked in stx_attributes_mask. + * + * These give information about the features or the state of a file that might + * be of use to ordinary userspace programs such as GUIs or ls rather than + * specialised tools. + * + * Note that the flags marked [I] correspond to the FS_IOC_SETFLAGS flags + * semantically. Where possible, the numerical value is picked to correspond + * also. Note that the DAX attribute indicates that the file is in the CPU + * direct access state. It does not correspond to the per-inode flag that + * some filesystems support. + * + */ +#define STATX_ATTR_COMPRESSED 0x00000004 /* [I] File is compressed by the fs */ +#define STATX_ATTR_IMMUTABLE 0x00000010 /* [I] File is marked immutable */ +#define STATX_ATTR_APPEND 0x00000020 /* [I] File is append-only */ +#define STATX_ATTR_NODUMP 0x00000040 /* [I] File is not to be dumped */ +#define STATX_ATTR_ENCRYPTED 0x00000800 /* [I] File requires key to decrypt in fs */ +#define STATX_ATTR_AUTOMOUNT 0x00001000 /* Dir: Automount trigger */ +#define STATX_ATTR_MOUNT_ROOT 0x00002000 /* Root of a mount */ +#define STATX_ATTR_VERITY 0x00100000 /* [I] Verity protected file */ +#define STATX_ATTR_DAX 0x00200000 /* File is currently in DAX state */ +#define STATX_ATTR_WRITE_ATOMIC 0x00400000 /* File supports atomic write operations */ + + +#endif /* _LINUX_STAT_H */ diff --git a/src/basic/missing_stat.h b/src/basic/missing_stat.h deleted file mode 100644 index eba1a3876f9..00000000000 --- a/src/basic/missing_stat.h +++ /dev/null @@ -1,135 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include -#include - -#if WANT_LINUX_STAT_H -#include -#endif - -/* The newest definition we are aware of (fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60; 5.8) */ -#define STATX_DEFINITION { \ - __u32 stx_mask; \ - __u32 stx_blksize; \ - __u64 stx_attributes; \ - __u32 stx_nlink; \ - __u32 stx_uid; \ - __u32 stx_gid; \ - __u16 stx_mode; \ - __u16 __spare0[1]; \ - __u64 stx_ino; \ - __u64 stx_size; \ - __u64 stx_blocks; \ - __u64 stx_attributes_mask; \ - struct statx_timestamp stx_atime; \ - struct statx_timestamp stx_btime; \ - struct statx_timestamp stx_ctime; \ - struct statx_timestamp stx_mtime; \ - __u32 stx_rdev_major; \ - __u32 stx_rdev_minor; \ - __u32 stx_dev_major; \ - __u32 stx_dev_minor; \ - __u64 stx_mnt_id; \ - __u64 __spare2; \ - __u64 __spare3[12]; \ -} - -#if !HAVE_STRUCT_STATX -struct statx_timestamp { - __s64 tv_sec; - __u32 tv_nsec; - __s32 __reserved; -}; - -struct statx STATX_DEFINITION; -#endif - -/* Always define the newest version we are aware of as a distinct type, so that we can use it even if glibc - * defines an older definition */ -struct new_statx STATX_DEFINITION; - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef AT_STATX_SYNC_AS_STAT -#define AT_STATX_SYNC_AS_STAT 0x0000 -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef AT_STATX_FORCE_SYNC -#define AT_STATX_FORCE_SYNC 0x2000 -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef AT_STATX_DONT_SYNC -#define AT_STATX_DONT_SYNC 0x4000 -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_TYPE -#define STATX_TYPE 0x00000001U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_MODE -#define STATX_MODE 0x00000002U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_NLINK -#define STATX_NLINK 0x00000004U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_UID -#define STATX_UID 0x00000008U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_GID -#define STATX_GID 0x00000010U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_ATIME -#define STATX_ATIME 0x00000020U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_MTIME -#define STATX_MTIME 0x00000040U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_CTIME -#define STATX_CTIME 0x00000080U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_INO -#define STATX_INO 0x00000100U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_SIZE -#define STATX_SIZE 0x00000200U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_BLOCKS -#define STATX_BLOCKS 0x00000400U -#endif - -/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ -#ifndef STATX_BTIME -#define STATX_BTIME 0x00000800U -#endif - -/* fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60 (5.8) */ -#ifndef STATX_MNT_ID -#define STATX_MNT_ID 0x00001000U -#endif - -/* 80340fe3605c0e78cfe496c3b3878be828cfdbfe (5.8) */ -#ifndef STATX_ATTR_MOUNT_ROOT -#define STATX_ATTR_MOUNT_ROOT 0x00002000 /* Root of a mount */ -#endif diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h index f4eb4dd57b2..3eab1a27efa 100644 --- a/src/basic/missing_syscall.h +++ b/src/basic/missing_syscall.h @@ -19,7 +19,6 @@ #include "macro.h" #include "missing_keyctl.h" #include "missing_sched.h" -#include "missing_stat.h" #include "missing_syscall_def.h" /* ======================================================================= */ @@ -223,28 +222,6 @@ static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) { /* ======================================================================= */ -#if !HAVE_STATX -struct statx; - -static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer) { -# ifdef __NR_statx - return syscall(__NR_statx, dfd, filename, flags, mask, buffer); -# else - errno = ENOSYS; - return -1; -# endif -} -#endif - -/* This typedef is supposed to be always defined. */ -typedef struct statx struct_statx; - -#if !HAVE_STATX -# define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer) -#endif - -/* ======================================================================= */ - #if !HAVE_SET_MEMPOLICY enum { MPOL_DEFAULT, diff --git a/src/basic/missing_syscall_def.h b/src/basic/missing_syscall_def.h index 48116fc0f7c..e042b6be880 100644 --- a/src/basic/missing_syscall_def.h +++ b/src/basic/missing_syscall_def.h @@ -1333,71 +1333,3 @@ assert_cc(__NR_setxattrat == systemd_NR_setxattrat); # endif # endif #endif - -#ifndef __IGNORE_statx -# if defined(__aarch64__) -# define systemd_NR_statx 291 -# elif defined(__alpha__) -# define systemd_NR_statx 522 -# elif defined(__arc__) || defined(__tilegx__) -# define systemd_NR_statx 291 -# elif defined(__arm__) -# define systemd_NR_statx 397 -# elif defined(__i386__) -# define systemd_NR_statx 383 -# elif defined(__ia64__) -# define systemd_NR_statx 1350 -# elif defined(__loongarch_lp64) -# define systemd_NR_statx 291 -# elif defined(__m68k__) -# define systemd_NR_statx 379 -# elif defined(_MIPS_SIM) -# if _MIPS_SIM == _MIPS_SIM_ABI32 -# define systemd_NR_statx 4366 -# elif _MIPS_SIM == _MIPS_SIM_NABI32 -# define systemd_NR_statx 6330 -# elif _MIPS_SIM == _MIPS_SIM_ABI64 -# define systemd_NR_statx 5326 -# else -# error "Unknown MIPS ABI" -# endif -# elif defined(__hppa__) -# define systemd_NR_statx 349 -# elif defined(__powerpc__) -# define systemd_NR_statx 383 -# elif defined(__riscv) -# if __riscv_xlen == 32 -# define systemd_NR_statx 291 -# elif __riscv_xlen == 64 -# define systemd_NR_statx 291 -# else -# error "Unknown RISC-V ABI" -# endif -# elif defined(__s390__) -# define systemd_NR_statx 379 -# elif defined(__sparc__) -# define systemd_NR_statx 360 -# elif defined(__x86_64__) -# if defined(__ILP32__) -# define systemd_NR_statx (332 | /* __X32_SYSCALL_BIT */ 0x40000000) -# else -# define systemd_NR_statx 332 -# endif -# elif !defined(missing_arch_template) -# warning "statx() syscall number is unknown for your architecture" -# endif - -/* may be an (invalid) negative number due to libseccomp, see PR 13319 */ -# if defined __NR_statx && __NR_statx >= 0 -# if defined systemd_NR_statx -assert_cc(__NR_statx == systemd_NR_statx); -# endif -# else -# if defined __NR_statx -# undef __NR_statx -# endif -# if defined systemd_NR_statx && systemd_NR_statx >= 0 -# define __NR_statx systemd_NR_statx -# endif -# endif -#endif diff --git a/src/basic/missing_syscalls.py b/src/basic/missing_syscalls.py index d0e9d7dec4b..e84e0afc202 100644 --- a/src/basic/missing_syscalls.py +++ b/src/basic/missing_syscalls.py @@ -25,7 +25,6 @@ SYSCALLS = [ 'renameat2', 'setns', 'setxattrat', - 'statx', ] def dictify(f): diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index d366b3aa51e..e59a748df03 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -16,7 +16,6 @@ #include "missing_fcntl.h" #include "missing_fs.h" #include "missing_mount.h" -#include "missing_stat.h" #include "missing_syscall.h" #include "mkdir.h" #include "mountpoint-util.h" @@ -261,8 +260,7 @@ int is_mount_point_at(int fd, const char *filename, int flags) { * with a variety of st_dev reported. Also, btrfs subvolumes have different st_dev, even though * they aren't real mounts of their own. */ - STRUCT_STATX_DEFINE(sx); - + struct statx sx = {}; /* explicitly initialize the struct to make msan silent. */ if (statx(fd, filename, at_flags_normalize_nofollow(flags) | AT_NO_AUTOMOUNT | /* don't trigger automounts – mounts are a local concept, hence no need to trigger automounts to determine STATX_ATTR_MOUNT_ROOT */ @@ -401,7 +399,7 @@ int path_get_mnt_id_at_fallback(int dir_fd, const char *path, int *ret) { } int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) { - STRUCT_NEW_STATX_DEFINE(buf); + struct statx sx; assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(ret); @@ -412,7 +410,7 @@ int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) { AT_NO_AUTOMOUNT | /* don't trigger automounts, mnt_id is a local concept */ AT_STATX_DONT_SYNC, /* don't go to the network, mnt_id is a local concept */ STATX_MNT_ID, - &buf.sx) < 0) { + &sx) < 0) { if (!ERRNO_IS_NOT_SUPPORTED(errno) && /* statx() is not supported by the kernel. */ !ERRNO_IS_PRIVILEGE(errno) && /* maybe filtered by seccomp. */ errno != EINVAL) /* glibc's fallback method returns EINVAL when AT_STATX_DONT_SYNC is set. */ @@ -421,8 +419,8 @@ int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) { /* Fall back to name_to_handle_at() and then fdinfo if statx is not supported or we lack * privileges */ - } else if (FLAGS_SET(buf.nsx.stx_mask, STATX_MNT_ID)) { - *ret = buf.nsx.stx_mnt_id; + } else if (FLAGS_SET(sx.stx_mask, STATX_MNT_ID)) { + *ret = sx.stx_mnt_id; return 0; } diff --git a/src/basic/recurse-dir.c b/src/basic/recurse-dir.c index 4ff55032cc8..18e06551681 100644 --- a/src/basic/recurse-dir.c +++ b/src/basic/recurse-dir.c @@ -151,7 +151,7 @@ int recurse_dir( void *userdata) { _cleanup_free_ DirectoryEntries *de = NULL; - STRUCT_STATX_DEFINE(root_sx); + struct statx root_sx; int r; assert(dir_fd >= 0); @@ -193,7 +193,7 @@ int recurse_dir( for (size_t i = 0; i < de->n_entries; i++) { _cleanup_close_ int inode_fd = -EBADF, subdir_fd = -EBADF; _cleanup_free_ char *joined = NULL; - STRUCT_STATX_DEFINE(sx); + struct statx sx; bool sx_valid = false; const char *p; diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 10bd7c0fe17..687b7b2ddcf 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -470,8 +470,8 @@ bool statx_inode_same(const struct statx *a, const struct statx *b) { a->stx_ino == b->stx_ino; } -bool statx_mount_same(const struct new_statx *a, const struct new_statx *b) { - if (!new_statx_is_set(a) || !new_statx_is_set(b)) +bool statx_mount_same(const struct statx *a, const struct statx *b) { + if (!statx_is_set(a) || !statx_is_set(b)) return false; /* if we have the mount ID, that's all we need */ diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h index 7556f8f59a6..f7c926e9f80 100644 --- a/src/basic/stat-util.h +++ b/src/basic/stat-util.h @@ -11,7 +11,6 @@ #include "fs-util.h" #include "macro.h" -#include "missing_stat.h" #include "siphash24.h" #include "time-util.h" @@ -90,31 +89,12 @@ bool stat_inode_same(const struct stat *a, const struct stat *b); bool stat_inode_unmodified(const struct stat *a, const struct stat *b); bool statx_inode_same(const struct statx *a, const struct statx *b); -bool statx_mount_same(const struct new_statx *a, const struct new_statx *b); +bool statx_mount_same(const struct statx *a, const struct statx *b); int statx_fallback(int dfd, const char *path, int flags, unsigned mask, struct statx *sx); int xstatfsat(int dir_fd, const char *path, struct statfs *ret); -#if HAS_FEATURE_MEMORY_SANITIZER -# warning "Explicitly initializing struct statx, to work around msan limitation. Please remove as soon as msan has been updated to not require this." -# define STRUCT_STATX_DEFINE(var) \ - struct statx var = {} -# define STRUCT_NEW_STATX_DEFINE(var) \ - union { \ - struct statx sx; \ - struct new_statx nsx; \ - } var = {} -#else -# define STRUCT_STATX_DEFINE(var) \ - struct statx var -# define STRUCT_NEW_STATX_DEFINE(var) \ - union { \ - struct statx sx; \ - struct new_statx nsx; \ - } var -#endif - static inline usec_t statx_timestamp_load(const struct statx_timestamp *ts) { return timespec_load(&(const struct timespec) { .tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec }); } @@ -140,6 +120,3 @@ static inline bool stat_is_set(const struct stat *st) { static inline bool statx_is_set(const struct statx *sx) { return sx && sx->stx_mask != 0; } -static inline bool new_statx_is_set(const struct new_statx *sx) { - return sx && sx->stx_mask != 0; -} diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c index a43f795f0f2..b2ff1bcb329 100644 --- a/src/basic/xattr-util.c +++ b/src/basic/xattr-util.c @@ -379,7 +379,7 @@ int getcrtime_at( usec_t *ret) { _cleanup_free_ le64_t *le = NULL; - STRUCT_STATX_DEFINE(sx); + struct statx sx; usec_t a, b; int r; diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index f830d6dfe32..9b6517f53d3 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -273,8 +273,7 @@ static int verify_fsroot_dir( bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING), unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE); _cleanup_free_ char *f = NULL; - STRUCT_NEW_STATX_DEFINE(sxa); - STRUCT_NEW_STATX_DEFINE(sxb); + struct statx sxa, sxb; int r; /* Checks if the specified directory is at the root of its file system, and returns device @@ -292,21 +291,21 @@ static int verify_fsroot_dir( return log_error_errno(r, "Failed to extract filename of %s: %m", path); r = statx_fallback(dir_fd, strempty(f), AT_SYMLINK_NOFOLLOW|(isempty(f) ? AT_EMPTY_PATH : 0), - STATX_TYPE|STATX_INO|STATX_MNT_ID, &sxa.sx); + STATX_TYPE|STATX_INO|STATX_MNT_ID, &sxa); if (r < 0) return log_full_errno((searching && r == -ENOENT) || (unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR, r, "Failed to determine block device node of \"%s\": %m", path); - assert(S_ISDIR(sxa.sx.stx_mode)); /* We used O_DIRECTORY above, when opening, so this must hold */ + assert(S_ISDIR(sxa.stx_mode)); /* We used O_DIRECTORY above, when opening, so this must hold */ - if (FLAGS_SET(sxa.sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) { + if (FLAGS_SET(sxa.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) { /* If we have STATX_ATTR_MOUNT_ROOT, we are happy, that's all we need. We operate under the * assumption that a top of a mount point is also the top of the file system. (Which of * course is strictly speaking not always true...) */ - if (!FLAGS_SET(sxa.sx.stx_attributes, STATX_ATTR_MOUNT_ROOT)) + if (!FLAGS_SET(sxa.stx_attributes, STATX_ATTR_MOUNT_ROOT)) return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), "Directory \"%s\" is not the root of the file system.", path); @@ -315,15 +314,15 @@ static int verify_fsroot_dir( } /* Now let's look at the parent */ - r = statx_fallback(dir_fd, "", AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &sxb.sx); + r = statx_fallback(dir_fd, "", AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &sxb); if (r < 0) return log_full_errno(unprivileged_mode && ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_ERR, r, "Failed to determine block device node of parent of \"%s\": %m", path); - if (statx_inode_same(&sxa.sx, &sxb.sx)) /* for the root dir inode nr for both inodes will be the same */ + if (statx_inode_same(&sxa, &sxb)) /* for the root dir inode nr for both inodes will be the same */ goto success; - if (statx_mount_same(&sxa.nsx, &sxb.nsx)) + if (statx_mount_same(&sxa, &sxb)) return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), "Directory \"%s\" is not the root of the file system.", path); @@ -332,10 +331,10 @@ success: if (!ret_dev) return 0; - if (sxa.sx.stx_dev_major == 0) /* Hmm, maybe a btrfs device, and the caller asked for the backing device? Then let's try to get it. */ + if (sxa.stx_dev_major == 0) /* Hmm, maybe a btrfs device, and the caller asked for the backing device? Then let's try to get it. */ return btrfs_get_block_device_at(dir_fd, strempty(f), ret_dev); - *ret_dev = makedev(sxa.sx.stx_dev_major, sxa.sx.stx_dev_minor); + *ret_dev = makedev(sxa.stx_dev_major, sxa.stx_dev_minor); return 0; } diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 28108b81301..b3b50fc315d 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -564,7 +564,7 @@ static int opendir_and_stat( bool *ret_mountpoint) { _cleanup_closedir_ DIR *d = NULL; - STRUCT_NEW_STATX_DEFINE(st1); + struct statx sx1; int r; assert(path); @@ -591,24 +591,23 @@ static int opendir_and_stat( return 0; } - r = statx_fallback(dirfd(d), "", AT_EMPTY_PATH, STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME, &st1.sx); + r = statx_fallback(dirfd(d), "", AT_EMPTY_PATH, STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME, &sx1); if (r < 0) return log_error_errno(r, "statx(%s) failed: %m", path); - if (FLAGS_SET(st1.sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) - *ret_mountpoint = FLAGS_SET(st1.sx.stx_attributes, STATX_ATTR_MOUNT_ROOT); + if (FLAGS_SET(sx1.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) + *ret_mountpoint = FLAGS_SET(sx1.stx_attributes, STATX_ATTR_MOUNT_ROOT); else { - STRUCT_NEW_STATX_DEFINE(st2); - - r = statx_fallback(dirfd(d), "..", 0, STATX_INO, &st2.sx); + struct statx sx2; + r = statx_fallback(dirfd(d), "..", 0, STATX_INO, &sx2); if (r < 0) return log_error_errno(r, "statx(%s/..) failed: %m", path); - *ret_mountpoint = !statx_mount_same(&st1.nsx, &st2.nsx); + *ret_mountpoint = !statx_mount_same(&sx1, &sx2); } *ret = TAKE_PTR(d); - *ret_sx = st1.sx; + *ret_sx = sx1; return 1; } @@ -707,8 +706,7 @@ static int dir_cleanup( * systems such as overlayfs better where each file is originating from a different * st_dev. */ - STRUCT_STATX_DEFINE(sx); - + struct statx sx; r = statx_fallback( dirfd(d), de->d_name, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, @@ -2994,7 +2992,7 @@ static int remove_recursive( bool remove_instance) { _cleanup_closedir_ DIR *d = NULL; - STRUCT_STATX_DEFINE(sx); + struct statx sx; bool mountpoint; int r; @@ -3144,7 +3142,7 @@ static int clean_item_instance( usec_t cutoff = n - i->age; _cleanup_closedir_ DIR *d = NULL; - STRUCT_STATX_DEFINE(sx); + struct statx sx; bool mountpoint; int r;