13111: Move SetParent() responsibility from Child() to caller.
authorTom Clegg <tclegg@veritasgenetics.com>
Wed, 3 Jan 2018 08:27:36 +0000 (03:27 -0500)
committerTom Clegg <tclegg@veritasgenetics.com>
Wed, 3 Jan 2018 08:27:36 +0000 (03:27 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

sdk/go/arvados/fs_base.go
sdk/go/arvados/fs_collection.go

index 419be7ffb1ef621ab1db359b62832f6d22842948..fd8c18b3def852cb48f11c25439e1fa1f3a5c75f 100644 (file)
@@ -103,6 +103,14 @@ type inode interface {
        // the child inode is replaced with the one returned by
        // replace().
        //
+       // If replace(x) returns an inode (besides x or nil) that is
+       // subsequently returned by Child(), then Child()'s caller
+       // must ensure the new child's name and parent are set/updated
+       // to Child()'s name argument and its receiver respectively.
+       // This is not necessarily done before replace(x) returns, but
+       // it must be done before Child()'s caller releases the
+       // parent's lock.
+       //
        // Nil represents "no child". replace(nil) signifies that no
        // child with this name exists yet. If replace() returns nil,
        // the existing child should be deleted if possible.
@@ -232,7 +240,6 @@ func (n *treenode) Child(name string, replace func(inode) inode) (child inode) {
                if newchild == nil {
                        delete(n.inodes, name)
                } else if newchild != child {
-                       newchild.SetParent(n, name)
                        n.inodes[name] = newchild
                        n.fileinfo.modTime = time.Now()
                        child = newchild
@@ -323,6 +330,7 @@ func (fs *fileSystem) openFile(name string, flag int, perm os.FileMode) (*fileha
                var err error
                n = parent.Child(name, func(inode) inode {
                        n, err = parent.FS().newNode(name, perm|0755, time.Now())
+                       n.SetParent(parent, name)
                        return n
                })
                if err != nil {
@@ -371,6 +379,7 @@ func (fs *fileSystem) Mkdir(name string, perm os.FileMode) (err error) {
        }
        child := n.Child(name, func(inode) (child inode) {
                child, err = n.FS().newNode(name, perm|os.ModeDir, time.Now())
+               child.SetParent(n, name)
                return
        })
        if err != nil {
@@ -464,6 +473,7 @@ func (fs *fileSystem) Rename(oldname, newname string) error {
                        // Leave oldinode in olddir.
                        return oldinode
                }
+               accepted.SetParent(newdirf.inode, newname)
                return nil
        })
        return err
index 27ea9048acdc6e8b45ed16e1b1ab313ceb9b554c..fbd9775b0cde0876e68328fd63a019485eeac4a9 100644 (file)
@@ -532,19 +532,14 @@ 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, name)
                return gn
        }
-       oldchild := dn.treenode.Child(name, nil)
-       child := dn.treenode.Child(name, replace)
-       if child != nil && child != oldchild {
-               child.SetParent(dn, name)
-       }
-       return child
+       return dn.treenode.Child(name, replace)
 }
 
 // sync flushes in-memory data (for all files in the tree rooted at
@@ -844,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 {
@@ -861,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: