Commit 8caf9e25 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Add simplistic debugging through the FS.

parent 4bc4f55c
...@@ -39,20 +39,20 @@ func main() { ...@@ -39,20 +39,20 @@ func main() {
orig := flag.Arg(1) orig := flag.Arg(1)
loopbackfs := fuse.NewLoopbackFileSystem(orig) loopbackfs := fuse.NewLoopbackFileSystem(orig)
fs = loopbackfs fs = loopbackfs
debugFs := new(fuse.PathFilesystemDebug)
debugFs.Original = fs
fs = debugFs
timing := fuse.NewTimingPathFilesystem(fs) timing := fuse.NewTimingPathFilesystem(fs)
fs = timing fs = timing
if *debug {
pp := new(PathPrintingFs)
pp.Original = fs
fs = pp
}
var opts fuse.PathFileSystemConnectorOptions var opts fuse.PathFileSystemConnectorOptions
loopbackfs.FillOptions(&opts) loopbackfs.FillOptions(&opts)
conn := fuse.NewPathFileSystemConnector(fs) conn := fuse.NewPathFileSystemConnector(fs)
debugFs.Connector = conn
rawTiming := fuse.NewTimingRawFilesystem(conn) rawTiming := fuse.NewTimingRawFilesystem(conn)
conn.SetOptions(opts) conn.SetOptions(opts)
......
...@@ -19,6 +19,7 @@ GOFILES=misc.go\ ...@@ -19,6 +19,7 @@ GOFILES=misc.go\
timingrawfs.go \ timingrawfs.go \
xattr.go \ xattr.go \
devnull.go \ devnull.go \
pathdebug.go
include $(GOROOT)/src/Make.pkg include $(GOROOT)/src/Make.pkg
package fuse
import (
"fmt"
)
var _ = fmt.Println
type PathFilesystemDebug struct {
// TODO - use a generic callback system instead.
Connector *PathFileSystemConnector
WrappingPathFilesystem
}
func (me *PathFilesystemDebug) Open(path string, flags uint32) (fuseFile FuseFile, status Status) {
if path == ".debug" && me.Connector != nil {
return NewReadOnlyFile([]byte(me.Connector.DebugString())), OK
}
return me.Original.Open(path, flags)
}
func (me *PathFilesystemDebug) GetAttr(path string) (*Attr, Status) {
if path == ".debug" && me.Connector != nil {
return &Attr{
Mode: S_IFREG,
Size: uint64(len(me.Connector.DebugString())),
}, OK
}
return me.Original.GetAttr(path)
}
...@@ -89,7 +89,7 @@ func (me *inode) GetPath() (path string, mount *mountData) { ...@@ -89,7 +89,7 @@ func (me *inode) GetPath() (path string, mount *mountData) {
rev_components = append(rev_components, inode.Name) rev_components = append(rev_components, inode.Name)
} }
if inode == nil { if inode == nil {
panic("did not find parent with mount") panic(fmt.Sprintf("did not find parent with mount: %v", rev_components))
} }
mount = inode.mount mount = inode.mount
...@@ -166,6 +166,19 @@ type PathFileSystemConnector struct { ...@@ -166,6 +166,19 @@ type PathFileSystemConnector struct {
nextFreeHandle uint64 nextFreeHandle uint64
} }
func (me *PathFileSystemConnector) DebugString() string {
me.lock.RLock()
defer me.lock.RUnlock()
me.fileLock.RLock()
defer me.fileLock.RUnlock()
root := me.inodeMap[FUSE_ROOT_ID]
return fmt.Sprintf("Mounts %20d\nFiles %20d\nInodes %20d\n",
root.totalMountCount(),
len(me.openFiles), len(me.inodeMap))
}
func (me *PathFileSystemConnector) unregisterFile(node *inode, handle uint64) interface{} { func (me *PathFileSystemConnector) unregisterFile(node *inode, handle uint64) interface{} {
me.fileLock.Lock() me.fileLock.Lock()
defer me.fileLock.Unlock() defer me.fileLock.Unlock()
...@@ -347,7 +360,7 @@ func (me *PathFileSystemConnector) findInode(fullPath string) *inode { ...@@ -347,7 +360,7 @@ func (me *PathFileSystemConnector) findInode(fullPath string) *inode {
// Below routines should not access inodePathMap(ByInode) directly, // Below routines should not access inodePathMap(ByInode) directly,
// and there need no locking. // and there need no locking.
func NewPathFileSystemConnector(fs PathFilesystem) (out *PathFileSystemConnector) { func EmptyPathFileSystemConnector() (out *PathFileSystemConnector) {
out = new(PathFileSystemConnector) out = new(PathFileSystemConnector)
out.inodeMap = make(map[uint64]*inode) out.inodeMap = make(map[uint64]*inode)
out.openFiles = make(map[uint64]interface{}) out.openFiles = make(map[uint64]interface{})
...@@ -361,11 +374,15 @@ func NewPathFileSystemConnector(fs PathFilesystem) (out *PathFileSystemConnector ...@@ -361,11 +374,15 @@ func NewPathFileSystemConnector(fs PathFilesystem) (out *PathFileSystemConnector
out.options.NegativeTimeout = 0.0 out.options.NegativeTimeout = 0.0
out.options.AttrTimeout = 1.0 out.options.AttrTimeout = 1.0
out.options.EntryTimeout = 1.0 out.options.EntryTimeout = 1.0
out.verify()
return out;
}
func NewPathFileSystemConnector(fs PathFilesystem) (out *PathFileSystemConnector) {
out = EmptyPathFileSystemConnector()
if code := out.Mount("/", fs); code != OK { if code := out.Mount("/", fs); code != OK {
panic("root mount failed.") panic("root mount failed.")
} }
out.verify() out.verify()
return out return out
...@@ -770,14 +787,14 @@ func (me *PathFileSystemConnector) Create(header *InHeader, input *CreateIn, nam ...@@ -770,14 +787,14 @@ func (me *PathFileSystemConnector) Create(header *InHeader, input *CreateIn, nam
} }
func (me *PathFileSystemConnector) Release(header *InHeader, input *ReleaseIn) { func (me *PathFileSystemConnector) Release(header *InHeader, input *ReleaseIn) {
_, _, node := me.GetPath(header.NodeId) node := me.getInodeData(header.NodeId)
f := me.unregisterFile(node, input.Fh).(FuseFile) f := me.unregisterFile(node, input.Fh).(FuseFile)
f.Release() f.Release()
me.considerDropInode(node) me.considerDropInode(node)
} }
func (me *PathFileSystemConnector) ReleaseDir(header *InHeader, input *ReleaseIn) { func (me *PathFileSystemConnector) ReleaseDir(header *InHeader, input *ReleaseIn) {
_, _, node := me.GetPath(header.NodeId) node := me.getInodeData(header.NodeId)
d := me.unregisterFile(node, input.Fh).(RawFuseDir) d := me.unregisterFile(node, input.Fh).(RawFuseDir)
d.Release() d.Release()
me.considerDropInode(node) me.considerDropInode(node)
......
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