mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 05:49:46 +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
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
if cacheObj != nil {
|
||||
o, name := item.o, item.name
|
||||
item.mu.Unlock()
|
||||
o, err := operations.Copy(ctx, item.c.fremote, o, name, cacheObj)
|
||||
item.mu.Lock()
|
||||
unlockMutexForCall(&item.mu, func() {
|
||||
o, err = operations.Copy(ctx, item.c.fremote, o, name, cacheObj)
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, fs.ErrorCantUploadEmptyFiles) {
|
||||
fs.Errorf(name, "Writeback failed: %v", err)
|
||||
|
|
Loading…
Reference in New Issue
Block a user