diff --git a/vfs/file.go b/vfs/file.go index f06b35bb1..535aa414f 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -300,6 +300,17 @@ func (f *File) ModTime() (modTime time.Time) { if d.vfs.Opt.NoModTime { return d.ModTime() } + // Read the modtime from a dirty item if it exists + if f.d.vfs.Opt.CacheMode >= vfscommon.CacheModeMinimal { + if item := f.d.vfs.cache.DirtyItem(f._path()); item != nil { + modTime, err := item.GetModTime() + if err != nil { + fs.Errorf(f._path(), "ModTime: Item GetModTime failed: %v", err) + } else { + return modTime + } + } + } if !pendingModTime.IsZero() { return pendingModTime } diff --git a/vfs/vfscache/cache.go b/vfs/vfscache/cache.go index 2d1950ab0..45fc98554 100644 --- a/vfs/vfscache/cache.go +++ b/vfs/vfscache/cache.go @@ -237,7 +237,8 @@ func (c *Cache) InUse(name string) bool { return item.inUse() } -// DirtyItem the Item if it exists in the cache and is Dirty +// DirtyItem returns the Item if it exists in the cache **and** is +// dirty otherwise it returns nil. // // name should be a remote path not an osPath func (c *Cache) DirtyItem(name string) (item *Item) { diff --git a/vfs/vfscache/item.go b/vfs/vfscache/item.go index 8fffb2bc5..b7f6f0700 100644 --- a/vfs/vfscache/item.go +++ b/vfs/vfscache/item.go @@ -359,17 +359,22 @@ func (item *Item) Truncate(size int64) (err error) { return nil } +// _stat gets the current stat of the backing file +// +// Call with mutex held +func (item *Item) _stat() (fi os.FileInfo, err error) { + if item.fd != nil { + return item.fd.Stat() + } + osPath := item.c.toOSPath(item.name) // No locking in Cache + return os.Stat(osPath) +} + // _getSize gets the current size of the item and updates item.info.Size // // Call with mutex held func (item *Item) _getSize() (size int64, err error) { - var fi os.FileInfo - if item.fd != nil { - fi, err = item.fd.Stat() - } else { - osPath := item.c.toOSPath(item.name) // No locking in Cache - fi, err = os.Stat(osPath) - } + fi, err := item._stat() if err != nil { if os.IsNotExist(err) && item.o != nil { size = item.o.Size() @@ -1187,6 +1192,18 @@ func (item *Item) setModTime(modTime time.Time) { item.mu.Unlock() } +// GetModTime of the cache file +func (item *Item) GetModTime() (modTime time.Time, err error) { + // defer log.Trace(item.name, "modTime=%v", modTime)("") + item.mu.Lock() + defer item.mu.Unlock() + fi, err := item._stat() + if err == nil { + modTime = fi.ModTime() + } + return modTime, nil +} + // ReadAt bytes from the file at off func (item *Item) ReadAt(b []byte, off int64) (n int, err error) { n = 0