Commit 76583006 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Hide members of inode.

parent 94429a4b
package fuse package fuse
// This file contains the internal logic of the // This file contains the internal logic of the
// FileSystemConnector. The functions for satisfying the raw interface are in // FileSystemConnector. The functions for satisfying the raw interface are in
// fsops.go // fsops.go
...@@ -43,7 +42,7 @@ func NewFileSystemConnector(fs FileSystem, opts *FileSystemOptions) (me *FileSys ...@@ -43,7 +42,7 @@ func NewFileSystemConnector(fs FileSystem, opts *FileSystemOptions) (me *FileSys
} }
me.inodeMap = NewHandleMap(!opts.SkipCheckHandles) me.inodeMap = NewHandleMap(!opts.SkipCheckHandles)
me.rootNode = me.newInode(true) me.rootNode = me.newInode(true)
me.rootNode.NodeId = FUSE_ROOT_ID me.rootNode.nodeId = FUSE_ROOT_ID
me.verify() me.verify()
me.mountRoot(fs, opts) me.mountRoot(fs, opts)
return me return me
...@@ -59,11 +58,11 @@ func (me *FileSystemConnector) verify() { ...@@ -59,11 +58,11 @@ func (me *FileSystemConnector) verify() {
func (me *FileSystemConnector) newInode(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)
data.fsInode = new(fsInode) data.fsInode = new(fsInode)
data.fsInode.inode = data data.fsInode.inode = data
if isDir { if isDir {
data.Children = make(map[string]*inode, initDirSize) data.children = make(map[string]*inode, initDirSize)
} }
return data return data
...@@ -75,29 +74,29 @@ func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bo ...@@ -75,29 +74,29 @@ func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bo
parent.treeLock.Lock() parent.treeLock.Lock()
defer parent.treeLock.Unlock() defer parent.treeLock.Unlock()
data, ok := parent.Children[name] data, ok := parent.children[name]
if !ok { if !ok {
data = me.newInode(isDir) data = me.newInode(isDir)
parent.addChild(name, data) parent.addChild(name, data)
data.mount = parent.mount data.mount = parent.mount
data.treeLock = &data.mount.treeLock data.treeLock = &data.mount.treeLock
} }
data.LookupCount += lookupCount data.lookupCount += lookupCount
return data return data
} }
func (me *FileSystemConnector) lookupMount(parent *inode, name string, lookupCount int) (mount *fileSystemMount) { func (me *FileSystemConnector) lookupMount(parent *inode, name string, lookupCount int) (mount *fileSystemMount) {
parent.treeLock.RLock() parent.treeLock.RLock()
defer parent.treeLock.RUnlock() defer parent.treeLock.RUnlock()
if parent.Mounts == nil { if parent.mounts == nil {
return nil return nil
} }
mount, ok := parent.Mounts[name] mount, ok := parent.mounts[name]
if ok { if ok {
mount.treeLock.Lock() mount.treeLock.Lock()
defer mount.treeLock.Unlock() defer mount.treeLock.Unlock()
mount.mountInode.LookupCount += lookupCount mount.mountInode.lookupCount += lookupCount
return mount return mount
} }
return nil return nil
...@@ -118,13 +117,13 @@ func (me *FileSystemConnector) forgetUpdate(nodeId uint64, forgetCount int) { ...@@ -118,13 +117,13 @@ func (me *FileSystemConnector) forgetUpdate(nodeId uint64, forgetCount int) {
node.treeLock.Lock() node.treeLock.Lock()
defer node.treeLock.Unlock() defer node.treeLock.Unlock()
node.LookupCount -= forgetCount node.lookupCount -= forgetCount
me.considerDropInode(node) me.considerDropInode(node)
} }
func (me *FileSystemConnector) considerDropInode(n *inode) (drop bool) { func (me *FileSystemConnector) considerDropInode(n *inode) (drop bool) {
delChildren := []string{} delChildren := []string{}
for k, v := range n.Children { for k, v := range n.children {
if v.mountPoint == nil && me.considerDropInode(v) { if v.mountPoint == nil && me.considerDropInode(v) {
delChildren = append(delChildren, k) delChildren = append(delChildren, k)
} }
...@@ -134,19 +133,19 @@ func (me *FileSystemConnector) considerDropInode(n *inode) (drop bool) { ...@@ -134,19 +133,19 @@ func (me *FileSystemConnector) considerDropInode(n *inode) (drop bool) {
if ch == nil { if ch == nil {
panic(fmt.Sprintf("trying to del child %q, but not present", k)) panic(fmt.Sprintf("trying to del child %q, but not present", k))
} }
me.inodeMap.Forget(ch.NodeId) me.inodeMap.Forget(ch.nodeId)
} }
if len(n.Children) > 0 || n.LookupCount > 0 { if len(n.children) > 0 || n.lookupCount > 0 {
return false return false
} }
if n == me.rootNode || n.mountPoint != nil { if n == me.rootNode || n.mountPoint != nil {
return false return false
} }
n.OpenFilesMutex.Lock() n.openFilesMutex.Lock()
defer n.OpenFilesMutex.Unlock() defer n.openFilesMutex.Unlock()
return len(n.OpenFiles) == 0 return len(n.openFiles) == 0
} }
func (me *FileSystemConnector) renameUpdate(oldParent *inode, oldName string, newParent *inode, newName string) { func (me *FileSystemConnector) renameUpdate(oldParent *inode, oldName string, newParent *inode, newName string) {
...@@ -196,7 +195,7 @@ func (me *FileSystemConnector) findLastKnownInode(fullPath string) (*inode, []st ...@@ -196,7 +195,7 @@ func (me *FileSystemConnector) findLastKnownInode(fullPath string) (*inode, []st
defer node.mountPoint.treeLock.RUnlock() defer node.mountPoint.treeLock.RUnlock()
} }
next := node.Children[component] next := node.children[component]
if next == nil { if next == nil {
return node, comps[i:] return node, comps[i:]
} }
...@@ -250,7 +249,7 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil ...@@ -250,7 +249,7 @@ 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
} }
...@@ -263,10 +262,10 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil ...@@ -263,10 +262,10 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil
node.mountFs(fs, opts) node.mountFs(fs, opts)
parent.addChild(base, node) parent.addChild(base, node)
if parent.Mounts == nil { if parent.mounts == nil {
parent.Mounts = make(map[string]*fileSystemMount) parent.mounts = make(map[string]*fileSystemMount)
} }
parent.Mounts[base] = node.mountPoint parent.mounts[base] = node.mountPoint
if me.Debug { if me.Debug {
log.Println("Mount: ", fs, "on dir", mountPoint, log.Println("Mount: ", fs, "on dir", mountPoint,
"parent", parent) "parent", parent)
...@@ -301,7 +300,7 @@ func (me *FileSystemConnector) Unmount(path string) Status { ...@@ -301,7 +300,7 @@ func (me *FileSystemConnector) Unmount(path string) Status {
parentNode.treeLock.Lock() parentNode.treeLock.Lock()
defer parentNode.treeLock.Unlock() defer parentNode.treeLock.Unlock()
mount := parentNode.Mounts[name] mount := parentNode.mounts[name]
if mount == nil { if mount == nil {
return EINVAL return EINVAL
} }
...@@ -318,11 +317,11 @@ func (me *FileSystemConnector) Unmount(path string) Status { ...@@ -318,11 +317,11 @@ func (me *FileSystemConnector) Unmount(path string) Status {
mount.mountInode = nil mount.mountInode = nil
mountInode.mountPoint = nil mountInode.mountPoint = nil
parentNode.Mounts[name] = nil, false parentNode.mounts[name] = nil, false
parentNode.Children[name] = nil, false parentNode.children[name] = nil, false
mount.fs.Unmount() mount.fs.Unmount()
me.fsInit.EntryNotify(parentNode.NodeId, name) me.fsInit.EntryNotify(parentNode.nodeId, name)
return OK return OK
} }
...@@ -336,7 +335,7 @@ func (me *FileSystemConnector) FileNotify(path string, off int64, length int64) ...@@ -336,7 +335,7 @@ func (me *FileSystemConnector) FileNotify(path string, off int64, length int64)
out := NotifyInvalInodeOut{ out := NotifyInvalInodeOut{
Length: length, Length: length,
Off: off, Off: off,
Ino: node.NodeId, Ino: node.nodeId,
} }
return me.fsInit.InodeNotify(&out) return me.fsInit.InodeNotify(&out)
} }
...@@ -347,16 +346,16 @@ func (me *FileSystemConnector) EntryNotify(dir string, name string) Status { ...@@ -347,16 +346,16 @@ func (me *FileSystemConnector) EntryNotify(dir string, name string) Status {
return ENOENT return ENOENT
} }
return me.fsInit.EntryNotify(node.NodeId, name) return me.fsInit.EntryNotify(node.nodeId, name)
} }
func (me *FileSystemConnector) Notify(path string) Status { func (me *FileSystemConnector) Notify(path string) Status {
node, rest := me.findLastKnownInode(path) node, rest := me.findLastKnownInode(path)
if len(rest) > 0 { if len(rest) > 0 {
return me.fsInit.EntryNotify(node.NodeId, rest[0]) return me.fsInit.EntryNotify(node.nodeId, rest[0])
} }
out := NotifyInvalInodeOut{ out := NotifyInvalInodeOut{
Ino: node.NodeId, Ino: node.nodeId,
} }
return me.fsInit.InodeNotify(&out) return me.fsInit.InodeNotify(&out)
} }
...@@ -70,27 +70,27 @@ func (me *FileSystemConnector) getOpenedFile(h uint64) *openedFile { ...@@ -70,27 +70,27 @@ func (me *FileSystemConnector) getOpenedFile(h uint64) *openedFile {
func (me *fileSystemMount) unregisterFileHandle(handle uint64, node *inode) *openedFile { func (me *fileSystemMount) unregisterFileHandle(handle uint64, node *inode) *openedFile {
obj := me.openFiles.Forget(handle) obj := me.openFiles.Forget(handle)
opened := (*openedFile)(unsafe.Pointer(obj)) opened := (*openedFile)(unsafe.Pointer(obj))
node.OpenFilesMutex.Lock() node.openFilesMutex.Lock()
defer node.OpenFilesMutex.Unlock() defer node.openFilesMutex.Unlock()
idx := -1 idx := -1
for i, v := range node.OpenFiles { for i, v := range node.openFiles {
if v == opened { if v == opened {
idx = i idx = i
break break
} }
} }
l := len(node.OpenFiles) l := len(node.openFiles)
node.OpenFiles[idx] = node.OpenFiles[l-1] node.openFiles[idx] = node.openFiles[l-1]
node.OpenFiles = node.OpenFiles[:l-1] node.openFiles = node.openFiles[:l-1]
return opened return opened
} }
func (me *fileSystemMount) registerFileHandle(node *inode, dir rawDir, f File, flags uint32) (uint64, *openedFile) { func (me *fileSystemMount) registerFileHandle(node *inode, dir rawDir, f File, flags uint32) (uint64, *openedFile) {
node.OpenFilesMutex.Lock() node.openFilesMutex.Lock()
defer node.OpenFilesMutex.Unlock() defer node.openFilesMutex.Unlock()
b := &openedFile{ b := &openedFile{
dir: dir, dir: dir,
file: f, file: f,
...@@ -103,7 +103,7 @@ func (me *fileSystemMount) registerFileHandle(node *inode, dir rawDir, f File, f ...@@ -103,7 +103,7 @@ func (me *fileSystemMount) registerFileHandle(node *inode, dir rawDir, f File, f
f = withFlags.File f = withFlags.File
} }
node.OpenFiles = append(node.OpenFiles, b) node.openFiles = append(node.openFiles, b)
handle := me.openFiles.Register(&b.Handled) handle := me.openFiles.Register(&b.Handled)
return handle, b return handle, b
} }
...@@ -32,9 +32,9 @@ func (me *FileSystemConnector) internalMountLookup(mount *fileSystemMount, looku ...@@ -32,9 +32,9 @@ func (me *FileSystemConnector) internalMountLookup(mount *fileSystemMount, looku
} }
mount.treeLock.Lock() mount.treeLock.Lock()
defer mount.treeLock.Unlock() defer mount.treeLock.Unlock()
mount.mountInode.LookupCount += lookupCount mount.mountInode.lookupCount += lookupCount
out = &EntryOut{ out = &EntryOut{
NodeId: mount.mountInode.NodeId, NodeId: mount.mountInode.nodeId,
Generation: 1, // where to get the generation? Generation: 1, // where to get the generation?
} }
mount.fileInfoToEntry(fi, out) mount.fileInfoToEntry(fi, out)
...@@ -56,11 +56,11 @@ func (me *FileSystemConnector) internalLookup(parent *inode, name string, lookup ...@@ -56,11 +56,11 @@ func (me *FileSystemConnector) internalLookup(parent *inode, name string, lookup
} }
node = me.lookupUpdate(parent, name, fi.IsDirectory(), lookupCount) node = me.lookupUpdate(parent, name, fi.IsDirectory(), lookupCount)
out = &EntryOut{ out = &EntryOut{
NodeId: node.NodeId, NodeId: node.nodeId,
Generation: 1, // where to get the generation? Generation: 1, // where to get the generation?
} }
parent.mount.fileInfoToEntry(fi, out) parent.mount.fileInfoToEntry(fi, out)
out.Attr.Ino = node.NodeId out.Attr.Ino = node.nodeId
return out, OK, node return out, OK, node
} }
......
...@@ -7,14 +7,14 @@ import ( ...@@ -7,14 +7,14 @@ import (
// The inode reflects the kernel's idea of the inode. // The inode reflects the kernel's idea of the inode.
type inode struct { type inode struct {
Handled handled Handled
// Constant during lifetime. // Constant during lifetime.
NodeId uint64 nodeId uint64
// Number of open files and its protection. // Number of open files and its protection.
OpenFilesMutex sync.Mutex openFilesMutex sync.Mutex
OpenFiles []*openedFile openFiles []*openedFile
// treeLock is a pointer to me.mount.treeLock; we need store // treeLock is a pointer to me.mount.treeLock; we need store
// this mutex separately, since unmount may set me.mount = nil // this mutex separately, since unmount may set me.mount = nil
...@@ -27,12 +27,12 @@ type inode struct { ...@@ -27,12 +27,12 @@ type inode struct {
// All data below is protected by treeLock. // All data below is protected by treeLock.
fsInode *fsInode fsInode *fsInode
Children map[string]*inode children map[string]*inode
// Contains directories that function as mounts. The entries // Contains directories that function as mounts. The entries
// are duplicated in Children. // are duplicated in children.
Mounts map[string]*fileSystemMount mounts map[string]*fileSystemMount
LookupCount int lookupCount int
// Non-nil if this is a mountpoint. // Non-nil if this is a mountpoint.
mountPoint *fileSystemMount mountPoint *fileSystemMount
...@@ -46,21 +46,21 @@ type inode struct { ...@@ -46,21 +46,21 @@ type inode struct {
// Must be called with treeLock for the mount held. // Must be called with treeLock for the mount held.
func (me *inode) addChild(name string, child *inode) { func (me *inode) addChild(name string, child *inode) {
if paranoia { if paranoia {
ch := me.Children[name] ch := me.children[name]
if ch != nil { if ch != nil {
panic(fmt.Sprintf("Already have an inode with same name: %v: %v", name, ch)) panic(fmt.Sprintf("Already have an inode with same name: %v: %v", name, ch))
} }
} }
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.
func (me *inode) rmChild(name string) (ch *inode) { 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
...@@ -80,7 +80,7 @@ func (me *inode) mountFs(fs FileSystem, opts *FileSystemOptions) { ...@@ -80,7 +80,7 @@ func (me *inode) mountFs(fs FileSystem, opts *FileSystemOptions) {
// 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 {
if v.mountPoint != nil { if v.mountPoint != nil {
// This access may be out of date, but it is no // This access may be out of date, but it is no
// problem to err on the safe side. // problem to err on the safe side.
...@@ -91,20 +91,20 @@ func (me *inode) canUnmount() bool { ...@@ -91,20 +91,20 @@ func (me *inode) canUnmount() bool {
} }
} }
me.OpenFilesMutex.Lock() me.openFilesMutex.Lock()
defer me.OpenFilesMutex.Unlock() defer me.openFilesMutex.Unlock()
return len(me.OpenFiles) == 0 return len(me.openFiles) == 0
} }
func (me *inode) IsDir() bool { func (me *inode) IsDir() bool {
return me.Children != nil return me.children != nil
} }
func (me *inode) getMountDirEntries() (out []DirEntry) { func (me *inode) getMountDirEntries() (out []DirEntry) {
me.treeLock.RLock() me.treeLock.RLock()
defer me.treeLock.RUnlock() defer me.treeLock.RUnlock()
for k, _ := range me.Mounts { for k, _ := range me.mounts {
out = append(out, DirEntry{ out = append(out, DirEntry{
Name: k, Name: k,
Mode: S_IFDIR, Mode: S_IFDIR,
...@@ -115,10 +115,10 @@ func (me *inode) getMountDirEntries() (out []DirEntry) { ...@@ -115,10 +115,10 @@ func (me *inode) getMountDirEntries() (out []DirEntry) {
// Returns any open file, preferably a r/w one. // Returns any open file, preferably a r/w one.
func (me *inode) getAnyFile() (file File) { func (me *inode) getAnyFile() (file File) {
me.OpenFilesMutex.Lock() me.openFilesMutex.Lock()
defer me.OpenFilesMutex.Unlock() defer me.openFilesMutex.Unlock()
for _, f := range me.OpenFiles { for _, f := range me.openFiles {
if file == nil || f.OpenFlags & O_ANYWRITE != 0 { if file == nil || f.OpenFlags & O_ANYWRITE != 0 {
file = f.file file = f.file
} }
...@@ -128,10 +128,10 @@ func (me *inode) getAnyFile() (file File) { ...@@ -128,10 +128,10 @@ func (me *inode) getAnyFile() (file File) {
// Returns an open writable file for the given inode. // Returns an open writable file for the given inode.
func (me *inode) getWritableFiles() (files []File) { func (me *inode) getWritableFiles() (files []File) {
me.OpenFilesMutex.Lock() me.openFilesMutex.Lock()
defer me.OpenFilesMutex.Unlock() defer me.openFilesMutex.Unlock()
for _, f := range me.OpenFiles { for _, f := range me.openFiles {
if f.OpenFlags & O_ANYWRITE != 0 { if f.OpenFlags & O_ANYWRITE != 0 {
files = append(files, f.file) files = append(files, f.file)
} }
...@@ -152,14 +152,14 @@ func (me *inode) verify(cur *fileSystemMount) { ...@@ -152,14 +152,14 @@ func (me *inode) verify(cur *fileSystemMount) {
panic(fmt.Sprintf("me.mount not set correctly %v %v", me.mount, cur)) panic(fmt.Sprintf("me.mount not set correctly %v %v", me.mount, cur))
} }
for name, m := range me.Mounts { for name, m := range me.mounts {
if m.mountInode != me.Children[name] { if m.mountInode != me.children[name] {
panic(fmt.Sprintf("mountpoint parent mismatch: node:%v name:%v ch:%v", panic(fmt.Sprintf("mountpoint parent mismatch: node:%v name:%v ch:%v",
me.mountPoint, name, me.Children)) me.mountPoint, name, me.children))
} }
} }
for _, ch := range me.Children { for _, ch := range me.children {
if ch == nil { if ch == nil {
panic("Found nil child.") panic("Found nil child.")
} }
......
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