Commit 98c05019 authored by Jakob Unterwurzacher's avatar Jakob Unterwurzacher

misc: add comments, small logging improvements

Change-Id: I5612016b2bccf9e28186a83f2f420cefe1c30120
parent 5f1423b7
......@@ -4,9 +4,9 @@
package main
import (
"log"
"flag"
"fmt"
"log"
"os"
"path"
"path/filepath"
......
......@@ -114,6 +114,7 @@ func (c *FileSystemConnector) lookupUpdate(node *Inode) (id, generation uint64)
return
}
// forgetUpdate decrements the reference counter for "nodeID" by "forgetCount".
// Must run outside treeLock.
func (c *FileSystemConnector) forgetUpdate(nodeID uint64, forgetCount int) {
if nodeID == fuse.FUSE_ROOT_ID {
......
......@@ -68,8 +68,14 @@ func (c *FileSystemConnector) lookupMountUpdate(out *fuse.Attr, mount *fileSyste
return mount.mountInode, fuse.OK
}
// internalLookup executes a lookup without affecting NodeId reference counts.
func (c *FileSystemConnector) internalLookup(out *fuse.Attr, parent *Inode, name string, header *fuse.InHeader) (node *Inode, code fuse.Status) {
// We may already know the child because it was created using Create or Mkdir,
// from an earlier lookup, or because the nodes were created in advance
// (in-memory filesystems).
child := parent.GetChild(name)
if child != nil && child.mountPoint != nil {
return c.lookupMountUpdate(out, child.mountPoint)
}
......
......@@ -6,20 +6,27 @@ import (
)
// HandleMap translates objects in Go space to 64-bit handles that can
// be given out to -say- the linux kernel.
// be given out to -say- the linux kernel as NodeIds.
//
// The 32 bits version of this is a threadsafe wrapper around a map.
//
// To use it, include Handled as first member of the structure
// To use it, include "handled" as first member of the structure
// you wish to export.
//
// This structure is thread-safe.
type handleMap interface {
// Register stores "obj" and returns a unique (NodeId, generation) tuple.
Register(obj *handled) (handle, generation uint64)
Count() int
// Decode retrieves a stored object from its 64-bit handle.
Decode(uint64) *handled
// Forget decrements the reference counter for "handle" by "count" and drops
// the object if the refcount reaches zero.
// Returns a boolean whether the object was dropped and the object itself.
Forget(handle uint64, count int) (bool, *handled)
// Handle gets the object's NodeId.
Handle(obj *handled) uint64
// Has checks if NodeId is stored.
Has(uint64) bool
}
......@@ -45,10 +52,15 @@ const _ALREADY_MSG = "Object already has a handle"
type portableHandleMap struct {
sync.RWMutex
// The generation counter is incremented each time a NodeId is reused,
// hence the (NodeId, Generation) tuple is always unique.
generation uint64
used int
handles []*handled
freeIds []uint64
// Number of currently used handles
used int
// Array of Go objects indexed by NodeId
handles []*handled
// Free slots in the "handles" array
freeIds []uint64
}
func newPortableHandleMap() *portableHandleMap {
......
......@@ -163,6 +163,7 @@ func (n *Inode) RmChild(name string) (ch *Inode) {
//////////////////////////////////////////////////////////////
// private
// addChild adds "child" to our children under name "name".
// Must be called with treeLock for the mount held.
func (n *Inode) addChild(name string, child *Inode) {
if paranoia {
......@@ -177,6 +178,7 @@ func (n *Inode) addChild(name string, child *Inode) {
}
}
// rmChild drops "name" from our children.
// Must be called with treeLock for the mount held.
func (n *Inode) rmChild(name string) *Inode {
ch := n.children[name]
......
......@@ -229,12 +229,14 @@ func doGetAttr(server *Server, req *request) {
req.status = s
}
// doForget - forget one NodeId
func doForget(server *Server, req *request) {
if !server.opts.RememberInodes {
server.fileSystem.Forget(req.inHeader.NodeId, (*ForgetIn)(req.inData).Nlookup)
}
}
// doBatchForget - forget a list of NodeIds
func doBatchForget(server *Server, req *request) {
in := (*_BatchForgetIn)(req.inData)
wantBytes := uintptr(in.Count) * unsafe.Sizeof(_ForgetOne{})
......
......@@ -93,11 +93,11 @@ func FlagString(names map[int64]string, fl int64, def string) string {
}
func (me *ForgetIn) string() string {
return fmt.Sprintf("{%d}", me.Nlookup)
return fmt.Sprintf("{Nlookup=%d}", me.Nlookup)
}
func (me *_BatchForgetIn) string() string {
return fmt.Sprintf("{%d}", me.Count)
return fmt.Sprintf("{Count=%d}", me.Count)
}
func (me *MkdirIn) string() string {
......@@ -195,6 +195,7 @@ func (me *AttrOut) string() string {
me.AttrValid, me.AttrValidNsec, &me.Attr)
}
// Returned by LOOKUP
func (me *EntryOut) string() string {
return fmt.Sprintf("{NodeId: %d Generation=%d EntryValid=%d.%03d AttrValid=%d.%03d Attr=%v}",
me.NodeId, me.Generation, me.EntryValid, me.EntryValidNsec/1000000,
......
......@@ -51,13 +51,15 @@ func setRecursiveWritable(t *testing.T, dir string, writable bool) {
}
}
// Creates 3 directories on a temporary dir: /mnt with the overlayed
// (unionfs) mount, rw with modifiable data, and ro on the bottom.
func setupUfs(t *testing.T) (workdir string, cleanup func()) {
// Creates a temporary dir "wd" with 3 directories:
// mnt ... overlayed (unionfs) mount
// rw .... modifiable data
// ro .... read-only data
func setupUfs(t *testing.T) (wd string, cleanup func()) {
// Make sure system setting does not affect test.
syscall.Umask(0)
wd, _ := ioutil.TempDir("", "unionfs")
wd, _ = ioutil.TempDir("", "unionfs")
err := os.Mkdir(wd+"/mnt", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
......
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