diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go index cb9436ca6..e52e41463 100644 --- a/pkg/fs/fs.go +++ b/pkg/fs/fs.go @@ -99,6 +99,8 @@ type node struct { fs *CamliFileSystem blobref *blobref.BlobRef + pnodeModTime time.Time // optionally set by recent.go; modtime of permanode + dmu sync.Mutex // guards dirents. acquire before mu. dirents []fuse.Dirent // nil until populated once @@ -269,16 +271,21 @@ func (n *node) populateAttr() error { // TODO: inode? - n.attr.Mtime = meta.ModTime() + if mt := meta.ModTime(); !mt.IsZero() { + n.attr.Mtime = mt + } else { + n.attr.Mtime = n.pnodeModTime + } switch meta.Type() { case "file": n.attr.Size = uint64(meta.PartsSize()) n.attr.Blocks = 0 // TODO: set? + n.attr.Mode |= 0400 case "directory": - // Nothing special? Just prevent default case. + n.attr.Mode |= 0500 case "symlink": - // Nothing special? Just prevent default case. + n.attr.Mode |= 0400 default: log.Printf("unknown attr ss.Type %q in populateAttr", meta.Type()) } diff --git a/pkg/fs/recent.go b/pkg/fs/recent.go index 6c0895741..bc1c3e933 100644 --- a/pkg/fs/recent.go +++ b/pkg/fs/recent.go @@ -21,6 +21,7 @@ import ( "os" "path" "sync" + "time" "camlistore.org/pkg/blobref" "camlistore.org/pkg/search" @@ -34,8 +35,9 @@ import ( type recentDir struct { fs *CamliFileSystem - mu sync.Mutex - ents map[string]*search.DescribedBlob // filename to blob meta + mu sync.Mutex + ents map[string]*search.DescribedBlob // filename to blob meta + modTime map[string]time.Time // filename to permanode modtime } func (n *recentDir) Attr() fuse.Attr { @@ -52,6 +54,7 @@ func (n *recentDir) ReadDir(intr fuse.Intr) ([]fuse.Dirent, fuse.Error) { defer n.mu.Unlock() n.ents = make(map[string]*search.DescribedBlob) + n.modTime = make(map[string]time.Time) req := &search.RecentRequest{N: 100} res, err := n.fs.client.GetRecentPermanodes(req) @@ -90,7 +93,8 @@ func (n *recentDir) ReadDir(intr fuse.Intr) ([]fuse.Dirent, fuse.Error) { } } n.ents[name] = ccMeta - log.Printf("fs.recent: name %q = %v", name, ccMeta.BlobRef) + n.modTime[name] = ri.ModTime.Time() + log.Printf("fs.recent: name %q = %v (at %v)", name, ccMeta.BlobRef, ri.ModTime.Time()) ents = append(ents, fuse.Dirent{ Name: name, }) @@ -105,7 +109,7 @@ func (n *recentDir) Lookup(name string, intr fuse.Intr) (fuse.Node, fuse.Error) if n.ents == nil { // Odd case: a Lookup before a Readdir. Force a readdir to // seed our map. Mostly hit just during development. - n.mu.Unlock() // release, since ReadDir will acquire + n.mu.Unlock() // release, since ReadDir will acquire n.ReadDir(intr) n.mu.Lock() } @@ -114,7 +118,10 @@ func (n *recentDir) Lookup(name string, intr fuse.Intr) (fuse.Node, fuse.Error) if db == nil { return nil, fuse.ENOENT } - // TODO: fake the modtime to be the modtime of the permanode instead? - // set some optional field in *node for that. - return &node{fs: n.fs, blobref: db.BlobRef}, nil + nod := &node{ + fs: n.fs, + blobref: db.BlobRef, + pnodeModTime: n.modTime[name], + } + return nod, nil }