Conversation
Move the non-blocking statx() based stat() alternative out of libmount,
so that other tools can use it too. lsfd needs it to avoid blocking on
hung filesystems.
ul_safe_statx() is the primitive; it adds AT_STATX_DONT_SYNC and
AT_NO_AUTOMOUNT (and AT_EMPTY_PATH for an empty path) to the caller's
flags, so there is one place that knows what "do not block" means.
ul_safe_stat() converts the result to struct stat. It's an improved
version of the original libmount code:
* the caller says what it needs by a statx(2) attribute mask, see
UL_STATX_{ESSENTIAL,BASIC}. These are plain statx masks, so they can
be composed, for example UL_STATX_ESSENTIAL | STATX_ATIME.
UL_STATX_ESSENTIAL is always added, so 0 is a valid request for the
minimum.
* ul_statx_to_stat() honours stx_mask. statx(2) is not obliged to
return everything we ask for, and with AT_STATX_DONT_SYNC that's
exactly the case we care about. The original code copied the fields
unconditionally, which could report garbage as a valid attribute.
* the optional @Retmask returns what the kernel really provided, so
the caller can tell which fields in the struct stat are usable.
* it fails with EOPNOTSUPP when the kernel does not provide the
essential attributes, so the caller can fall back to stat().
Both functions return 0 or a negative errno, and they set errno too.
ul_safe_statx() always zeroizes the struct statx, so the caller never
sees stale data on an error path. The HAVE_UL_SAFE_STAT{,X} macros hide
the HAVE_STATX, HAVE_STRUCT_STATX and AT_* feature tests from the
callers.
libmount's safe_stat() and get_mnt_id() now use the new functions. Note
that this changes mnt_id_from_path(), mnt_id_from_fd() and the internal
mnt_safe_stat()/mnt_safe_lstat() to return -errno rather than -1. All
in-tree callers only test for non-zero, and the public functions are
documented as "<0 on error" only.
get_mnt_id() honours stx_mask now too. The kernel silently ignores
unsupported mask bits rather than failing, so the old "errno == EINVAL"
probe for STATX_MNT_ID_UNIQUE never triggered; statx(2) returns EINVAL
only for STATX__RESERVED. On kernels older than 6.8 that made
mnt_id_from_path() report the legacy non-unique mount ID as if it were
the unique one. Both IDs are returned only when the kernel advertises
them in stx_mask, otherwise -ENOSYS -- which is what mnt_fs_fetch_ids()
already expects for its fallback to the old mount ID.
Add test_fileutils --safe-stat and tests/ts/misc/safe-stat. The stat
attributes differ between systems, so the test program does not print
them; it compares the ul_safe_stat() result with the classic stat() and
prints OK/FAILED per attribute. The reported attributes depend on the
requested mask only, not on how generous the kernel is.
Addresses: util-linux#4647
Signed-off-by: Karel Zak <kzak@redhat.com>
karelzak
force-pushed
the
PR/fileutils-safe-stat
branch
from
October 2, 2026 09:32
ca6ae96 to
052be81
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prerequisite split out of #4647 ("lsfd: do not block on hung file systems"),
so that @masatake can rebase on top of it and drop his first two commits.
Moves the non-blocking statx() based stat() alternative from libmount to
lib/fileutils.c, so that lsfd and others can use it too, and fixes the
original code to honour stx_mask.