Commit 444f87ef authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Implement Link.

parent d0dbfc98
......@@ -92,6 +92,10 @@ func (me *fsInode) SetInode(node *inode) {
me.inode = node
}
func (me *fsInode) Inode() *inode {
return me.inode
}
////////////////////////////////////////////////////////////////
func (me *fsInode) Readlink(c *Context) ([]byte, Status) {
......@@ -188,8 +192,19 @@ func (me *fsInode) Rename(oldName string, newParent *fsInode, newName string, co
return me.fs.Rename(oldPath, newPath, context)
}
func (me *fsInode) Link(name string, existing *fsInode, context *Context) (code Status) {
return me.fs.Link(existing.GetPath(), filepath.Join(me.GetPath(), name), context)
func (me *fsInode) Link(name string, existing *fsInode, context *Context) (fi *os.FileInfo, newNode *fsInode, code Status) {
newPath := filepath.Join(me.GetPath(), name)
oldPath := existing.GetPath()
code = me.fs.Link(oldPath, newPath, context)
if code.Ok() {
oldFi, _ := me.fs.GetAttr(oldPath, context)
fi, _ = me.fs.GetAttr(newPath, context)
if oldFi != nil && fi != nil && oldFi.Ino != 0 && oldFi.Ino == fi.Ino {
return fi, existing, OK
}
newNode = me.createChild(name)
}
return
}
func (me *fsInode) Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *os.FileInfo, newNode *fsInode, code Status) {
......
......@@ -47,17 +47,17 @@ func (me *fileSystemMount) setOwner(attr *Attr) {
attr.Owner = *me.options.Owner
}
}
func (me *fileSystemMount) fileInfoToEntry(fi *os.FileInfo, out *EntryOut) {
func (me *fileSystemMount) fileInfoToEntry(fi *os.FileInfo) (out *EntryOut) {
out = &EntryOut{}
SplitNs(me.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec)
SplitNs(me.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec)
CopyFileInfo(fi, &out.Attr)
me.setOwner(&out.Attr)
if !fi.IsDirectory() {
fi.Nlink = 1
}
CopyFileInfo(fi, &out.Attr)
me.setOwner(&out.Attr)
return out
}
func (me *fileSystemMount) fileInfoToAttr(fi *os.FileInfo, out *AttrOut) {
CopyFileInfo(fi, &out.Attr)
......
......@@ -33,11 +33,11 @@ func (me *FileSystemConnector) internalMountLookup(mount *fileSystemMount, looku
mount.treeLock.Lock()
defer mount.treeLock.Unlock()
mount.mountInode.lookupCount += lookupCount
out = &EntryOut{
NodeId: mount.mountInode.nodeId,
Generation: 1, // where to get the generation?
}
mount.fileInfoToEntry(fi, out)
out = mount.fileInfoToEntry(fi)
out.NodeId = mount.mountInode.nodeId
// We don't do NFS.
out.Generation = 1
return out, OK, mount.mountInode
}
......@@ -60,11 +60,9 @@ func (me *FileSystemConnector) internalLookup(parent *inode, name string, lookup
}
if child != nil && code.Ok() {
out = &EntryOut{
NodeId: child.nodeId,
Generation: 1, // where to get the generation?
}
parent.mount.fileInfoToEntry(fi, out)
out = parent.mount.fileInfoToEntry(fi)
out.NodeId = child.nodeId
out.Generation = 1
return out, OK, child
}
......@@ -203,8 +201,7 @@ func (me *FileSystemConnector) Mknod(header *InHeader, input *MknodIn, name stri
func (me *FileSystemConnector) createChild(parent *inode, name string, fi *os.FileInfo, fsi *fsInode) (out *EntryOut, child *inode) {
child = parent.createChild(name, fi.IsDirectory(), fsi, me)
out = &EntryOut{}
parent.mount.fileInfoToEntry(fi, out)
out = parent.mount.fileInfoToEntry(fi)
out.Ino = child.nodeId
out.NodeId = child.nodeId
return out, child
......@@ -270,20 +267,26 @@ func (me *FileSystemConnector) Rename(header *InHeader, input *RenameIn, oldName
return code
}
func (me *FileSystemConnector) Link(header *InHeader, input *LinkIn, filename string) (out *EntryOut, code Status) {
func (me *FileSystemConnector) Link(header *InHeader, input *LinkIn, name string) (out *EntryOut, code Status) {
existing := me.getInodeData(input.Oldnodeid)
parent := me.getInodeData(header.NodeId)
if existing.mount != parent.mount {
return nil, EXDEV
}
code = parent.fsInode.Link(filename, existing.fsInode, &header.Context)
fi, fsInode, code := parent.fsInode.Link(name, existing.fsInode, &header.Context)
if !code.Ok() {
return nil, code
}
// TODO - revise this for real hardlinks?
out, code, _ = me.internalLookup(parent, filename, 1, &header.Context)
if fsInode.Inode() == nil {
out, _ = me.createChild(parent, name, fi, fsInode)
} else {
out = parent.mount.fileInfoToEntry(fi)
out.Ino = fsInode.Inode().nodeId
out.NodeId = out.Ino
}
return out, code
}
......
......@@ -243,11 +243,17 @@ func TestLink(t *testing.T) {
err = os.Link(me.mountFile, mountSubfile)
CheckSuccess(err)
subfi, err := os.Lstat(mountSubfile)
CheckSuccess(err)
fi, err := os.Lstat(me.origFile)
CheckSuccess(err)
if fi.Nlink != 2 {
t.Errorf("Expect 2 links: %v", fi)
}
if fi.Ino != subfi.Ino {
t.Errorf("Link succeeded, but inode numbers different: %v %v", fi.Ino, subfi.Ino)
}
f, err := os.Open(mountSubfile)
var buf [1024]byte
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment