}
type inode interface {
- SetParent(inode)
+ SetParent(parent inode, name string)
Parent() inode
FS() FileSystem
Read([]byte, filenodePtr) (int, filenodePtr, error)
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 {
delete(n.inodes, name)
} else if newchild != child {
n.inodes[name] = newchild
- newchild.SetParent(n)
+ newchild.SetParent(n, name)
child = newchild
}
}
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
inodes: make(map[string]inode),
},
}
- root.SetParent(root)
+ root.SetParent(root, ".")
if err := root.loadManifest(c.ManifestText); err != nil {
return nil, err
}
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 {
}
return data, err
}}
- gn.SetParent(dn)
+ gn.SetParent(dn, name)
return gn
}
return dn.treenode.Child(name, replace)