Skip to content

fix(files): do not reject ownership transfer when free space is unlimited - #64020

Open
jo23sh wants to merge 1 commit into
nextcloud:masterfrom
jo23sh:fix/transfer-ownership-free-space-sentinel
Open

fix(files): do not reject ownership transfer when free space is unlimited#64020
jo23sh wants to merge 1 commit into
nextcloud:masterfrom
jo23sh:fix/transfer-ownership-free-space-sentinel

Conversation

@jo23sh

@jo23sh jo23sh commented Sep 4, 2026

Copy link
Copy Markdown

Fixes #64019

The quota check in analyse() exempted only SPACE_UNKNOWN (-2), but free_space() also returns SPACE_UNLIMITED (-3). A quota-less user on object-store primary storage gets -3, so $size > -3 was true for any non-empty source and the transfer aborted with "Target user does not have enough free space available."

Exempt SPACE_UNLIMITED as well. SPACE_NOT_COMPUTED (-1) keeps rejecting: Quota::free_space() returns it when a quota is set but the used size could not be read, so there is a finite limit that should still be respected.

…ited

View::free_space() can return negative sentinels (SPACE_UNKNOWN, SPACE_UNLIMITED,
SPACE_NOT_COMPUTED) instead of an amount of free space. The quota check in
analyse() exempted only SPACE_UNKNOWN, so SPACE_UNLIMITED (-3) fell through the
guard: `$size > -3` is true for any non-empty source, and the transfer aborted
with "Target user does not have enough free space available."

This is reachable on instances using object storage as primary storage, where
ObjectStoreStorage::free_space() returns SPACE_UNLIMITED unless a totalSizeLimit
is configured, and Quota::free_space() passes that through unchanged for a
destination user with no quota set. The transfer then fails precisely because
the target has unlimited space.

Exempt SPACE_UNLIMITED alongside SPACE_UNKNOWN. SPACE_NOT_COMPUTED (-1) keeps
rejecting: Quota::free_space() returns it when a quota is set but the used size
could not be read, so there is a finite limit that should still be respected.

Signed-off-by: Josua Hunziker <josh@o23.ch>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jo23sh
jo23sh requested a review from a team as a code owner September 4, 2026 12:21
@jo23sh
jo23sh requested review from CarlSchwan, leftybournes, salmart-dev and sorbaugh and removed request for a team September 4, 2026 12:21
// A negative return value is a sentinel (SPACE_UNKNOWN, SPACE_UNLIMITED or
// SPACE_NOT_COMPUTED) rather than an amount of free space, so there is no
// finite limit to compare the size against.
if ($freeSpace >= 0 && $size > $freeSpace) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should allow SPACE_NOT_COMPUTED as this could mean this overflows the quota, no?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, you're right. Quota::free_space() only returns SPACE_NOT_COMPUTED on the branch where a quota is set and the cached size couldn't be read — so it means "there is a limit, headroom unknown", not "no limit". Amended to exempt only SPACE_UNKNOWN and SPACE_UNLIMITED.

Side note: the quota wrapper itself treats any negative as "allow" (copy(), moveFromStorage(), fopen()), so -1 isn't enforced downstream either — but failing closed in the pre-check is cheap.

@jo23sh
jo23sh force-pushed the fix/transfer-ownership-free-space-sentinel branch from 0e73553 to 4131c46 Compare September 5, 2026 05:49
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.

files:transfer-ownership fails with "not enough free space" when the target quota is unlimited

2 participants