Skip to content

Commit 90e985f

Browse files
authored
Merge pull request #13739 from nextcloud/cache-cleanup-change
cleanup shared lock if changing to exclusive lock failed
2 parents 0d33302 + f69c2d1 commit 90e985f

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

lib/private/Files/View.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,13 @@ private function basicOperation($operation, $path, $hooks = [], $extraParam = nu
11371137
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
11381138
if ($run and $storage) {
11391139
if (in_array('write', $hooks) || in_array('delete', $hooks)) {
1140-
$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
1140+
try {
1141+
$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
1142+
} catch (LockedException $e) {
1143+
// release the shared lock we acquired before quiting
1144+
$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1145+
throw $e;
1146+
}
11411147
}
11421148
try {
11431149
if (!is_null($extraParam)) {

tests/lib/Files/ViewTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,37 @@ function () {
19971997
$this->assertNull($this->getFileLockType($view, $path), 'File got unlocked after exception');
19981998
}
19991999

2000+
public function testLockBasicOperationUnlocksAfterLockException() {
2001+
$view = new View('/' . $this->user . '/files/');
2002+
2003+
$storage = new Temporary([]);
2004+
2005+
Filesystem::mount($storage, array(), $this->user . '/');
2006+
2007+
$storage->mkdir('files');
2008+
$storage->mkdir('files/dir');
2009+
$storage->file_put_contents('files/test.txt', 'blah');
2010+
$storage->getScanner()->scan('files');
2011+
2012+
// get a shared lock
2013+
$handle = $view->fopen('test.txt', 'r');
2014+
2015+
$thrown = false;
2016+
try {
2017+
// try (and fail) to get a write lock
2018+
$view->unlink('test.txt');
2019+
} catch (\Exception $e) {
2020+
$thrown = true;
2021+
$this->assertInstanceOf(LockedException::class, $e);
2022+
}
2023+
$this->assertTrue($thrown, 'Exception was rethrown');
2024+
2025+
// clean shared lock
2026+
fclose($handle);
2027+
2028+
$this->assertNull($this->getFileLockType($view, 'test.txt'), 'File got unlocked');
2029+
}
2030+
20002031
/**
20012032
* Test locks for fopen with fclose at the end
20022033
*

0 commit comments

Comments
 (0)