Merge pull request #13160 from owncloud/extstorage-ocbackendnopartfile

Disable part files for OC ext storage backend + s2s backend
This commit is contained in:
Morris Jobke 2015-01-16 13:38:59 +01:00
commit 0f0204ee35
1 changed files with 59 additions and 27 deletions

View File

@ -74,8 +74,16 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
return $this->createFileChunked($data);
}
// mark file as partial while uploading (ignored by the scanner)
$partFilePath = $this->path . '.ocTransferId' . rand() . '.part';
list($storage, ) = $this->fileView->resolvePath($this->path);
$needsPartFile = $this->needsPartFile($storage);
if ($needsPartFile) {
// mark file as partial while uploading (ignored by the scanner)
$partFilePath = $this->path . '.ocTransferId' . rand() . '.part';
} else {
// upload file directly as the final path
$partFilePath = $this->path;
}
try {
$putOkay = $this->fileView->file_put_contents($partFilePath, $data);
@ -123,19 +131,21 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
}
}
// rename to correct path
try {
$renameOkay = $this->fileView->rename($partFilePath, $this->path);
$fileExists = $this->fileView->file_exists($this->path);
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
$this->fileView->unlink($partFilePath);
throw new \Sabre\DAV\Exception('Could not rename part file to final file');
if ($needsPartFile) {
// rename to correct path
try {
$renameOkay = $this->fileView->rename($partFilePath, $this->path);
$fileExists = $this->fileView->file_exists($this->path);
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
$this->fileView->unlink($partFilePath);
throw new \Sabre\DAV\Exception('Could not rename part file to final file');
}
}
catch (\OCP\Files\LockNotAcquiredException $e) {
// the file is currently being written to by another process
throw new OC_Connector_Sabre_Exception_FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
catch (\OCP\Files\LockNotAcquiredException $e) {
// the file is currently being written to by another process
throw new OC_Connector_Sabre_Exception_FileLocked($e->getMessage(), $e->getCode(), $e);
}
// allow sync clients to send the mtime along in a header
@ -267,23 +277,30 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
}
if ($chunk_handler->isComplete()) {
list($storage, ) = $this->fileView->resolvePath($path);
$needsPartFile = $this->needsPartFile($storage);
try {
// we first assembly the target file as a part file
$partFile = $path . '/' . $info['name'] . '.ocTransferId' . $info['transferid'] . '.part';
$chunk_handler->file_assemble($partFile);
// here is the final atomic rename
$targetPath = $path . '/' . $info['name'];
$renameOkay = $this->fileView->rename($partFile, $targetPath);
$fileExists = $this->fileView->file_exists($targetPath);
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
// only delete if an error occurred and the target file was already created
if ($fileExists) {
$this->fileView->unlink($targetPath);
if ($needsPartFile) {
// we first assembly the target file as a part file
$partFile = $path . '/' . $info['name'] . '.ocTransferId' . $info['transferid'] . '.part';
$chunk_handler->file_assemble($partFile);
// here is the final atomic rename
$renameOkay = $this->fileView->rename($partFile, $targetPath);
$fileExists = $this->fileView->file_exists($targetPath);
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
// only delete if an error occurred and the target file was already created
if ($fileExists) {
$this->fileView->unlink($targetPath);
}
throw new \Sabre\DAV\Exception('Could not rename part file assembled from chunks');
}
throw new \Sabre\DAV\Exception('Could not rename part file assembled from chunks');
} else {
// assemble directly into the final file
$chunk_handler->file_assemble($targetPath);
}
// allow sync clients to send the mtime along in a header
@ -303,4 +320,19 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\
return null;
}
/**
* Returns whether a part file is needed for the given storage
* or whether the file can be assembled/uploaded directly on the
* target storage.
*
* @param \OCP\Files\Storage $storage storage to check
* @param bool true if the storage needs part file handling
*/
private function needsPartFile($storage) {
// TODO: in the future use ChunkHandler provided by storage
// and/or add method on Storage called "needsPartFile()"
return !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') &&
!$storage->instanceOfStorage('OC\Files\Storage\OwnCloud');
}
}