forked from TrueCloudLab/rclone
Add rclone mount --dir-cache-time to control caching of directory entries - fixes #680
This commit is contained in:
parent
368cce93ff
commit
a02edb9e69
2 changed files with 31 additions and 7 deletions
|
@ -30,7 +30,7 @@ type Dir struct {
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
path string
|
path string
|
||||||
mu sync.RWMutex // protects the following
|
mu sync.RWMutex // protects the following
|
||||||
read bool
|
read time.Time // time directory entry last read
|
||||||
items map[string]*DirEntry
|
items map[string]*DirEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +66,16 @@ func (d *Dir) delObject(leaf string) {
|
||||||
func (d *Dir) readDir() error {
|
func (d *Dir) readDir() error {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
if d.read {
|
when := time.Now()
|
||||||
|
if d.read.IsZero() {
|
||||||
|
fs.Debug(d.path, "Reading directory")
|
||||||
|
} else {
|
||||||
|
age := when.Sub(d.read)
|
||||||
|
if age < dirCacheTime {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
fs.Debug(d.path, "Re-reading directory (%v old)", age)
|
||||||
|
}
|
||||||
objs, dirs, err := fs.NewLister().SetLevel(1).Start(d.f, d.path).GetAll()
|
objs, dirs, err := fs.NewLister().SetLevel(1).Start(d.f, d.path).GetAll()
|
||||||
if err == fs.ErrorDirNotFound {
|
if err == fs.ErrorDirNotFound {
|
||||||
// We treat directory not found as empty because we
|
// We treat directory not found as empty because we
|
||||||
|
@ -76,6 +83,13 @@ func (d *Dir) readDir() error {
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// NB when we re-read a directory after its cache has expired
|
||||||
|
// we drop the old files which should lead to correct
|
||||||
|
// behaviour but may not be very efficient.
|
||||||
|
|
||||||
|
// Keep a note of the previous contents of the directory
|
||||||
|
oldItems := d.items
|
||||||
|
|
||||||
// Cache the items by name
|
// Cache the items by name
|
||||||
d.items = make(map[string]*DirEntry, len(objs)+len(dirs))
|
d.items = make(map[string]*DirEntry, len(objs)+len(dirs))
|
||||||
for _, obj := range objs {
|
for _, obj := range objs {
|
||||||
|
@ -87,12 +101,19 @@ func (d *Dir) readDir() error {
|
||||||
}
|
}
|
||||||
for _, dir := range dirs {
|
for _, dir := range dirs {
|
||||||
name := path.Base(dir.Remote())
|
name := path.Base(dir.Remote())
|
||||||
|
// Use old dir value if it exists
|
||||||
|
if oldItem, ok := oldItems[name]; ok {
|
||||||
|
if _, ok := oldItem.o.(*fs.Dir); ok {
|
||||||
|
d.items[name] = oldItem
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
d.items[name] = &DirEntry{
|
d.items[name] = &DirEntry{
|
||||||
o: dir,
|
o: dir,
|
||||||
node: nil,
|
node: nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.read = true
|
d.read = when
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ package mount
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"bazil.org/fuse"
|
"bazil.org/fuse"
|
||||||
"github.com/ncw/rclone/cmd"
|
"github.com/ncw/rclone/cmd"
|
||||||
|
@ -21,6 +22,7 @@ var (
|
||||||
noModTime = false
|
noModTime = false
|
||||||
debugFUSE = false
|
debugFUSE = false
|
||||||
noSeek = false
|
noSeek = false
|
||||||
|
dirCacheTime = 5 * 60 * time.Second
|
||||||
// mount options
|
// mount options
|
||||||
readOnly = false
|
readOnly = false
|
||||||
allowNonEmpty = false
|
allowNonEmpty = false
|
||||||
|
@ -45,6 +47,7 @@ func init() {
|
||||||
mountCmd.Flags().BoolVarP(&noModTime, "no-modtime", "", noModTime, "Don't read the modification time (can speed things up).")
|
mountCmd.Flags().BoolVarP(&noModTime, "no-modtime", "", noModTime, "Don't read the modification time (can speed things up).")
|
||||||
mountCmd.Flags().BoolVarP(&debugFUSE, "debug-fuse", "", debugFUSE, "Debug the FUSE internals - needs -v.")
|
mountCmd.Flags().BoolVarP(&debugFUSE, "debug-fuse", "", debugFUSE, "Debug the FUSE internals - needs -v.")
|
||||||
mountCmd.Flags().BoolVarP(&noSeek, "no-seek", "", noSeek, "Don't allow seeking in files.")
|
mountCmd.Flags().BoolVarP(&noSeek, "no-seek", "", noSeek, "Don't allow seeking in files.")
|
||||||
|
mountCmd.Flags().DurationVarP(&dirCacheTime, "dir-cache-time", "", dirCacheTime, "Time to cache directory entries for.")
|
||||||
// mount options
|
// mount options
|
||||||
mountCmd.Flags().BoolVarP(&readOnly, "read-only", "", readOnly, "Mount read-only.")
|
mountCmd.Flags().BoolVarP(&readOnly, "read-only", "", readOnly, "Mount read-only.")
|
||||||
mountCmd.Flags().BoolVarP(&allowNonEmpty, "allow-non-empty", "", allowNonEmpty, "Allow mounting over a non-empty directory.")
|
mountCmd.Flags().BoolVarP(&allowNonEmpty, "allow-non-empty", "", allowNonEmpty, "Allow mounting over a non-empty directory.")
|
||||||
|
|
Loading…
Add table
Reference in a new issue