Commit 2f81df59 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Update mtime field in the cache for Open() and Truncate() calls.

This should fix Emacs save problems more robustly.
parent 7b4ae829
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"path/filepath" "path/filepath"
"sync" "sync"
"strings" "strings"
"time"
) )
// TODO(hanwen): is md5 sufficiently fast? // TODO(hanwen): is md5 sufficiently fast?
...@@ -346,6 +347,7 @@ func (me *UnionFs) Truncate(path string, offset uint64) (code fuse.Status) { ...@@ -346,6 +347,7 @@ func (me *UnionFs) Truncate(path string, offset uint64) (code fuse.Status) {
} }
if code.Ok() { if code.Ok() {
r.attr.Size = int64(offset) r.attr.Size = int64(offset)
r.attr.Mtime_ns = time.Nanoseconds()
me.branchCache.Set(path, r) me.branchCache.Set(path, r)
} }
return code return code
...@@ -688,22 +690,22 @@ func (me *UnionFs) Rename(src string, dst string) (code fuse.Status) { ...@@ -688,22 +690,22 @@ func (me *UnionFs) Rename(src string, dst string) (code fuse.Status) {
func (me *UnionFs) Open(name string, flags uint32) (fuseFile fuse.File, status fuse.Status) { func (me *UnionFs) Open(name string, flags uint32) (fuseFile fuse.File, status fuse.Status) {
r := me.getBranch(name) r := me.getBranch(name)
branch := r.branch
if flags&fuse.O_ANYWRITE != 0 && r.branch > 0 { if flags&fuse.O_ANYWRITE != 0 && r.branch > 0 {
code := me.Promote(name, r) code := me.Promote(name, r)
if code != fuse.OK { if code != fuse.OK {
return nil, code return nil, code
} }
branch = 0 r.branch = 0
r.attr.Mtime_ns = time.Nanoseconds()
me.branchCache.Set(name, r)
} }
return me.fileSystems[branch].Open(name, uint32(flags)) return me.fileSystems[r.branch].Open(name, uint32(flags))
} }
func (me *UnionFs) Release(name string) { func (me *UnionFs) Release(name string) {
r := me.getBranch(name) // Refresh timestamps and size field.
fresh := me.getBranchAttrNoCache(name) me.branchCache.DropEntry(name)
r.attr.Size = fresh.attr.Size me.getBranch(name)
me.branchCache.Set(name, r)
} }
func (me *UnionFs) Roots() (result []string) { func (me *UnionFs) Roots() (result []string) {
......
...@@ -416,3 +416,33 @@ func TestCopyChmod(t *testing.T) { ...@@ -416,3 +416,33 @@ func TestCopyChmod(t *testing.T) {
t.Errorf("uncached attr error %o", fi.Mode) t.Errorf("uncached attr error %o", fi.Mode)
} }
} }
func abs(dt int64) int64 {
if dt >= 0 {
return dt
}
return -dt
}
func TestTruncateTimestamp(t *testing.T) {
t.Log("TestTruncateTimestamp")
wd, state := setupUfs(t)
defer state.Unmount()
contents := "hello"
fn := wd + "/mount/y"
err := ioutil.WriteFile(fn, []byte(contents), 0644)
CheckSuccess(err)
time.Sleep(0.2e9)
truncTs := time.Nanoseconds()
err = os.Truncate(fn, 3)
CheckSuccess(err)
fi, err := os.Lstat(fn)
CheckSuccess(err)
if abs(truncTs - fi.Mtime_ns) > 0.1e9 {
t.Error("timestamp drift", truncTs, fi.Mtime_ns)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment