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