Repository navigation
Description
Hello,
We want to spread spaces over several filesystems under the POSIX root and add a new one when the previous is nearly full:
<root>/users/u0/<userId> <root>/projects/p0/<spaceId>
<root>/users/u1/<userId> <root>/projects/p1/<spaceId>
Each shard is its own mount, so it can be backed up, grown or replaced independently, and we avoid very large LUNs. We do not want hash-based pre-partitioning, because we cannot predict growth. The active shard is selected through the path templates (and for personal spaces, possibly from a per-user value such as an LDAP attribute):
STORAGE_USERS_POSIX_PERSONAL_SPACE_PATH_TEMPLATE=users/u1/{{.User.Id.OpaqueId}}
STORAGE_USERS_POSIX_GENERAL_SPACE_PATH_TEMPLATE=projects/p1/{{.SpaceId}}
Environment: OpenCloud 8.1.0 (reva v2.51.0), POSIX driver, default SCAN_FS=true, WATCH_FS=false. Related: #3434.
The problem
The driver assumes that a space root is a direct child of the static part of the template (the text before the first {{, templates.Base):
Ignorer.IsSpaceRoot(path)is true only iffilepath.Dir(path)isRoot + Base(personal)orRoot + Base(general).Lookup.GenerateSpaceIDdecides whether a personal space already exists from the path rendered with the current template.- The quick preload at startup (
warmupSpaceRootCache) also usesRoot + Base(template): it lists only that directory. It therefore warms the current shard quickly (for exampleusers/u1), but not the older ones.
An intermediate shard folder (u0, u1, p0, p1) breaks these assumptions: only the active shard is understood, and older shards are treated as ordinary content.
Confirmed by tests
- Duplicate personal space. After switching the active shard from
u0tou1, a user who already had a personal space onu0got a second one onu1once the gateway'screate_personal_spacecache entry for that user had expired.GenerateSpaceIDlooks only at the path rendered with the current template, so the existing space onu0is not found. - Internal folders exposed. After the initial FS scan, internal folders such as
.oc-nodesand.Trashappear as ordinary folders in the web interface, in personal and project spaces that are not recognized as space roots (non-active shards). The ignore rules for them depend onIsSpaceRoot.
Creating spaces and uploading/deleting files on the active and older shards otherwise works.
Proposal
Make intermediate folders a normal part of the layout, with a self-describing marker:
- Marker xattr on shard folders. A folder such as
users/u0carries a custom xattr (for exampleuser.oc.space-container=1), set by the operator or by the driver when it creates a space under a template with intermediate levels. The driver treats the children of a marked folder as space roots, and treats the marked folder itself as a container, not as user content. This keeps existing templates working and keeps older shards recognized after a template change. - Quick preload driven by the template and the markers. Keep the fast preload of the current shard from the template, and also warm quickly the marked shard folders, so every shard is preloaded and not just the active one.
- Cross-shard lookup when creating a personal space. Before generating a new space ID, check whether the owner already has a personal space (user-space index or ID cache) and return
ALREADY_EXISTSregardless of the rendered path. - Same recognition for ignore rules, so
.oc-nodes,.Trashand.oc-tmpstay hidden in every recognized space on every shard. - Parallel and manual scans. Allow running
opencloud posixfs scan <path>manually, per shard or per space and in parallel, with the same marker-based recognition, and allow disabling the initial FS scan (SCAN_FS=false) while keeping the quick preload. The initial scan walks the whole root at every start, which is long compared with the quick preload and affects startup performance. It also risks data incoherence when user modifications happen during the walk (the walk stops on the first error, and partial tree sizes are still written).
Questions
- Is "space roots are direct children of the static template prefix" an intentional constraint?
- Would a marker-xattr approach (or detecting space roots from their own
user.oc.space.id) be acceptable? - Is there a recommended pattern today for spreading spaces over several filesystems?
Thank you for your work
Activity