Skip to content

fix(decomposedfs): tolerate a space root with an unset name attribute#713

Closed
michaelstingl wants to merge 1 commit into
opencloud-eu:mainfrom
michaelstingl:issue-1878-readnode-unset-name
Closed

fix(decomposedfs): tolerate a space root with an unset name attribute#713
michaelstingl wants to merge 1 commit into
opencloud-eu:mainfrom
michaelstingl:issue-1878-readnode-unset-name

Conversation

@michaelstingl

@michaelstingl michaelstingl commented Jun 28, 2026

Copy link
Copy Markdown

Description

ReadNode fails when a space root has no user.oc.name attribute, which happens for a half-deleted user space (the node lingers after the name attribute is gone). Reading the name returns ENODATA and aborts the read, which surfaces to the caller as code 15. The fix swallows the unset-name case in readNode the same way the owner lookup just above already does: match metadata.IsAttrUnset and keep the empty name. Any other read error still propagates.

Related Issue

Part of opencloud-eu/opencloud#1878

It stops the read crash for every ReadNode caller but does not clean up the orphaned index entries the half-deletion leaves behind, so it does not fully resolve the issue.

Motivation and Context

Two paths stat a space root through ReadNode and hit the failure: the search indexer's tree walk, which logs error while indexing a space on every pass, and ListStorageSpaces, which fails a listing by id outright. Fixing ReadNode at the root covers both, plus every other caller. StorageSpaceFromNode already tolerates a missing name downstream, so the nameless space flows through without a second failure.

How Has This Been Tested?

  • node_test.go: strip a space root's name attribute, ReadNode it, assert it returns the node with an empty name and Exists == true instead of erroring. Red without the change (the exact user.oc.name: no data available), green with it.
  • decomposedfs/node package green in a golang:1.25 container on ext4; gofmt, go vet, golangci-lint v2.10.1 clean.
  • e2e: after the shareInvitations.feature "deleted user" scenario, the error while indexing a space log lines drop from 4 to 0 on a patched build.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation added (n/a: reva builds the changelog from the PR title and Type:* label via ready-release-go, so no fragment is needed)

🤖 drafted with Claude Code, reviewed before submitting.

ReadNode failed with an internal error when a space root had no
user.oc.name attribute, which happens for a half-deleted user space
(its node lingers while the name attribute is already gone). Reading
the name with XattrString returned the ENODATA error and aborted the
read, which surfaces to the caller as code 15. The search service's
tree walk stats every space root through this path, so one such node
aborted the entire space index and logged "error while indexing a
space" on every run; any other ReadNode caller hit the same hard
failure.

Swallow the unset-name case the same way the owner lookup just above
already swallows a missing attribute: match metadata.IsAttrUnset and
keep the empty name instead of failing the read. Any other read error
keeps its existing behaviour, so a genuine read failure is not hidden.

Related: opencloud-eu/opencloud#1878
@michaelstingl

Copy link
Copy Markdown
Author

Closing this. It tolerates the symptom (a nameless space root) on read; it does not address the cause.

The root cause is in the hybrid metadata backend: locking an already-deleted space root materialises a node with no attributes (details in opencloud#1878). That is the layer to fix.

🤖 drafted with Claude Code, reviewed before submitting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant