13111: Sync name when changing parents.
authorTom Clegg <tclegg@veritasgenetics.com>
Thu, 21 Dec 2017 06:07:22 +0000 (01:07 -0500)
committerTom Clegg <tclegg@veritasgenetics.com>
Wed, 3 Jan 2018 05:24:19 +0000 (00:24 -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
sdk/go/arvados/fs_site.go

index ebf2ad605018b9875af0936ccdae8089c8577ba0..9978c4302e6ac5d61267a217df7a948fa1d35a3d 100644 (file)
@@ -85,7 +85,7 @@ type FileSystem interface {
 }
 
 type inode interface {
-       SetParent(inode)
+       SetParent(parent inode, name string)
        Parent() inode
        FS() FileSystem
        Read([]byte, filenodePtr) (int, filenodePtr, error)
@@ -207,10 +207,11 @@ func (n *treenode) FS() FileSystem {
        return n.fs
 }
 
-func (n *treenode) SetParent(p inode) {
-       n.RLock()
-       defer n.RUnlock()
+func (n *treenode) SetParent(p inode, name string) {
+       n.Lock()
+       defer n.Unlock()
        n.parent = p
+       n.fileinfo.name = name
 }
 
 func (n *treenode) Parent() inode {
@@ -232,7 +233,7 @@ func (n *treenode) Child(name string, replace func(inode) inode) (child inode) {
                        delete(n.inodes, name)
                } else if newchild != child {
                        n.inodes[name] = newchild
-                       newchild.SetParent(n)
+                       newchild.SetParent(n, name)
                        child = newchild
                }
        }
@@ -442,28 +443,21 @@ func (fs *fileSystem) Rename(oldname, newname string) error {
                        err = os.ErrNotExist
                        return nil
                }
-               newdirf.inode.Child(newname, func(existing inode) inode {
+               accepted := newdirf.inode.Child(newname, func(existing inode) inode {
                        if existing != nil && existing.IsDir() {
                                err = ErrIsDirectory
                                return existing
                        }
                        return oldinode
                })
-               if err != nil {
+               if accepted != oldinode {
+                       if err == nil {
+                               // newdirf didn't accept oldinode.
+                               err = ErrInvalidArgument
+                       }
+                       // Leave oldinode in olddir.
                        return oldinode
                }
-               oldinode.Lock()
-               defer oldinode.Unlock()
-               switch n := oldinode.(type) {
-               case *dirnode:
-                       n.parent = newdirf.inode
-                       n.fileinfo.name = newname
-               case *filenode:
-                       n.parent = newdirf.inode
-                       n.fileinfo.name = newname
-               default:
-                       panic(fmt.Sprintf("bad inode type %T", n))
-               }
                //TODO: olddirf.setModTime(time.Now())
                //TODO: newdirf.setModTime(time.Now())
                return nil
index 96977cbc661417f46d557a31ffd10c37d110fc0e..0121d2dccce31d745f36fbdf5f2bf7bf0b1463de 100644 (file)
@@ -63,7 +63,7 @@ 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
        }
@@ -219,10 +219,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 {
@@ -522,7 +523,7 @@ func (dn *dirnode) Child(name string, replace func(inode) inode) inode {
                        }
                        return data, err
                }}
-               gn.SetParent(dn)
+               gn.SetParent(dn, name)
                return gn
        }
        return dn.treenode.Child(name, replace)
index 974dad8c4929ed2b5466f632b291de2f83b168b5..8a54b44e7e631928e8d63371669167efdc36e36b 100644 (file)
@@ -71,8 +71,7 @@ func (fs *siteFileSystem) mountCollection(parent inode, id string) inode {
                return nil
        }
        root := cfs.rootnode()
-       root.SetParent(parent)
-       root.(*dirnode).fileinfo.name = id
+       root.SetParent(parent, id)
        return root
 }
 
@@ -94,7 +93,7 @@ func (vn *vdirnode) Child(name string, _ func(inode) inode) inode {
                } else {
                        n := vn.create(vn, name)
                        if n != nil {
-                               n.SetParent(vn)
+                               n.SetParent(vn, name)
                        }
                        return n
                }