Yes. statvfs()
works for this case also. At the same time, it avoids blocking on the FUSE filesystem.
$ mkdir mnt
$ bindfs --no-allow-other mnt mnt
$ stat -f mnt
File: "mnt"
ID: 0 Namelen: 255 Type: fuseblk
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 78150265 Free: 8223357 Available: 4722313
Inodes: Total: 19857408 Free: 18558102
$ strace stat -f mnt
...
statfs("mnt", {f_type=FUSE_SUPER_MAGIC, f_bsize=0, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=0, f_frsize=0, f_flags=ST_VALID|ST_NOSUID|ST_NODEV|ST_RELATIME}) = 0
...
File: "mnt"
ID: 0 Namelen: 0 Type: fuseblk
Block size: 0 Fundamental block size: 0
Blocks: Total: 0 Free: 0 Available: 0
Inodes: Total: 0 Free: 0
+++ exited with 0 +++
statvfs()
is explicitly documented as not requiring access to the target directory, only the parents.
EACCES (statvfs()) Search permission is denied for a component of the
path prefix of path. (See also path_resolution(7).)
Unfortunately your process of re-mounting does have a race condition, that cannot be fixed if you cannot open the target directory. Note O_PATH
lets you open directories without requiring any permission on the directory itself. (O_PATH
fds can then be addressed as a path using /proc/self/fd/%d
, including by mount()
).