13111: Merge branch 'master' into 12308-go-fuse
[arvados.git] / sdk / go / arvados / fs_collection.go
index 96977cbc661417f46d557a31ffd10c37d110fc0e..fbd9775b0cde0876e68328fd63a019485eeac4a9 100644 (file)
@@ -63,14 +63,27 @@ func (c *Collection) FileSystem(client apiClient, kc keepClient) (CollectionFile
                        inodes: make(map[string]inode),
                },
        }
-       root.SetParent(root)
+       root.SetParent(root, ".")
        if err := root.loadManifest(c.ManifestText); err != nil {
                return nil, err
        }
+       backdateTree(root, modTime)
        fs.root = root
        return fs, nil
 }
 
+func backdateTree(n inode, modTime time.Time) {
+       switch n := n.(type) {
+       case *filenode:
+               n.fileinfo.modTime = modTime
+       case *dirnode:
+               n.fileinfo.modTime = modTime
+               for _, n := range n.inodes {
+                       backdateTree(n, modTime)
+               }
+       }
+}
+
 func (fs *collectionFileSystem) newNode(name string, perm os.FileMode, modTime time.Time) (node inode, err error) {
        if name == "" || name == "." || name == ".." {
                return nil, ErrInvalidArgument
@@ -219,10 +232,11 @@ func (fn *filenode) appendSegment(e segment) {
        fn.fileinfo.size += int64(e.Len())
 }
 
-func (fn *filenode) SetParent(p inode) {
-       fn.RLock()
-       defer fn.RUnlock()
+func (fn *filenode) SetParent(p inode, name string) {
+       fn.Lock()
+       defer fn.Unlock()
        fn.parent = p
+       fn.fileinfo.name = name
 }
 
 func (fn *filenode) Parent() inode {
@@ -518,11 +532,11 @@ func (dn *dirnode) Child(name string, replace func(inode) inode) inode {
                        }
                        data, err := json.Marshal(&coll)
                        if err == nil {
-                               data = append(data, 10)
+                               data = append(data, '\n')
                        }
                        return data, err
                }}
-               gn.SetParent(dn)
+               gn.SetParent(dn, name)
                return gn
        }
        return dn.treenode.Child(name, replace)
@@ -825,8 +839,9 @@ func (dn *dirnode) createFileAndParents(path string) (fn *filenode, err error) {
                }
                node.Child(name, func(child inode) inode {
                        if child == nil {
-                               node, err = node.FS().newNode(name, 0755|os.ModeDir, node.Parent().FileInfo().ModTime())
-                               child = node
+                               child, err = node.FS().newNode(name, 0755|os.ModeDir, node.Parent().FileInfo().ModTime())
+                               child.SetParent(node, name)
+                               node = child
                        } else if !child.IsDir() {
                                err = ErrFileExists
                        } else {
@@ -842,6 +857,7 @@ func (dn *dirnode) createFileAndParents(path string) (fn *filenode, err error) {
                switch child := child.(type) {
                case nil:
                        child, err = node.FS().newNode(basename, 0755, node.FileInfo().ModTime())
+                       child.SetParent(node, basename)
                        fn = child.(*filenode)
                        return child
                case *filenode: