vfs: fix directory locking caused by slow directory listings
Before this fix we took the directory lock to read the ModTime of the directory. This was causing locking on directories which were being re-read from the backend. This commit gives the modtime its own lock so it can be read even when the directory is being updated. See: https://forum.rclone.org/t/high-cpu-load-with-rclone-mount/17604
This commit is contained in:
parent
811b30d116
commit
ddfde68140
1 changed files with 10 additions and 6 deletions
16
vfs/dir.go
16
vfs/dir.go
|
@ -29,12 +29,14 @@ type Dir struct {
|
|||
mu sync.RWMutex // protects the following
|
||||
parent *Dir // parent, nil for root
|
||||
path string
|
||||
modTime time.Time
|
||||
entry fs.Directory
|
||||
read time.Time // time directory entry last read
|
||||
items map[string]Node // directory entries - can be empty but not nil
|
||||
virtual map[string]vState // virtual directory entries - may be nil
|
||||
sys atomic.Value // user defined info to be attached here
|
||||
|
||||
modTimeMu sync.Mutex // protects the following
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
//go:generate stringer -type=vState
|
||||
|
@ -270,11 +272,13 @@ func (d *Dir) _age(when time.Time) (age time.Duration, stale bool) {
|
|||
// reading everything again
|
||||
func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) {
|
||||
d.ForgetAll()
|
||||
d.modTimeMu.Lock()
|
||||
d.modTime = fsDir.ModTime(context.TODO())
|
||||
d.modTimeMu.Unlock()
|
||||
d.mu.Lock()
|
||||
d.parent = newParent
|
||||
d.entry = fsDir
|
||||
d.path = fsDir.Remote()
|
||||
d.modTime = fsDir.ModTime(context.TODO())
|
||||
d.read = time.Time{}
|
||||
d.mu.Unlock()
|
||||
}
|
||||
|
@ -550,8 +554,8 @@ func (d *Dir) isEmpty() (bool, error) {
|
|||
|
||||
// ModTime returns the modification time of the directory
|
||||
func (d *Dir) ModTime() time.Time {
|
||||
d.mu.RLock()
|
||||
defer d.mu.RUnlock()
|
||||
d.modTimeMu.Lock()
|
||||
defer d.modTimeMu.Unlock()
|
||||
// fs.Debugf(d.path, "Dir.ModTime %v", d.modTime)
|
||||
return d.modTime
|
||||
}
|
||||
|
@ -566,9 +570,9 @@ func (d *Dir) SetModTime(modTime time.Time) error {
|
|||
if d.vfs.Opt.ReadOnly {
|
||||
return EROFS
|
||||
}
|
||||
d.mu.Lock()
|
||||
d.modTimeMu.Lock()
|
||||
d.modTime = modTime
|
||||
d.mu.Unlock()
|
||||
d.modTimeMu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue