diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-05-07 12:48:30 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-05-07 12:48:30 -0400 |
commit | 7129ed0ff069fde418773be313442beb0dacfaaf (patch) | |
tree | 89f1c19826a2a899a56da89fde9bf053a106e3a3 /src/stat.c | |
parent | 781b9eb78070872734c4e8303b3d02ae9e9c0f37 (diff) | |
download | bfs-7129ed0ff069fde418773be313442beb0dacfaaf.tar.xz |
stat: Prefer fstat(fd) to fstatat(fd, "", AT_EMPTY_PATH)
This lets us get rid of the runtime probe for AT_EMPTY_PATH support, and
should be more efficient anyway.
We still use statx(fd, "", AT_EMPTY_PATH) if available.
Link: https://lore.kernel.org/linux-fsdevel/CAHk-=wiYnnv7Kw7v+Cp2xU6_Fd-qxQMZuuxZ61LgA2=Gtftw-A@mail.gmail.com/
Diffstat (limited to 'src/stat.c')
-rw-r--r-- | src/stat.c | 32 |
1 files changed, 13 insertions, 19 deletions
@@ -297,27 +297,21 @@ int bfs_stat(int at_fd, const char *at_path, enum bfs_stat_flags flags, struct b return bfs_stat_tryfollow(at_fd, at_path, at_flags, flags, buf); } - // Check __GNU__ to work around https://lists.gnu.org/archive/html/bug-hurd/2021-12/msg00001.html -#if defined(AT_EMPTY_PATH) && !__GNU__ - static atomic bool has_at_ep = true; - if (load(&has_at_ep, relaxed)) { - at_flags |= AT_EMPTY_PATH; - int ret = bfs_stat_explicit(at_fd, "", at_flags, buf); - if (ret != 0 && errno == EINVAL) { - store(&has_at_ep, false, relaxed); - } else { - return ret; - } - } -#endif - - struct stat statbuf; - if (fstat(at_fd, &statbuf) == 0) { - bfs_stat_convert(buf, &statbuf); - return 0; - } else { +#if BFS_USE_STATX + // If we have statx(), use it with AT_EMPTY_PATH for its extra features + at_flags |= AT_EMPTY_PATH; + return bfs_stat_explicit(at_fd, "", at_flags, buf); +#else + // Otherwise, just use fstat() rather than fstatat(at_fd, ""), to save + // the kernel the trouble of copying in the empty string + struct stat sb; + if (fstat(at_fd, &sb) != 0) { return -1; } + + bfs_stat_convert(buf, &sb); + return 0; +#endif } const struct timespec *bfs_stat_time(const struct bfs_stat *buf, enum bfs_stat_field field) { |