File tree Expand file tree Collapse file tree 2 files changed +36
-3
lines changed
tests/unit/Connector/Sabre Expand file tree Collapse file tree 2 files changed +36
-3
lines changed Original file line number Diff line number Diff line change @@ -252,10 +252,22 @@ public function put($data) {
252252 try {
253253 $ this ->changeLock (ILockingProvider::LOCK_EXCLUSIVE );
254254 } catch (LockedException $ e ) {
255- if ($ needsPartFile ) {
256- $ partStorage ->unlink ($ internalPartPath );
255+ // during very large uploads, the shared lock we got at the start might have been expired
256+ // meaning that the above lock can fail not just only because somebody else got a shared lock
257+ // or because there is no existing shared lock to make exclusive
258+ //
259+ // Thus we try to get a new exclusive lock, if the original lock failed because of a different shared
260+ // lock this will still fail, if our original shared lock expired the new lock will be successful and
261+ // the entire operation will be safe
262+
263+ try {
264+ $ this ->acquireLock (ILockingProvider::LOCK_EXCLUSIVE );
265+ } catch (LockedException $ e ) {
266+ if ($ needsPartFile ) {
267+ $ partStorage ->unlink ($ internalPartPath );
268+ }
269+ throw new FileLocked ($ e ->getMessage (), $ e ->getCode (), $ e );
257270 }
258- throw new FileLocked ($ e ->getMessage (), $ e ->getCode (), $ e );
259271 }
260272
261273 // rename to correct path
Original file line number Diff line number Diff line change @@ -1201,4 +1201,25 @@ public function testSimplePutNoCreatePermissions() {
12011201
12021202 $ this ->assertEquals ('new content ' , $ view ->file_get_contents ('root/file.txt ' ));
12031203 }
1204+
1205+ public function testPutLockExpired () {
1206+ $ view = new \OC \Files \View ('/ ' . $ this ->user . '/files/ ' );
1207+
1208+ $ path = 'test-locking.txt ' ;
1209+ $ info = new \OC \Files \FileInfo (
1210+ '/ ' . $ this ->user . '/files/ ' . $ path ,
1211+ $ this ->getMockStorage (),
1212+ null ,
1213+ ['permissions ' => \OCP \Constants::PERMISSION_ALL ],
1214+ null
1215+ );
1216+
1217+ $ file = new \OCA \DAV \Connector \Sabre \File ($ view , $ info );
1218+
1219+ // don't lock before the PUT to simulate an expired shared lock
1220+ $ this ->assertNotEmpty ($ file ->put ($ this ->getStream ('test data ' )));
1221+
1222+ // afterMethod unlocks
1223+ $ view ->unlockFile ($ path , ILockingProvider::LOCK_SHARED );
1224+ }
12041225}
You can’t perform that action at this time.
0 commit comments