Commit 015cd0f4 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Split out root mount code.

parent 608f78e2
...@@ -58,17 +58,9 @@ type fileSystemMount struct { ...@@ -58,17 +58,9 @@ type fileSystemMount struct {
openFiles *HandleMap openFiles *HandleMap
} }
func newMount(fs FileSystem) *fileSystemMount { func (me *FileSystemConnector) getOpenedFile(h uint64) *openedFile {
return &fileSystemMount{ b := (*openedFile)(unsafe.Pointer(DecodeHandle(h)))
fs: fs, return b
openFiles: NewHandleMap(),
}
}
func (me *fileSystemMount) setOwner(attr *Attr) {
if me.options.Owner != nil {
attr.Owner = *me.options.Owner
}
} }
func (me *fileSystemMount) unregisterFileHandle(node *inode, handle uint64) *openedFile { func (me *fileSystemMount) unregisterFileHandle(node *inode, handle uint64) *openedFile {
...@@ -114,9 +106,9 @@ type inode struct { ...@@ -114,9 +106,9 @@ type inode struct {
OpenCountMutex sync.Mutex OpenCountMutex sync.Mutex
OpenCount int OpenCount int
// me.mount.treeLock; we need store this mutex separately, // treeLock is a pointer to me.mount.treeLock; we need store
// since unmount may set me.mount = nil during Unmount(). // this mutex separately, since unmount may set me.mount = nil
// Constant during lifetime. // during Unmount(). Constant during lifetime.
// //
// If multiple treeLocks must be acquired, the treeLocks // If multiple treeLocks must be acquired, the treeLocks
// closer to the root must be acquired first. // closer to the root must be acquired first.
...@@ -138,6 +130,18 @@ type inode struct { ...@@ -138,6 +130,18 @@ type inode struct {
mount *fileSystemMount mount *fileSystemMount
} }
// Can only be called on untouched inodes.
func (me *inode) mountFs(fs FileSystem, opts *FileSystemOptions) {
me.mountPoint = &fileSystemMount{
fs: fs,
openFiles: NewHandleMap(),
mountInode: me,
options: opts,
}
me.mount = me.mountPoint
me.treeLock = &me.mountPoint.treeLock
}
// Must be called with treeLock held. // Must be called with treeLock held.
func (me *inode) canUnmount() bool { func (me *inode) canUnmount() bool {
for _, v := range me.Children { for _, v := range me.Children {
...@@ -302,7 +306,6 @@ type FileSystemConnector struct { ...@@ -302,7 +306,6 @@ type FileSystemConnector struct {
Debug bool Debug bool
////////////////
inodeMap *HandleMap inodeMap *HandleMap
rootNode *inode rootNode *inode
} }
...@@ -311,12 +314,6 @@ func (me *FileSystemConnector) Statistics() string { ...@@ -311,12 +314,6 @@ func (me *FileSystemConnector) Statistics() string {
return fmt.Sprintf("Inodes %20d\n", me.inodeMap.Count()) return fmt.Sprintf("Inodes %20d\n", me.inodeMap.Count())
} }
func (me *FileSystemConnector) getOpenedFile(h uint64) *openedFile {
b := (*openedFile)(unsafe.Pointer(DecodeHandle(h)))
return b
}
func (me *FileSystemConnector) verify() { func (me *FileSystemConnector) verify() {
if !paranoia { if !paranoia {
return return
...@@ -326,13 +323,9 @@ func (me *FileSystemConnector) verify() { ...@@ -326,13 +323,9 @@ func (me *FileSystemConnector) verify() {
root.verify(me.rootNode.mountPoint) root.verify(me.rootNode.mountPoint)
} }
func (me *FileSystemConnector) newInode(root bool, isDir bool) *inode { func (me *FileSystemConnector) newInode(isDir bool) *inode {
data := new(inode) data := new(inode)
data.NodeId = me.inodeMap.Register(&data.Handled) data.NodeId = me.inodeMap.Register(&data.Handled)
if root {
me.rootNode = data
data.NodeId = FUSE_ROOT_ID
}
if isDir { if isDir {
data.Children = make(map[string]*inode, initDirSize) data.Children = make(map[string]*inode, initDirSize)
} }
...@@ -348,7 +341,7 @@ func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bo ...@@ -348,7 +341,7 @@ func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bo
data, ok := parent.Children[name] data, ok := parent.Children[name]
if !ok { if !ok {
data = me.newInode(false, isDir) data = me.newInode(isDir)
data.Name = name data.Name = name
data.setParent(parent) data.setParent(parent)
data.mount = parent.mount data.mount = parent.mount
...@@ -478,13 +471,14 @@ func (me *FileSystemConnector) findInode(fullPath string) *inode { ...@@ -478,13 +471,14 @@ func (me *FileSystemConnector) findInode(fullPath string) *inode {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
func EmptyFileSystemConnector() (out *FileSystemConnector) { func EmptyFileSystemConnector() (me *FileSystemConnector) {
out = new(FileSystemConnector) me = new(FileSystemConnector)
out.inodeMap = NewHandleMap() me.inodeMap = NewHandleMap()
out.newInode(true, true) me.rootNode = me.newInode(true)
out.verify() me.rootNode.NodeId = FUSE_ROOT_ID
return out me.verify()
return me
} }
// Mount() generates a synthetic directory node, and mounts the file // Mount() generates a synthetic directory node, and mounts the file
...@@ -499,11 +493,13 @@ func EmptyFileSystemConnector() (out *FileSystemConnector) { ...@@ -499,11 +493,13 @@ func EmptyFileSystemConnector() (out *FileSystemConnector) {
// //
// EBUSY: the intended mount point already exists. // EBUSY: the intended mount point already exists.
func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *FileSystemOptions) Status { func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *FileSystemOptions) Status {
var node *inode if mountPoint == "/" || mountPoint == "" {
var parent *inode me.mountRoot(fs, opts)
if mountPoint != "/" { return OK
}
dirParent, base := filepath.Split(mountPoint) dirParent, base := filepath.Split(mountPoint)
parent = me.findInode(dirParent) parent := me.findInode(dirParent)
if parent == nil { if parent == nil {
log.Println("Could not find mountpoint parent:", dirParent) log.Println("Could not find mountpoint parent:", dirParent)
return ENOENT return ENOENT
...@@ -514,45 +510,41 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil ...@@ -514,45 +510,41 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil
if parent.mount == nil { if parent.mount == nil {
return ENOENT return ENOENT
} }
node = parent.Children[base] node := parent.Children[base]
if node != nil { if node != nil {
return EBUSY return EBUSY
} }
node = me.newInode(false, true) node = me.newInode(true)
node.Name = base node.Name = base
node.setParent(parent) node.setParent(parent)
if opts == nil { if opts == nil {
opts = me.rootNode.mountPoint.options opts = me.rootNode.mountPoint.options
} }
} else {
node = me.rootNode
if opts == nil {
opts = NewFileSystemOptions()
}
}
node.mountPoint = newMount(fs) node.mountFs(fs, opts)
node.treeLock = &node.mountPoint.treeLock
node.mount = node.mountPoint
node.mountPoint.mountInode = node
if parent != nil {
if parent.Mounts == nil { if parent.Mounts == nil {
parent.Mounts = make(map[string]*fileSystemMount) parent.Mounts = make(map[string]*fileSystemMount)
} }
parent.Mounts[node.Name] = node.mountPoint parent.Mounts[node.Name] = node.mountPoint
}
node.mountPoint.options = opts
if me.Debug { if me.Debug {
log.Println("Mount: ", fs, "on dir", mountPoint, log.Println("Mount: ", fs, "on dir", mountPoint,
"parent", parent) "parent", parent)
} }
fs.Mount(me) fs.Mount(me)
me.verify()
return OK return OK
} }
func (me *FileSystemConnector) mountRoot(fs FileSystem, opts *FileSystemOptions) {
if opts == nil {
opts = NewFileSystemOptions()
}
me.rootNode.mountFs(fs, opts)
fs.Mount(me)
me.verify()
}
// Unmount() tries to unmount the given path. Because of kernel-side // Unmount() tries to unmount the given path. Because of kernel-side
// caching, it may takes a few seconds for files to disappear when // caching, it may takes a few seconds for files to disappear when
// viewed from user-space. // viewed from user-space.
...@@ -618,17 +610,6 @@ func (me *FileSystemConnector) unsafeUnmountNode(node *inode) { ...@@ -618,17 +610,6 @@ func (me *FileSystemConnector) unsafeUnmountNode(node *inode) {
unmounted.fs.Unmount() unmounted.fs.Unmount()
} }
func (me *FileSystemConnector) GetPath(nodeid uint64) (path string, mount *fileSystemMount, node *inode) {
n := me.getInodeData(nodeid)
p, m := n.GetPath()
if me.Debug {
log.Printf("Node %v = '%s'", nodeid, n.GetFullPath())
}
return p, m, n
}
func (me *FileSystemConnector) getOpenFileData(nodeid uint64, fh uint64) (f File, m *fileSystemMount, p string) { func (me *FileSystemConnector) getOpenFileData(nodeid uint64, fh uint64) (f File, m *fileSystemMount, p string) {
node := me.getInodeData(nodeid) node := me.getInodeData(nodeid)
node.treeLock.RLock() node.treeLock.RLock()
......
...@@ -14,16 +14,28 @@ var _ = fmt.Println ...@@ -14,16 +14,28 @@ var _ = fmt.Println
func NewFileSystemConnector(fs FileSystem, opts *FileSystemOptions) (out *FileSystemConnector) { func NewFileSystemConnector(fs FileSystem, opts *FileSystemOptions) (out *FileSystemConnector) {
out = EmptyFileSystemConnector() out = EmptyFileSystemConnector()
if code := out.Mount("/", fs, opts); code != OK { out.mountRoot(fs, opts)
panic("root mount failed.") return out
}
func (me *FileSystemConnector) GetPath(nodeid uint64) (path string, mount *fileSystemMount, node *inode) {
n := me.getInodeData(nodeid)
p, m := n.GetPath()
if me.Debug {
log.Printf("Node %v = '%s'", nodeid, n.GetFullPath())
} }
out.verify()
return out return p, m, n
} }
func (me *FileSystemConnector) Destroy(h *InHeader, input *InitIn) { func (me *FileSystemConnector) Destroy(h *InHeader, input *InitIn) {
// TODO - umount all. }
func (me *fileSystemMount) setOwner(attr *Attr) {
if me.options.Owner != nil {
attr.Owner = *me.options.Owner
}
} }
func (me *FileSystemConnector) Lookup(header *InHeader, name string) (out *EntryOut, status Status) { func (me *FileSystemConnector) Lookup(header *InHeader, name string) (out *EntryOut, status Status) {
......
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