Quota: maxTotalBytes measures the whole filesystem, and quota.enabled is ignored #497
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#497
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Status: from source (read at
bd006ef, not reproduced). Line numbers atbd006ef.What happens
maxTotalBytesis checked asusage.Used >= instanceTotal(internal/storage/quota/quota.go:113–119). On POSIX,Usedis the whole filesystem's statfs usage,(Blocks − Bfree) × Bsize(internal/storage/posix/usage_unix.go:16–26) — not what is stored under the storage root.storage.quota.enabledonly gates a log line; the quota decorator is always installed with whatever limits are set (cmd/cairnd/main.go:578–595atbd006ef).Impact
On a volume shared with anything else (the OS disk, other services, a NAS),
maxTotalByteseither blocks every write from the start or never triggers. cairn-desktop's integration tests had to useperUserBytesfor the quota scenario for this reason. Settingenabled: falsedoes not disable quotas, which surprises operators.Suggested fix
Measure usage under the storage root (a cached walk, as
perUserBytesalready does), or rename and document the setting as a filesystem-level floor. Honourenabled: falseby not installing the decorator.Found while building the cairn-desktop integration tests (phase 2, Cordy/cairn-desktop#29 scenario 9). Filed by Claude on behalf of @Cordy.
Shipped in v0.6.170 (PR #505), live on both dogfoods (
cairn_build_info{version="v0.6.170"}verified).What landed:
maxTotalBytesnow measures the bytes stored under the storage root — the same cached tree walk the per-user cap uses (~30s TTL, so enforcement can lag a burst of writes by up to that window; each accepted write also updates the cache incrementally). It no longer reads the filesystem's statfs, so on a shared volume the cap neither trips on other tenants' data nor stays blind when the disk is huge. Works on every backend — noUsagerneeded any more.Usage()reports Used as the under-root figure (Total = the cap), so the meter and the enforcement agree.reserveBytesis unchanged by design — it stays a statfs free-space floor ("don't fill the disk"), which genuinely is about the whole filesystem.storage.quota.enabled: falsenow really disables enforcement: the field is tri-state (*bool); explicitfalsekeeps the quota decorator out of the storage chain entirely, and admin-set caps are inert until re-enabled. Leaving the setting out keeps the always-installed behaviour from #178.TDD:
TestInstanceCapMeasuresUnderRoot/TestInstanceCapIgnoresSharedDiskUsage/TestInstanceCapUsageReportsUnderRootwitnessed red on the runner against the old statfs check;TestMaxTotalBytes(statfs semantics) retired, the no-Usagerguard test retargeted atreserveBytesonly; newTestQuotaEnabledTriStatecovers absent-vs-false config parsing.