diff options
author | Robin Appelman <robin@icewind.nl> | 2025-04-03 17:26:09 +0200 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2025-05-08 15:19:40 +0200 |
commit | 99364adc1c69bd124d332ac6178138fec4c88297 (patch) | |
tree | 54126c5244d45959c529f8a299466c7a1abe13f3 | |
parent | 1228cfd3a2dfb3320e071f5ff26a1bb78574f62c (diff) | |
download | nextcloud-server-newfolder-race-improvements.tar.gz nextcloud-server-newfolder-race-improvements.zip |
fix: improve handling of newFolder race condition handlingnewfolder-race-improvements
Signed-off-by: Robin Appelman <robin@icewind.nl>
-rw-r--r-- | lib/private/Files/Node/Folder.php | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php index a894c69649a..16365948031 100644 --- a/lib/private/Files/Node/Folder.php +++ b/lib/private/Files/Node/Folder.php @@ -126,8 +126,21 @@ class Folder extends Node implements \OCP\Files\Folder { $fullPath = $this->getFullPath($path); $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath); $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]); - if (!$this->view->mkdir($fullPath) && !$this->view->is_dir($fullPath)) { - throw new NotPermittedException('Could not create folder "' . $fullPath . '"'); + if (!$this->view->mkdir($fullPath)) { + // maybe another concurrent process created the folder already + if (!$this->view->is_dir($fullPath)) { + throw new NotPermittedException('Could not create folder "' . $fullPath . '"'); + } else { + // we need to ensure we don't return before the concurrent request has finished updating the cache + $tries = 5; + while (!$this->view->getFileInfo($fullPath)) { + if ($tries < 1) { + throw new NotPermittedException('Could not create folder "' . $fullPath . '", folder exists but unable to get cache entry'); + } + usleep(5 * 1000); + $tries--; + } + } } $parent = dirname($fullPath) === $this->getPath() ? $this : null; $node = new Folder($this->root, $this->view, $fullPath, null, $parent); |