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() {
orig := flag.Arg(1)
loopbackfs := fuse.NewLoopbackFileSystem(orig)
fs = loopbackfs
debugFs := new(fuse.PathFilesystemDebug)
debugFs.Original = fs
fs = debugFs
timing := fuse.NewTimingPathFilesystem(fs)
fs = timing
if *debug {
pp := new(PathPrintingFs)
pp.Original = fs
fs = pp
}
var opts fuse.PathFileSystemConnectorOptions
loopbackfs.FillOptions(&opts)
conn := fuse.NewPathFileSystemConnector(fs)
debugFs.Connector = conn
rawTiming := fuse.NewTimingRawFilesystem(conn)
conn.SetOptions(opts)
......
......@@ -19,6 +19,7 @@ GOFILES=misc.go\
timingrawfs.go \
xattr.go \
devnull.go \
pathdebug.go
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) {
rev_components = append(rev_components, inode.Name)
}
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
......@@ -166,6 +166,19 @@ type PathFileSystemConnector struct {
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{} {
me.fileLock.Lock()
defer me.fileLock.Unlock()
......@@ -347,7 +360,7 @@ func (me *PathFileSystemConnector) findInode(fullPath string) *inode {
// Below routines should not access inodePathMap(ByInode) directly,
// and there need no locking.
func NewPathFileSystemConnector(fs PathFilesystem) (out *PathFileSystemConnector) {
func EmptyPathFileSystemConnector() (out *PathFileSystemConnector) {
out = new(PathFileSystemConnector)
out.inodeMap = make(map[uint64]*inode)
out.openFiles = make(map[uint64]interface{})
......@@ -361,11 +374,15 @@ func NewPathFileSystemConnector(fs PathFilesystem) (out *PathFileSystemConnector
out.options.NegativeTimeout = 0.0
out.options.AttrTimeout = 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 {
panic("root mount failed.")
}
out.verify()
return out
......@@ -770,14 +787,14 @@ func (me *PathFileSystemConnector) Create(header *InHeader, input *CreateIn, nam
}
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.Release()
me.considerDropInode(node)
}
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.Release()
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