mountpoint-util: use new kernel 5.8 statx() API for determining mnt_id
The kernel finally has a proper API to determine the mnt_id of a file. Let's use it. This adds support for the STATX_MNT_ID field of statx(), added in kernel 5.8.
This commit is contained in:
parent
ffaf45e4f3
commit
69b3fa14cd
|
@ -8,38 +8,47 @@
|
||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
/* Thew 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
|
#if !HAVE_STRUCT_STATX
|
||||||
struct statx_timestamp {
|
struct statx_timestamp {
|
||||||
__s64 tv_sec;
|
__s64 tv_sec;
|
||||||
__u32 tv_nsec;
|
__u32 tv_nsec;
|
||||||
__s32 __reserved;
|
__s32 __reserved;
|
||||||
};
|
};
|
||||||
struct statx {
|
|
||||||
__u32 stx_mask;
|
struct statx STATX_DEFINITION;
|
||||||
__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 __spare2[14];
|
|
||||||
};
|
|
||||||
#endif
|
#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) */
|
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||||
#ifndef STATX_BTIME
|
#ifndef STATX_BTIME
|
||||||
#define STATX_BTIME 0x00000800U
|
#define STATX_BTIME 0x00000800U
|
||||||
|
@ -49,3 +58,8 @@ struct statx {
|
||||||
#ifndef AT_STATX_DONT_SYNC
|
#ifndef AT_STATX_DONT_SYNC
|
||||||
#define AT_STATX_DONT_SYNC 0x4000
|
#define AT_STATX_DONT_SYNC 0x4000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60 (5.8) */
|
||||||
|
#ifndef STATX_MNT_ID
|
||||||
|
#define STATX_MNT_ID 0x00001000U
|
||||||
|
#endif
|
||||||
|
|
|
@ -482,7 +482,7 @@ static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flag
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
# define statx missing_statx
|
# define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !HAVE_SET_MEMPOLICY
|
#if !HAVE_SET_MEMPOLICY
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
|
#include "missing_stat.h"
|
||||||
|
#include "missing_syscall.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
@ -283,8 +285,29 @@ int path_is_mount_point(const char *t, const char *root, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int path_get_mnt_id(const char *path, int *ret) {
|
int path_get_mnt_id(const char *path, int *ret) {
|
||||||
|
union {
|
||||||
|
struct statx sx;
|
||||||
|
struct new_statx nsx;
|
||||||
|
} buf
|
||||||
|
#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."
|
||||||
|
#endif
|
||||||
|
;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (statx(AT_FDCWD, path, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_MNT_ID, &buf.sx) < 0) {
|
||||||
|
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0);
|
r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0);
|
||||||
if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */
|
if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */
|
||||||
return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret);
|
return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret);
|
||||||
|
|
Loading…
Reference in a new issue