aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2023-03-27 17:44:33 +0200
committerRobin Appelman <robin@icewind.nl>2023-04-03 18:28:29 +0200
commitd63fa2d9914b1629ce5f5cba0950ac5e27cebc00 (patch)
tree0f4eaf83a88f291d50959a0e0bb518ae2c34b60b /lib
parent5024f295dcfdf850d2d95f419bcf122bf08be5c8 (diff)
downloadnextcloud-server-d63fa2d9914b1629ce5f5cba0950ac5e27cebc00.tar.gz
nextcloud-server-d63fa2d9914b1629ce5f5cba0950ac5e27cebc00.zip
improve objectstore rmdir handling
remove folder entries as they are cleared instead of in one go afterwards otherwise they stick around if some of the child entries can't be removed Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Files/ObjectStore/ObjectStoreStorage.php86
1 files changed, 50 insertions, 36 deletions
diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index 4ca00cf6a16..8ca5cf53d16 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -27,6 +27,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Files\ObjectStore;
use Aws\S3\Exception\S3Exception;
@@ -177,63 +178,65 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
public function rmdir($path) {
$path = $this->normalizePath($path);
+ $entry = $this->getCache()->get($path);
- if (!$this->is_dir($path)) {
- return false;
- }
-
- if (!$this->rmObjects($path)) {
+ if (!$entry || $entry->getMimeType() !== ICacheEntry::DIRECTORY_MIMETYPE) {
return false;
}
- $this->getCache()->remove($path);
-
- return true;
+ return $this->rmObjects($entry);
}
- private function rmObjects($path) {
- $children = $this->getCache()->getFolderContents($path);
+ private function rmObjects(ICacheEntry $entry): bool {
+ $children = $this->getCache()->getFolderContentsById($entry->getId());
foreach ($children as $child) {
- if ($child['mimetype'] === 'httpd/unix-directory') {
- if (!$this->rmObjects($child['path'])) {
+ if ($child->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
+ if (!$this->rmObjects($child)) {
return false;
}
} else {
- if (!$this->unlink($child['path'])) {
+ if (!$this->rmObject($child)) {
return false;
}
}
}
+ $this->getCache()->remove($entry->getPath());
+
return true;
}
public function unlink($path) {
$path = $this->normalizePath($path);
- $stat = $this->stat($path);
+ $entry = $this->getCache()->get($path);
- if ($stat && isset($stat['fileid'])) {
- if ($stat['mimetype'] === 'httpd/unix-directory') {
- return $this->rmdir($path);
- }
- try {
- $this->objectStore->deleteObject($this->getURN($stat['fileid']));
- } catch (\Exception $ex) {
- if ($ex->getCode() !== 404) {
- $this->logger->logException($ex, [
- 'app' => 'objectstore',
- 'message' => 'Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path,
- ]);
- return false;
- }
- //removing from cache is ok as it does not exist in the objectstore anyway
+ if ($entry instanceof ICacheEntry) {
+ if ($entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
+ return $this->rmObjects($entry);
+ } else {
+ return $this->rmObject($entry);
}
- $this->getCache()->remove($path);
- return true;
}
return false;
}
+ public function rmObject(ICacheEntry $entry): bool {
+ try {
+ $this->objectStore->deleteObject($this->getURN($entry->getId()));
+ } catch (\Exception $ex) {
+ if ($ex->getCode() !== 404) {
+ $this->logger->logException($ex, [
+ 'app' => 'objectstore',
+ 'message' => 'Could not delete object ' . $this->getURN($entry->getId()) . ' for ' . $entry->getPath(),
+ ]);
+ return false;
+ }
+ //removing from cache is ok as it does not exist in the objectstore anyway
+ }
+ $this->getCache()->remove($entry->getPath());
+ return true;
+ }
+
public function stat($path) {
$path = $this->normalizePath($path);
$cacheEntry = $this->getCache()->get($path);
@@ -557,7 +560,12 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
return $this->objectStore;
}
- public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
+ public function copyFromStorage(
+ IStorage $sourceStorage,
+ $sourceInternalPath,
+ $targetInternalPath,
+ $preserveMtime = false
+ ) {
if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
/** @var ObjectStoreStorage $sourceStorage */
if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
@@ -645,7 +653,13 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
*
* @throws GenericFileException
*/
- public function putChunkedWritePart(string $targetPath, string $writeToken, string $chunkId, $data, $size = null): ?array {
+ public function putChunkedWritePart(
+ string $targetPath,
+ string $writeToken,
+ string $chunkId,
+ $data,
+ $size = null
+ ): ?array {
if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
throw new GenericFileException('Object store does not support multipart upload');
}
@@ -656,7 +670,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
$parts[$chunkId] = [
'PartNumber' => $chunkId,
- 'ETag' => trim($result->get('ETag'), '"')
+ 'ETag' => trim($result->get('ETag'), '"'),
];
return $parts[$chunkId];
}
@@ -680,11 +694,11 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
$stat['mimetype'] = $this->getMimeType($targetPath);
$this->getCache()->update($stat['fileid'], $stat);
}
- } catch (S3MultipartUploadException | S3Exception $e) {
+ } catch (S3MultipartUploadException|S3Exception $e) {
$this->objectStore->abortMultipartUpload($urn, $writeToken);
$this->logger->logException($e, [
'app' => 'objectstore',
- 'message' => 'Could not compete multipart upload ' . $urn. ' with uploadId ' . $writeToken
+ 'message' => 'Could not compete multipart upload ' . $urn . ' with uploadId ' . $writeToken,
]);
throw new GenericFileException('Could not write chunked file');
}