fix(fuse,scripts): log why a create finds no parent and fit the metadata floor to FUSE

A create that answered ENOENT left no trace in the log. It now warns
when the parent folder is no longer known, and when the parent left the
tree while its children were being listed, naming the parent inode and
the new name.

The acceptance script's metadata throughput floor was 20 operations per
second, which a FUSE mount cannot reach: each create and unlink waits for
Drive before it returns, about 350 ms apiece. On a FUSE mount the floor
is now 3 operations per second; other paths keep 20. The mount type is
read from /proc/self/mountinfo.
This commit is contained in:
nvrl committed 2026-09-29 21:22:54 +02:00
1 parent 54e9921efb
commit cb38f79aa3
3 files changed
+33 -2

No files matched your search

+21 -1
View File
@@ -1357,9 +1357,15 @@ def test_throughput(ctx: Context) -> None:
reads of just-written data come from the cache, so neither should depend
on the network. PDFS_ACCEPTANCE_MIN_MIBPS and PDFS_ACCEPTANCE_MIN_OPS move
the floors; 0 turns one off.
Metadata is the exception. On a Drive mount each create and each unlink
waits for Drive before it returns (about 350 ms for a create), so 20
operations a second is out of reach there by design. The default floor for
a FUSE target is 3, which still catches a second round trip per operation.
"""
min_rate = float(os.environ.get("PDFS_ACCEPTANCE_MIN_MIBPS", "10"))
min_ops = float(os.environ.get("PDFS_ACCEPTANCE_MIN_OPS", "20"))
default_ops = "3" if is_fuse(ctx.root) else "20"
min_ops = float(os.environ.get("PDFS_ACCEPTANCE_MIN_OPS", default_ops))
root = ctx.root / "throughput"
root.mkdir()
chunk = pattern(MIB, "throughput")
@@ -3308,6 +3314,20 @@ def is_mountpoint(path: Path) -> bool:
return os.path.ismount(path)
def is_fuse(path: Path) -> bool:
"""True when `path` lives on a FUSE mount, read from /proc/self/mountinfo."""
path = path.resolve()
best, fstype = -1, ""
with open("/proc/self/mountinfo", encoding="utf-8") as mounts:
for line in mounts:
fields = line.split()
# Octal escapes (\040 for a space) are how mountinfo writes odd names.
point = Path(fields[4].encode().decode("unicode_escape"))
if (path == point or point in path.parents) and len(point.parts) > best:
best, fstype = len(point.parts), fields[fields.index("-") + 1]
return fstype.startswith("fuse")
def run_managed_matrix(
paths: list[Path], reference: Run, args, janitor: Janitor | None = None
) -> None: