Skip to content

Commit

Permalink
Merge pull request #13746 from nextcloud/backport/13739/stable13
Browse files Browse the repository at this point in the history
[stable13] cleanup shared lock if changing to exclusive lock failed
  • Loading branch information
MorrisJobke authored Jan 23, 2019
2 parents 544d28a + 9126cdc commit b558e49
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/private/Files/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,13 @@ private function basicOperation($operation, $path, $hooks = [], $extraParam = nu
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
if ($run and $storage) {
if (in_array('write', $hooks) || in_array('delete', $hooks)) {
$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
try {
$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
} catch (LockedException $e) {
// release the shared lock we acquired before quiting
$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
throw $e;
}
}
try {
if (!is_null($extraParam)) {
Expand Down
31 changes: 31 additions & 0 deletions tests/lib/Files/ViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,37 @@ function () {
$this->assertNull($this->getFileLockType($view, $path), 'File got unlocked after exception');
}

public function testLockBasicOperationUnlocksAfterLockException() {
$view = new View('/' . $this->user . '/files/');

$storage = new Temporary([]);

Filesystem::mount($storage, array(), $this->user . '/');

$storage->mkdir('files');
$storage->mkdir('files/dir');
$storage->file_put_contents('files/test.txt', 'blah');
$storage->getScanner()->scan('files');

// get a shared lock
$handle = $view->fopen('test.txt', 'r');

$thrown = false;
try {
// try (and fail) to get a write lock
$view->unlink('test.txt');
} catch (\Exception $e) {
$thrown = true;
$this->assertInstanceOf(LockedException::class, $e);
}
$this->assertTrue($thrown, 'Exception was rethrown');

// clean shared lock
fclose($handle);

$this->assertNull($this->getFileLockType($view, 'test.txt'), 'File got unlocked');
}

/**
* Test locks for fopen with fclose at the end
*
Expand Down

0 comments on commit b558e49

Please sign in to comment.