#include <dirent.h>
#include <sched.h>
#include <sys/mount.h>
-#include <sys/stat.h>
#include <uchar.h>
'''
foreach decl : ['char16_t',
'char32_t',
'struct mount_attr',
- 'struct statx',
'struct dirent64',
'struct sched_attr',
]
endif
endif
- if decl == 'struct statx'
- if have
- want_linux_stat_h = false
- else
- have = cc.sizeof(decl,
- prefix : decl_headers + '#include <linux/stat.h>',
- 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']
#include <unistd.h>'''],
['bpf', '''#include <sys/syscall.h>
#include <unistd.h>'''],
- ['statx', '''#include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>'''],
['explicit_bzero' , '''#include <string.h>'''],
['reallocarray', '''#include <stdlib.h>'''],
['set_mempolicy', '''#include <stdlib.h>
#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);
}
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);
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);
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) {
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_STAT_H
+#define _LINUX_STAT_H
+
+#include <linux/types.h>
+
+#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 */
+++ /dev/null
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include <linux/types.h>
-#include <sys/stat.h>
-
-#if WANT_LINUX_STAT_H
-#include <linux/stat.h>
-#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
#include "macro.h"
#include "missing_keyctl.h"
#include "missing_sched.h"
-#include "missing_stat.h"
#include "missing_syscall_def.h"
/* ======================================================================= */
/* ======================================================================= */
-#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,
# 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
'renameat2',
'setns',
'setxattrat',
- 'statx',
]
def dictify(f):
#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"
* 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 */
}
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);
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. */
/* 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;
}
void *userdata) {
_cleanup_free_ DirectoryEntries *de = NULL;
- STRUCT_STATX_DEFINE(root_sx);
+ struct statx root_sx;
int r;
assert(dir_fd >= 0);
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;
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 */
#include "fs-util.h"
#include "macro.h"
-#include "missing_stat.h"
#include "siphash24.h"
#include "time-util.h"
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 });
}
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;
-}
usec_t *ret) {
_cleanup_free_ le64_t *le = NULL;
- STRUCT_STATX_DEFINE(sx);
+ struct statx sx;
usec_t a, b;
int r;
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
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);
}
/* 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);
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;
}
bool *ret_mountpoint) {
_cleanup_closedir_ DIR *d = NULL;
- STRUCT_NEW_STATX_DEFINE(st1);
+ struct statx sx1;
int r;
assert(path);
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;
}
* 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,
bool remove_instance) {
_cleanup_closedir_ DIR *d = NULL;
- STRUCT_STATX_DEFINE(sx);
+ struct statx sx;
bool mountpoint;
int r;
usec_t cutoff = n - i->age;
_cleanup_closedir_ DIR *d = NULL;
- STRUCT_STATX_DEFINE(sx);
+ struct statx sx;
bool mountpoint;
int r;