From: Ivan Shapovalov Date: Fri, 20 Mar 2026 15:45:07 +0000 (+0100) Subject: tmpfiles: do not mandate `STATX_ATIME` and `STATX_MTIME` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=122de8d93dbf496b0013c3aa3bc49a5dc6721ff8;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 2b1c612f5ce..baef92f7af5 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -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,