mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 08:46:24 +08:00
vfs: fix fatal error: sync: unlock of unlocked mutex in panics
Before this change a panic could be overwritten with the message fatal error: sync: unlock of unlocked mutex This was because we temporarily unlocked the mutex, but failed to lock it again if there was a panic. This is code is never the cause of an error but it masks the underlying error by overwriting the panic cause. See: https://forum.rclone.org/t/serve-webdav-is-crashing-fatal-error-sync-unlock-of-unlocked-mutex/46300
This commit is contained in:
parent
0e85ba5080
commit
4ed4483bbc
|
@ -573,6 +573,15 @@ func (item *Item) open(o fs.Object) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calls f with mu unlocked, re-locking mu if a panic is raised
|
||||||
|
//
|
||||||
|
// mu must be locked when calling this function
|
||||||
|
func unlockMutexForCall(mu *sync.Mutex, f func()) {
|
||||||
|
mu.Unlock()
|
||||||
|
defer mu.Lock()
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
// Store stores the local cache file to the remote object, returning
|
// Store stores the local cache file to the remote object, returning
|
||||||
// the new remote object. objOld is the old object if known.
|
// the new remote object. objOld is the old object if known.
|
||||||
//
|
//
|
||||||
|
@ -589,9 +598,9 @@ func (item *Item) _store(ctx context.Context, storeFn StoreFn) (err error) {
|
||||||
// Object has disappeared if cacheObj == nil
|
// Object has disappeared if cacheObj == nil
|
||||||
if cacheObj != nil {
|
if cacheObj != nil {
|
||||||
o, name := item.o, item.name
|
o, name := item.o, item.name
|
||||||
item.mu.Unlock()
|
unlockMutexForCall(&item.mu, func() {
|
||||||
o, err := operations.Copy(ctx, item.c.fremote, o, name, cacheObj)
|
o, err = operations.Copy(ctx, item.c.fremote, o, name, cacheObj)
|
||||||
item.mu.Lock()
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrorCantUploadEmptyFiles) {
|
if errors.Is(err, fs.ErrorCantUploadEmptyFiles) {
|
||||||
fs.Errorf(name, "Writeback failed: %v", err)
|
fs.Errorf(name, "Writeback failed: %v", err)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user