basic/stat-util: avoid access syscall

I was looking at strace for systemd-getty-generator and noticed the call to
faccessat2(3</sys>, "", W_OK, AT_EMPTY_PATH), even though we already did
fstatfs(3</sys>), which should give us all the necessary information. Let's
only do this additional check when it's likely to yield something useful, i.e.
for network fses and otherwise skip the syscall.

The call to statvfs is replaced by statfs because that gives us the .f_type
field and allows is_network_fs() to be called.

I'm a bit worried that the is_network_fs() is somewhat costly. This will be
improved in later commits.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2025-07-24 15:09:58 +02:00
parent 9154cc7e80
commit c136be3f04

View File

@@ -220,20 +220,22 @@ int null_or_empty_path_with_root(const char *fn, const char *root) {
}
int fd_is_read_only_fs(int fd) {
struct statvfs st;
struct statfs st;
assert(fd >= 0);
if (fstatvfs(fd, &st) < 0)
if (fstatfs(fd, &st) < 0)
return -errno;
if (st.f_flag & ST_RDONLY)
if (st.f_flags & ST_RDONLY)
return true;
/* On NFS, fstatvfs() might not reflect whether we can actually write to the remote share. Let's try
* again with access(W_OK) which is more reliable, at least sometimes. */
if (access_fd(fd, W_OK) == -EROFS)
return true;
if (is_network_fs(&st)) {
/* On NFS, fstatfs() might not reflect whether we can actually write to the remote share.
* Let's try again with access(W_OK) which is more reliable, at least sometimes. */
if (access_fd(fd, W_OK) == -EROFS)
return true;
}
return false;
}