Commit 61fa4895 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Access fsInode and inodeFs through interfaces.

parent 2c93be2a
......@@ -8,6 +8,56 @@ import (
// Types for users to implement.
type InodeFs interface {
Unmount()
Mount(conn *FileSystemConnector)
StatFs() *StatfsOut
Root() FsNode
}
type FsNode interface {
// The following are called by the FileSystemConnector
Inode() *inode
SetInode(node *inode)
RmChild(name string, child FsNode)
AddChild(name string, child FsNode)
Lookup(name string) (fi *os.FileInfo, node FsNode, code Status)
// Misc.
Access(mode uint32, context *Context) (code Status)
Readlink(c *Context) ([]byte, Status)
// Namespace operations
Mknod(name string, mode uint32, dev uint32, context *Context) (fi *os.FileInfo, newNode FsNode, code Status)
Mkdir(name string, mode uint32, context *Context) (fi *os.FileInfo, newNode FsNode, code Status)
Unlink(name string, context *Context) (code Status)
Rmdir(name string, context *Context) (code Status)
Symlink(name string, content string, context *Context) (fi *os.FileInfo, newNode FsNode, code Status)
Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status)
Link(name string, existing FsNode, context *Context) (fi *os.FileInfo, newNode FsNode, code Status)
// Files
Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *os.FileInfo, newNode FsNode, code Status)
Open(flags uint32, context *Context) (file File, code Status)
Flush(file File, openFlags uint32, context *Context) (code Status)
OpenDir(context *Context) (chan DirEntry, Status)
// XAttrs
GetXAttr(attribute string, context *Context) (data []byte, code Status)
RemoveXAttr(attr string, context *Context) Status
SetXAttr(attr string, data []byte, flags int, context *Context) Status
ListXAttr(context *Context) (attrs []string, code Status)
// Attributes
GetAttr(file File, context *Context) (fi *os.FileInfo, code Status)
Chmod(file File, perms uint32, context *Context) (code Status)
Chown(file File, uid uint32, gid uint32, context *Context) (code Status)
Truncate(file File, size uint64, context *Context) (code Status)
Utimens(file File, atime uint64, mtime uint64, context *Context) (code Status)
}
// A filesystem API that uses paths rather than inodes. A minimal
// file system should have at least a functional GetAttr method.
// Typically, each call happens in its own goroutine, so take care to
......
......@@ -8,6 +8,8 @@ import (
var _ = log.Println
type inodeFs struct {
fs FileSystem
root *fsInode
......@@ -36,10 +38,11 @@ func newInodeFs(fs FileSystem) *inodeFs {
return me
}
func (me *inodeFs) RootNode() *fsInode {
func (me *inodeFs) Root() FsNode {
return me.root
}
// This is a combination of dentry (entry in the file/directory and
// the inode). This structure is used to implement glue for FSes where
// there is a one-to-one mapping of paths and inodes, ie. FSes that
......@@ -73,14 +76,16 @@ func (me *fsInode) GetPath() (path string) {
return ReverseJoin(rev_components, "/")
}
func (me *fsInode) addChild(name string, ch *fsInode) {
func (me *fsInode) AddChild(name string, child FsNode) {
ch := child.(*fsInode)
if ch.inode.mountPoint == nil {
ch.Parent = me
}
ch.Name = name
}
func (me *fsInode) rmChild(name string, ch *fsInode) {
func (me *fsInode) RmChild(name string, child FsNode) {
ch := child.(*fsInode)
ch.Name = ".deleted"
ch.Parent = nil
}
......@@ -142,7 +147,7 @@ func (me *fsInode) OpenDir(context *Context) (chan DirEntry, Status) {
return me.fs.OpenDir(me.GetPath(), context)
}
func (me *fsInode) Mknod(name string, mode uint32, dev uint32, context *Context) (fi *os.FileInfo, newNode *fsInode, code Status) {
func (me *fsInode) Mknod(name string, mode uint32, dev uint32, context *Context) (fi *os.FileInfo, newNode FsNode, code Status) {
p := me.GetPath()
code = me.fs.Mknod(filepath.Join(p, name), mode, dev, context)
if code.Ok() {
......@@ -154,7 +159,7 @@ func (me *fsInode) Mknod(name string, mode uint32, dev uint32, context *Context)
return
}
func (me *fsInode) Mkdir(name string, mode uint32, context *Context) (fi *os.FileInfo, newNode *fsInode, code Status) {
func (me *fsInode) Mkdir(name string, mode uint32, context *Context) (fi *os.FileInfo, newNode FsNode, code Status) {
code = me.fs.Mkdir(filepath.Join(me.GetPath(), name), mode, context)
if code.Ok() {
newNode = me.createChild(name)
......@@ -173,7 +178,7 @@ func (me *fsInode) Rmdir(name string, context *Context) (code Status) {
return me.fs.Rmdir(filepath.Join(me.GetPath(), name), context)
}
func (me *fsInode) Symlink(name string, content string, context *Context) (fi *os.FileInfo, newNode *fsInode, code Status) {
func (me *fsInode) Symlink(name string, content string, context *Context) (fi *os.FileInfo, newNode FsNode, code Status) {
code = me.fs.Symlink(content, filepath.Join(me.GetPath(), name), context)
if code.Ok() {
newNode = me.createChild(name)
......@@ -185,16 +190,19 @@ func (me *fsInode) Symlink(name string, content string, context *Context) (fi *o
}
func (me *fsInode) Rename(oldName string, newParent *fsInode, newName string, context *Context) (code Status) {
func (me *fsInode) Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status) {
p := newParent.(*fsInode)
oldPath := filepath.Join(me.GetPath(), oldName)
newPath := filepath.Join(newParent.GetPath(), newName)
newPath := filepath.Join(p.GetPath(), newName)
return me.fs.Rename(oldPath, newPath, context)
}
func (me *fsInode) Link(name string, existing *fsInode, context *Context) (fi *os.FileInfo, newNode *fsInode, code Status) {
func (me *fsInode) Link(name string, existing FsNode, context *Context) (fi *os.FileInfo, newNode FsNode, code Status) {
newPath := filepath.Join(me.GetPath(), name)
oldPath := existing.GetPath()
e := existing.(*fsInode)
oldPath := e.GetPath()
code = me.fs.Link(oldPath, newPath, context)
if code.Ok() {
oldFi, _ := me.fs.GetAttr(oldPath, context)
......@@ -207,7 +215,7 @@ func (me *fsInode) Link(name string, existing *fsInode, context *Context) (fi *o
return
}
func (me *fsInode) Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *os.FileInfo, newNode *fsInode, code Status) {
func (me *fsInode) Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *os.FileInfo, newNode FsNode, code Status) {
fullPath := filepath.Join(me.GetPath(), name)
file, code = me.fs.Create(fullPath, flags, mode, context)
if code.Ok() {
......@@ -234,7 +242,7 @@ func (me *fsInode) Open(flags uint32, context *Context) (file File, code Status)
}
// TOOD - need context.
func (me *fsInode) Lookup(name string) (fi *os.FileInfo, node *fsInode, code Status) {
func (me *fsInode) Lookup(name string) (fi *os.FileInfo, node FsNode, code Status) {
fullPath := filepath.Join(me.GetPath(), name)
fi, code = me.fs.GetAttr(fullPath, nil)
if code.Ok() {
......
......@@ -24,7 +24,7 @@ type openedFile struct {
type fileSystemMount struct {
// The file system we mounted here.
fs *inodeFs
fs InodeFs
// Node that we were mounted on.
mountInode *inode
......
......@@ -23,7 +23,7 @@ func (me *FileSystemConnector) Lookup(header *InHeader, name string) (out *Entry
}
func (me *FileSystemConnector) internalMountLookup(mount *fileSystemMount, lookupCount int) (out *EntryOut, status Status, node *inode) {
fi, err := mount.fs.RootNode().GetAttr(nil, nil)
fi, err := mount.fs.Root().GetAttr(nil, nil)
if err == ENOENT && mount.options.NegativeTimeout > 0.0 {
return NegativeEntry(mount.options.NegativeTimeout), OK, nil
}
......@@ -199,7 +199,7 @@ func (me *FileSystemConnector) Mknod(header *InHeader, input *MknodIn, name stri
return out, code
}
func (me *FileSystemConnector) createChild(parent *inode, name string, fi *os.FileInfo, fsi *fsInode) (out *EntryOut, child *inode) {
func (me *FileSystemConnector) createChild(parent *inode, name string, fi *os.FileInfo, fsi FsNode) (out *EntryOut, child *inode) {
child = parent.createChild(name, fi.IsDirectory(), fsi, me)
out = parent.mount.fileInfoToEntry(fi)
out.Ino = child.nodeId
......
......@@ -25,7 +25,7 @@ type inode struct {
treeLock *sync.RWMutex
// All data below is protected by treeLock.
fsInode *fsInode
fsInode FsNode
children map[string]*inode
......@@ -43,7 +43,7 @@ type inode struct {
mount *fileSystemMount
}
func (me *inode) createChild(name string, isDir bool, fsi *fsInode, conn *FileSystemConnector) *inode {
func (me *inode) createChild(name string, isDir bool, fsi FsNode, conn *FileSystemConnector) *inode {
me.treeLock.Lock()
defer me.treeLock.Unlock()
......@@ -79,7 +79,7 @@ func (me *inode) addChild(name string, child *inode) {
}
me.children[name] = child
me.fsInode.addChild(name, child.fsInode)
me.fsInode.AddChild(name, child.fsInode)
}
// Must be called with treeLock for the mount held.
......@@ -87,7 +87,7 @@ func (me *inode) rmChild(name string) (ch *inode) {
ch = me.children[name]
if ch != nil {
me.children[name] = nil, false
me.fsInode.rmChild(name, ch.fsInode)
me.fsInode.RmChild(name, ch.fsInode)
}
return ch
}
......@@ -102,7 +102,7 @@ func (me *inode) mountFs(fs *inodeFs, opts *FileSystemOptions) {
}
me.mount = me.mountPoint
me.treeLock = &me.mountPoint.treeLock
me.fsInode = fs.RootNode()
me.fsInode = fs.Root()
me.fsInode.SetInode(me)
}
......
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