vfs: fix deadlock on concurrent operations on a directory - fixes #2811

Before this fix there were two paths where concurrent use of a
directory could take the file lock then directory lock and the other
would take the locks in the reverse order.

Fix this by narrowing the locking windows so the file lock and
directory lock don't overlap.
This commit is contained in:
Nick Craig-Wood 2018-12-03 21:51:39 +00:00
parent 5babf2dc5c
commit 13387c0838

View File

@ -331,9 +331,10 @@ func (f *File) setSize(n int64) {
// Update the object when written and add it to the directory
func (f *File) setObject(o fs.Object) {
f.mu.Lock()
defer f.mu.Unlock()
f.o = o
_ = f.applyPendingModTime()
f.mu.Unlock()
f.d.addObject(f)
}
@ -440,20 +441,23 @@ func (f *File) Sync() error {
// Remove the file
func (f *File) Remove() error {
f.mu.Lock()
defer f.mu.Unlock()
f.muRW.Lock()
defer f.muRW.Unlock()
if f.d.vfs.Opt.ReadOnly {
return EROFS
}
f.mu.Lock()
f.muRW.Lock()
if f.o != nil {
err := f.o.Remove()
if err != nil {
fs.Errorf(f, "File.Remove file error: %v", err)
f.muRW.Unlock()
f.mu.Unlock()
return err
}
}
f.muRW.Unlock()
f.mu.Unlock()
// Remove the item from the directory listing
f.d.delObject(f.Name())
// Remove the object from the cache