Skip to content

Commit 1cd5ba3

Browse files
authored
Merge pull request #7144 from nextcloud/rename-locks-stable12
Unlock files even if an exception occurs (stable12)
2 parents b1b02d3 + f907cdc commit 1cd5ba3

File tree

1 file changed

+86
-83
lines changed

1 file changed

+86
-83
lines changed

lib/private/Files/View.php

Lines changed: 86 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -766,98 +766,101 @@ public function rename($path1, $path2) {
766766
$this->lockFile($path1, ILockingProvider::LOCK_SHARED, true);
767767
try {
768768
$this->lockFile($path2, ILockingProvider::LOCK_SHARED, true);
769-
} catch (LockedException $e) {
770-
$this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
771-
throw $e;
772-
}
773769

774-
$run = true;
775-
if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
776-
// if it was a rename from a part file to a regular file it was a write and not a rename operation
777-
$this->emit_file_hooks_pre($exists, $path2, $run);
778-
} elseif ($this->shouldEmitHooks($path1)) {
779-
\OC_Hook::emit(
780-
Filesystem::CLASSNAME, Filesystem::signal_rename,
781-
array(
782-
Filesystem::signal_param_oldpath => $this->getHookPath($path1),
783-
Filesystem::signal_param_newpath => $this->getHookPath($path2),
784-
Filesystem::signal_param_run => &$run
785-
)
786-
);
787-
}
788-
if ($run) {
789-
$this->verifyPath(dirname($path2), basename($path2));
790-
791-
$manager = Filesystem::getMountManager();
792-
$mount1 = $this->getMount($path1);
793-
$mount2 = $this->getMount($path2);
794-
$storage1 = $mount1->getStorage();
795-
$storage2 = $mount2->getStorage();
796-
$internalPath1 = $mount1->getInternalPath($absolutePath1);
797-
$internalPath2 = $mount2->getInternalPath($absolutePath2);
798-
799-
$this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true);
800-
$this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true);
801-
802-
if ($internalPath1 === '') {
803-
if ($mount1 instanceof MoveableMount) {
804-
if ($this->isTargetAllowed($absolutePath2)) {
805-
/**
806-
* @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
807-
*/
808-
$sourceMountPoint = $mount1->getMountPoint();
809-
$result = $mount1->moveMount($absolutePath2);
810-
$manager->moveMount($sourceMountPoint, $mount1->getMountPoint());
811-
} else {
812-
$result = false;
813-
}
814-
} else {
815-
$result = false;
816-
}
817-
// moving a file/folder within the same mount point
818-
} elseif ($storage1 === $storage2) {
819-
if ($storage1) {
820-
$result = $storage1->rename($internalPath1, $internalPath2);
821-
} else {
822-
$result = false;
823-
}
824-
// moving a file/folder between storages (from $storage1 to $storage2)
825-
} else {
826-
$result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
827-
}
828-
829-
if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
770+
$run = true;
771+
if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
830772
// if it was a rename from a part file to a regular file it was a write and not a rename operation
831-
832-
$this->writeUpdate($storage2, $internalPath2);
833-
} else if ($result) {
834-
if ($internalPath1 !== '') { // don't do a cache update for moved mounts
835-
$this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2);
836-
}
773+
$this->emit_file_hooks_pre($exists, $path2, $run);
774+
} elseif ($this->shouldEmitHooks($path1)) {
775+
\OC_Hook::emit(
776+
Filesystem::CLASSNAME, Filesystem::signal_rename,
777+
array(
778+
Filesystem::signal_param_oldpath => $this->getHookPath($path1),
779+
Filesystem::signal_param_newpath => $this->getHookPath($path2),
780+
Filesystem::signal_param_run => &$run
781+
)
782+
);
837783
}
784+
if ($run) {
785+
$this->verifyPath(dirname($path2), basename($path2));
838786

839-
$this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
840-
$this->changeLock($path2, ILockingProvider::LOCK_SHARED, true);
787+
$manager = Filesystem::getMountManager();
788+
$mount1 = $this->getMount($path1);
789+
$mount2 = $this->getMount($path2);
790+
$storage1 = $mount1->getStorage();
791+
$storage2 = $mount2->getStorage();
792+
$internalPath1 = $mount1->getInternalPath($absolutePath1);
793+
$internalPath2 = $mount2->getInternalPath($absolutePath2);
841794

842-
if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
843-
if ($this->shouldEmitHooks()) {
844-
$this->emit_file_hooks_post($exists, $path2);
795+
$this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true);
796+
try {
797+
$this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true);
798+
799+
if ($internalPath1 === '') {
800+
if ($mount1 instanceof MoveableMount) {
801+
if ($this->isTargetAllowed($absolutePath2)) {
802+
/**
803+
* @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
804+
*/
805+
$sourceMountPoint = $mount1->getMountPoint();
806+
$result = $mount1->moveMount($absolutePath2);
807+
$manager->moveMount($sourceMountPoint, $mount1->getMountPoint());
808+
} else {
809+
$result = false;
810+
}
811+
} else {
812+
$result = false;
813+
}
814+
// moving a file/folder within the same mount point
815+
} elseif ($storage1 === $storage2) {
816+
if ($storage1) {
817+
$result = $storage1->rename($internalPath1, $internalPath2);
818+
} else {
819+
$result = false;
820+
}
821+
// moving a file/folder between storages (from $storage1 to $storage2)
822+
} else {
823+
$result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
824+
}
825+
826+
if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
827+
// if it was a rename from a part file to a regular file it was a write and not a rename operation
828+
$this->writeUpdate($storage2, $internalPath2);
829+
} else if ($result) {
830+
if ($internalPath1 !== '') { // don't do a cache update for moved mounts
831+
$this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2);
832+
}
833+
}
834+
} catch(\Exception $e) {
835+
throw $e;
836+
} finally {
837+
$this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
838+
$this->changeLock($path2, ILockingProvider::LOCK_SHARED, true);
845839
}
846-
} elseif ($result) {
847-
if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
848-
\OC_Hook::emit(
849-
Filesystem::CLASSNAME,
850-
Filesystem::signal_post_rename,
851-
array(
852-
Filesystem::signal_param_oldpath => $this->getHookPath($path1),
853-
Filesystem::signal_param_newpath => $this->getHookPath($path2)
854-
)
855-
);
840+
841+
if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
842+
if ($this->shouldEmitHooks()) {
843+
$this->emit_file_hooks_post($exists, $path2);
844+
}
845+
} elseif ($result) {
846+
if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
847+
\OC_Hook::emit(
848+
Filesystem::CLASSNAME,
849+
Filesystem::signal_post_rename,
850+
array(
851+
Filesystem::signal_param_oldpath => $this->getHookPath($path1),
852+
Filesystem::signal_param_newpath => $this->getHookPath($path2)
853+
)
854+
);
855+
}
856856
}
857857
}
858+
} catch(\Exception $e) {
859+
throw $e;
860+
} finally {
861+
$this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
862+
$this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true);
858863
}
859-
$this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
860-
$this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true);
861864
}
862865
return $result;
863866
}

0 commit comments

Comments
 (0)