tmpfiles: do not mandate STATX_ATIME and STATX_MTIME

Timestamps are not guaranteed to be set by `statx()`, and their presence
should not be asserted as a proxy to judge the kernel version. In
particular, `STATX_ATIME` is omitted from the return when querying a
file on a `noatime` superblock, causing spurious errors from tmpfiles.

Correctness analysis
====================

The timestamps produced by the `statx()` call in `opendir_and_stat()`
are only ever used once, in `clean_item_instance()` (lines 3148-3149)
as inputs to `dir_cleanup()`. Convert absent timestamps into
`NSEC_INFINITY` as per the previous commit.

Fixes #41227.
This commit is contained in:
Ivan Shapovalov
2026-04-06 22:53:00 +02:00
parent e18b75c3f1
commit 122de8d93d
+8 -4
View File
@@ -591,8 +591,8 @@ static int opendir_and_stat(
/* path= */ NULL,
AT_EMPTY_PATH,
/* xstatx_flags= */ 0,
STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME,
/* optional_mask= */ 0,
STATX_MODE|STATX_INO,
STATX_ATIME|STATX_MTIME,
STATX_ATTR_MOUNT_ROOT,
&sx);
if (r < 0)
@@ -3124,6 +3124,7 @@ static int clean_item_instance(
return 0;
usec_t cutoff = n - i->age;
nsec_t atime_nsec, mtime_nsec;
_cleanup_closedir_ DIR *d = NULL;
struct statx sx;
@@ -3134,6 +3135,9 @@ static int clean_item_instance(
if (r <= 0)
return r;
atime_nsec = FLAGS_SET(sx.stx_mask, STATX_ATIME) ? statx_timestamp_load_nsec(&sx.stx_atime) : NSEC_INFINITY;
mtime_nsec = FLAGS_SET(sx.stx_mask, STATX_MTIME) ? statx_timestamp_load_nsec(&sx.stx_mtime) : NSEC_INFINITY;
if (DEBUG_LOGGING) {
_cleanup_free_ char *ab_f = NULL, *ab_d = NULL;
@@ -3153,8 +3157,8 @@ static int clean_item_instance(
}
return dir_cleanup(c, i, instance, d,
statx_timestamp_load_nsec(&sx.stx_atime),
statx_timestamp_load_nsec(&sx.stx_mtime),
atime_nsec,
mtime_nsec,
cutoff * NSEC_PER_USEC,
sx.stx_dev_major, sx.stx_dev_minor,
mountpoint,