Repository navigation
Re-shared external storage (SMB) not always rescanned for recipients #63253
Description
Steps to reproduce
- User A adds an SMB external storage mount.
- User A shares a folder from that mount directly with User B.
- Something changes on the SMB server outside of Nextcloud.
- User A browses the folder → gets rescanned correctly.
- User B browses the re-share → does not get rescanned (stale listing).
Root cause
SharedStorage::getWatcher() decides between a real Watcher and a
NullWatcher purely from string metadata on the share's cache entry:
https://github.com/nextcloud/server/blob/master/apps/files_sharing/lib/SharedStorage.php#L453-L477
$node = $this->getShare()->getNodeCacheEntry();
if ($node instanceof CacheEntry) {
$storageId = $node->getData()['storage_string_id'] ?? null;
if ($storageId !== null && !(str_starts_with($storageId, 'home::') || str_starts_with($storageId, 'object::user'))) {
// real watcher, rescans happen
}
}
// falls through here -> NullWatcher, rescans never happen
$this->watcher = new NullWatcher();getNodeCacheEntry() returns null, or a CacheEntry missing the
storage_string_id key, for several legitimate code paths:
DefaultShareProvider::getSharesBy()/getShareById()/getSharesByPath()
never populate a node cache entry at all (nofilecache/storagesjoin).- Even
DefaultShareProvider::_getSharedWith()(used for the normal
getMountsForUser/getMountsForPathmount setup) can come back without
storage_string_idif the source node wasn't infilecacheyet at
share-fetch time.
Whenever that happens, the code silently assumes "home storage" and installs
a NullWatcher, meaning the share never gets checked against the real
backend for the lifetime of that storage object/request.
This is the same fragile spot as #50235, which was patched defensively in
#50769 (?? null to avoid the crash) — that fixed the exception but left the
underlying "silently never rescan" behavior in place.
Suggested fix
Fall back to a live, deterministic check of the real underlying storage
($this->nonMaskedStorage->instanceOfStorage(IHomeStorage::class), after
$this->init()) when the cache-entry metadata is missing or incomplete,
instead of assuming home storage. This mirrors the existing fallback pattern
in SharedStorage::getSourceRootInfo(). A FailedStorage guard is needed so
a deleted owner / offline storage still safely yields NullWatcher.
I'm happy to submit a PR for this if the approach sounds right.
This issue has been created in cooperation with Claude Sonnet 5 but it has been reviewed and submitted by me - human.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriaged
Activity