Skip to content

Commit

Permalink
vfs: fix deadlock under concurrent truncate and releases (#3457)
Browse files Browse the repository at this point in the history
  • Loading branch information
davies authored Apr 10, 2023
1 parent 5244ced commit 20630b8
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
9 changes: 8 additions & 1 deletion pkg/vfs/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,14 @@ func (v *VFS) newHandle(inode Ino) *handle {
func (v *VFS) findAllHandles(inode Ino) []*handle {
v.hanleM.Lock()
defer v.hanleM.Unlock()
return v.handles[inode]
hs := v.handles[inode]
if len(hs) <= 1 {
return hs
}
// copy hs so it will not be modified by releaseHandle
hs2 := make([]*handle, len(hs))
copy(hs2, hs)
return hs2
}

func (v *VFS) findHandle(inode Ino, fh uint64) *handle {
Expand Down
2 changes: 2 additions & 0 deletions pkg/vfs/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package vfs
import (
"encoding/json"
"runtime"
"sort"
"sync"
"syscall"
"time"
Expand Down Expand Up @@ -438,6 +439,7 @@ func (v *VFS) Truncate(ctx Context, ino Ino, size int64, opened uint8, attr *Att
return
}
hs := v.findAllHandles(ino)
sort.Slice(hs, func(i, j int) bool { return hs[i].fh < hs[j].fh })
for _, h := range hs {
if !h.Wlock(ctx) {
err = syscall.EINTR
Expand Down

0 comments on commit 20630b8

Please sign in to comment.