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

fuse: remove HandleMap and Handled from the API.

parent 63eae3b7
...@@ -40,7 +40,7 @@ type FileSystemConnector struct { ...@@ -40,7 +40,7 @@ type FileSystemConnector struct {
nodeFs NodeFileSystem nodeFs NodeFileSystem
// Translate between uint64 handles and *Inode. // Translate between uint64 handles and *Inode.
inodeMap HandleMap inodeMap handleMap
// The root of the FUSE file system. // The root of the FUSE file system.
rootNode *Inode rootNode *Inode
...@@ -61,7 +61,7 @@ func NewFileSystemConnector(nodeFs NodeFileSystem, opts *FileSystemOptions) (c * ...@@ -61,7 +61,7 @@ func NewFileSystemConnector(nodeFs NodeFileSystem, opts *FileSystemOptions) (c *
opts = NewFileSystemOptions() opts = NewFileSystemOptions()
} }
c.nodeFs = nodeFs c.nodeFs = nodeFs
c.inodeMap = NewHandleMap(opts.PortableInodes) c.inodeMap = newHandleMap(opts.PortableInodes)
c.rootNode = newInode(true, nodeFs.Root()) c.rootNode = newInode(true, nodeFs.Root())
// Make sure we don't reuse generation numbers. // Make sure we don't reuse generation numbers.
......
...@@ -12,7 +12,7 @@ var _ = log.Println ...@@ -12,7 +12,7 @@ var _ = log.Println
// openedFile stores either an open dir or an open file. // openedFile stores either an open dir or an open file.
type openedFile struct { type openedFile struct {
Handled handled
WithFlags WithFlags
...@@ -40,7 +40,7 @@ type fileSystemMount struct { ...@@ -40,7 +40,7 @@ type fileSystemMount struct {
treeLock sync.RWMutex treeLock sync.RWMutex
// Manage filehandles of open files. // Manage filehandles of open files.
openFiles HandleMap openFiles handleMap
Debug bool Debug bool
...@@ -133,7 +133,7 @@ func (m *fileSystemMount) registerFileHandle(node *Inode, dir rawDir, f File, fl ...@@ -133,7 +133,7 @@ func (m *fileSystemMount) registerFileHandle(node *Inode, dir rawDir, f File, fl
b.WithFlags.File.SetInode(node) b.WithFlags.File.SetInode(node)
} }
node.openFiles = append(node.openFiles, b) node.openFiles = append(node.openFiles, b)
handle := m.openFiles.Register(&b.Handled) handle := m.openFiles.Register(&b.handled)
node.openFilesMutex.Unlock() node.openFilesMutex.Unlock()
return handle, b return handle, b
} }
......
...@@ -16,22 +16,22 @@ import ( ...@@ -16,22 +16,22 @@ import (
// you wish to export. // you wish to export.
// //
// This structure is thread-safe. // This structure is thread-safe.
type HandleMap interface { type handleMap interface {
Register(obj *Handled) uint64 Register(obj *handled) uint64
Count() int Count() int
Decode(uint64) *Handled Decode(uint64) *handled
Forget(handle uint64, count int) (bool, *Handled) Forget(handle uint64, count int) (bool, *handled)
Handle(obj *Handled) uint64 Handle(obj *handled) uint64
Has(uint64) bool Has(uint64) bool
} }
type Handled struct { type handled struct {
check uint32 check uint32
handle uint64 handle uint64
count int count int
} }
func (h *Handled) verify() { func (h *handled) verify() {
if h.count < 0 { if h.count < 0 {
log.Panicf("negative lookup count %d", h.count) log.Panicf("negative lookup count %d", h.count)
} }
...@@ -48,18 +48,18 @@ const _ALREADY_MSG = "Object already has a handle" ...@@ -48,18 +48,18 @@ const _ALREADY_MSG = "Object already has a handle"
type portableHandleMap struct { type portableHandleMap struct {
sync.RWMutex sync.RWMutex
used int used int
handles []*Handled handles []*handled
freeIds []uint64 freeIds []uint64
} }
func newPortableHandleMap() *portableHandleMap { func newPortableHandleMap() *portableHandleMap {
return &portableHandleMap{ return &portableHandleMap{
// Avoid handing out ID 0 and 1. // Avoid handing out ID 0 and 1.
handles: []*Handled{nil, nil}, handles: []*handled{nil, nil},
} }
} }
func (m *portableHandleMap) Register(obj *Handled) (handle uint64) { func (m *portableHandleMap) Register(obj *handled) (handle uint64) {
m.Lock() m.Lock()
if obj.count == 0 { if obj.count == 0 {
if obj.check != 0 { if obj.check != 0 {
...@@ -84,7 +84,7 @@ func (m *portableHandleMap) Register(obj *Handled) (handle uint64) { ...@@ -84,7 +84,7 @@ func (m *portableHandleMap) Register(obj *Handled) (handle uint64) {
return handle return handle
} }
func (m *portableHandleMap) Handle(obj *Handled) (h uint64) { func (m *portableHandleMap) Handle(obj *handled) (h uint64) {
m.RLock() m.RLock()
if obj.count == 0 { if obj.count == 0 {
h = 0 h = 0
...@@ -102,14 +102,14 @@ func (m *portableHandleMap) Count() int { ...@@ -102,14 +102,14 @@ func (m *portableHandleMap) Count() int {
return c return c
} }
func (m *portableHandleMap) Decode(h uint64) *Handled { func (m *portableHandleMap) Decode(h uint64) *handled {
m.RLock() m.RLock()
v := m.handles[h] v := m.handles[h]
m.RUnlock() m.RUnlock()
return v return v
} }
func (m *portableHandleMap) Forget(h uint64, count int) (forgotten bool, obj *Handled) { func (m *portableHandleMap) Forget(h uint64, count int) (forgotten bool, obj *handled) {
m.Lock() m.Lock()
obj = m.handles[h] obj = m.handles[h]
obj.count -= count obj.count -= count
...@@ -136,10 +136,10 @@ func (m *portableHandleMap) Has(h uint64) bool { ...@@ -136,10 +136,10 @@ func (m *portableHandleMap) Has(h uint64) bool {
// 32 bits version of HandleMap // 32 bits version of HandleMap
type int32HandleMap struct { type int32HandleMap struct {
mutex sync.Mutex mutex sync.Mutex
handles map[uint32]*Handled handles map[uint32]*handled
} }
func (m *int32HandleMap) Register(obj *Handled) (handle uint64) { func (m *int32HandleMap) Register(obj *handled) (handle uint64) {
m.mutex.Lock() m.mutex.Lock()
h := uint32(uintptr(unsafe.Pointer(obj))) h := uint32(uintptr(unsafe.Pointer(obj)))
if obj.count == 0 { if obj.count == 0 {
...@@ -159,7 +159,7 @@ func (m *int32HandleMap) Has(h uint64) bool { ...@@ -159,7 +159,7 @@ func (m *int32HandleMap) Has(h uint64) bool {
return ok return ok
} }
func (m *int32HandleMap) Handle(obj *Handled) uint64 { func (m *int32HandleMap) Handle(obj *handled) uint64 {
if obj.count == 0 { if obj.count == 0 {
return 0 return 0
} }
...@@ -175,7 +175,7 @@ func (m *int32HandleMap) Count() int { ...@@ -175,7 +175,7 @@ func (m *int32HandleMap) Count() int {
return c return c
} }
func (m *int32HandleMap) Forget(handle uint64, count int) (forgotten bool, obj *Handled) { func (m *int32HandleMap) Forget(handle uint64, count int) (forgotten bool, obj *handled) {
obj = m.Decode(handle) obj = m.Decode(handle)
m.mutex.Lock() m.mutex.Lock()
...@@ -192,13 +192,13 @@ func (m *int32HandleMap) Forget(handle uint64, count int) (forgotten bool, obj * ...@@ -192,13 +192,13 @@ func (m *int32HandleMap) Forget(handle uint64, count int) (forgotten bool, obj *
return forgotten, obj return forgotten, obj
} }
func (m *int32HandleMap) Decode(handle uint64) *Handled { func (m *int32HandleMap) Decode(handle uint64) *handled {
val := (*Handled)(unsafe.Pointer(uintptr(handle & ((1 << 32) - 1)))) val := (*handled)(unsafe.Pointer(uintptr(handle & ((1 << 32) - 1))))
return val return val
} }
func newInt32HandleMap() *int32HandleMap { func newInt32HandleMap() *int32HandleMap {
return &int32HandleMap{ return &int32HandleMap{
handles: make(map[uint32]*Handled), handles: make(map[uint32]*handled),
} }
} }
...@@ -208,7 +208,7 @@ func newInt32HandleMap() *int32HandleMap { ...@@ -208,7 +208,7 @@ func newInt32HandleMap() *int32HandleMap {
// map, so the Go runtime will not garbage collect it. // map, so the Go runtime will not garbage collect it.
type int64HandleMap struct { type int64HandleMap struct {
mutex sync.Mutex mutex sync.Mutex
handles map[uint64]*Handled handles map[uint64]*handled
nextFree uint32 nextFree uint32
} }
...@@ -228,19 +228,19 @@ func (m *int64HandleMap) verify() { ...@@ -228,19 +228,19 @@ func (m *int64HandleMap) verify() {
func newInt64HandleMap() *int64HandleMap { func newInt64HandleMap() *int64HandleMap {
return &int64HandleMap{ return &int64HandleMap{
handles: make(map[uint64]*Handled), handles: make(map[uint64]*handled),
nextFree: 1, // to make tests easier. nextFree: 1, // to make tests easier.
} }
} }
// NewHandleMap creates a new HandleMap. If verify is given, we // NewHandleMap creates a new HandleMap. If verify is given, we
// use remaining bits in the handle to store sanity check bits. // use remaining bits in the handle to store sanity check bits.
func NewHandleMap(portable bool) (hm HandleMap) { func newHandleMap(portable bool) (hm handleMap) {
if portable { if portable {
return newPortableHandleMap() return newPortableHandleMap()
} }
var obj *Handled var obj *handled
switch unsafe.Sizeof(obj) { switch unsafe.Sizeof(obj) {
case 8: case 8:
return newInt64HandleMap() return newInt64HandleMap()
...@@ -260,7 +260,7 @@ func (m *int64HandleMap) Count() int { ...@@ -260,7 +260,7 @@ func (m *int64HandleMap) Count() int {
return c return c
} }
func (m *int64HandleMap) Register(obj *Handled) (handle uint64) { func (m *int64HandleMap) Register(obj *handled) (handle uint64) {
defer m.verify() defer m.verify()
m.mutex.Lock() m.mutex.Lock()
...@@ -296,7 +296,7 @@ func (m *int64HandleMap) Register(obj *Handled) (handle uint64) { ...@@ -296,7 +296,7 @@ func (m *int64HandleMap) Register(obj *Handled) (handle uint64) {
return handle return handle
} }
func (m *int64HandleMap) Handle(obj *Handled) (handle uint64) { func (m *int64HandleMap) Handle(obj *handled) (handle uint64) {
if obj.count == 0 { if obj.count == 0 {
return 0 return 0
} }
...@@ -307,7 +307,7 @@ func (m *int64HandleMap) Handle(obj *Handled) (handle uint64) { ...@@ -307,7 +307,7 @@ func (m *int64HandleMap) Handle(obj *Handled) (handle uint64) {
return handle return handle
} }
func (m *int64HandleMap) Forget(handle uint64, count int) (forgotten bool, obj *Handled) { func (m *int64HandleMap) Forget(handle uint64, count int) (forgotten bool, obj *handled) {
defer m.verify() defer m.verify()
obj = m.Decode(handle) obj = m.Decode(handle)
...@@ -332,10 +332,10 @@ func (m *int64HandleMap) Has(handle uint64) bool { ...@@ -332,10 +332,10 @@ func (m *int64HandleMap) Has(handle uint64) bool {
return ok return ok
} }
func (m *int64HandleMap) Decode(handle uint64) (val *Handled) { func (m *int64HandleMap) Decode(handle uint64) (val *handled) {
ptrBits := uintptr(handle & (1<<45 - 1)) ptrBits := uintptr(handle & (1<<45 - 1))
check := uint32(handle >> 45) check := uint32(handle >> 45)
val = (*Handled)(unsafe.Pointer(ptrBits << 3)) val = (*handled)(unsafe.Pointer(ptrBits << 3))
if val.check != check { if val.check != check {
msg := fmt.Sprintf("handle check mismatch; handle has 0x%x, object has 0x%x", msg := fmt.Sprintf("handle check mismatch; handle has 0x%x, object has 0x%x",
check, val.check) check, val.check)
......
...@@ -25,10 +25,10 @@ func TestHandleMapUnaligned(t *testing.T) { ...@@ -25,10 +25,10 @@ func TestHandleMapUnaligned(t *testing.T) {
t.Log("skipping test for 32 bits") t.Log("skipping test for 32 bits")
return return
} }
hm := NewHandleMap(false) hm := newHandleMap(false)
b := make([]byte, 100) b := make([]byte, 100)
v := (*Handled)(unsafe.Pointer(&b[1])) v := (*handled)(unsafe.Pointer(&b[1]))
defer markSeen(t, "unaligned") defer markSeen(t, "unaligned")
hm.Register(v) hm.Register(v)
...@@ -38,8 +38,8 @@ func TestHandleMapUnaligned(t *testing.T) { ...@@ -38,8 +38,8 @@ func TestHandleMapUnaligned(t *testing.T) {
func TestHandleMapLookupCount(t *testing.T) { func TestHandleMapLookupCount(t *testing.T) {
for _, portable := range []bool{true, false} { for _, portable := range []bool{true, false} {
t.Log("portable:", portable) t.Log("portable:", portable)
v := new(Handled) v := new(handled)
hm := NewHandleMap(portable) hm := newHandleMap(portable)
h1 := hm.Register(v) h1 := hm.Register(v)
h2 := hm.Register(v) h2 := hm.Register(v)
...@@ -80,8 +80,8 @@ func TestHandleMapLookupCount(t *testing.T) { ...@@ -80,8 +80,8 @@ func TestHandleMapLookupCount(t *testing.T) {
func TestHandleMapBasic(t *testing.T) { func TestHandleMapBasic(t *testing.T) {
for _, portable := range []bool{true, false} { for _, portable := range []bool{true, false} {
t.Log("portable:", portable) t.Log("portable:", portable)
v := new(Handled) v := new(handled)
hm := NewHandleMap(portable) hm := newHandleMap(portable)
h := hm.Register(v) h := hm.Register(v)
t.Logf("Got handle 0x%x", h) t.Logf("Got handle 0x%x", h)
if !hm.Has(h) { if !hm.Has(h) {
...@@ -110,9 +110,9 @@ func TestHandleMapBasic(t *testing.T) { ...@@ -110,9 +110,9 @@ func TestHandleMapBasic(t *testing.T) {
} }
func TestHandleMapMultiple(t *testing.T) { func TestHandleMapMultiple(t *testing.T) {
hm := NewHandleMap(false) hm := newHandleMap(false)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
v := &Handled{} v := &handled{}
h := hm.Register(v) h := hm.Register(v)
if hm.Decode(h) != v { if hm.Decode(h) != v {
t.Fatal("address mismatch") t.Fatal("address mismatch")
...@@ -130,8 +130,8 @@ func TestHandleMapCheckFail(t *testing.T) { ...@@ -130,8 +130,8 @@ func TestHandleMapCheckFail(t *testing.T) {
} }
defer markSeen(t, "check mismatch") defer markSeen(t, "check mismatch")
v := new(Handled) v := new(handled)
hm := NewHandleMap(false) hm := newHandleMap(false)
h := hm.Register(v) h := hm.Register(v)
hm.Decode(h | (uint64(1) << 63)) hm.Decode(h | (uint64(1) << 63))
t.Error("Borked decode did not panic") t.Error("Borked decode did not panic")
......
...@@ -11,7 +11,7 @@ var _ = log.Println ...@@ -11,7 +11,7 @@ var _ = log.Println
// created automatically when the kernel does lookups inode, or by // created automatically when the kernel does lookups inode, or by
// explicitly by calling Inode.New(). // explicitly by calling Inode.New().
type Inode struct { type Inode struct {
handled Handled handled handled
// Generation number of the inode. Each (re)use of an inode // Generation number of the inode. Each (re)use of an inode
// should have a unique generation number. // should have a unique generation number.
...@@ -166,7 +166,7 @@ func (n *Inode) rmChild(name string) (ch *Inode) { ...@@ -166,7 +166,7 @@ func (n *Inode) rmChild(name string) (ch *Inode) {
func (n *Inode) mountFs(fs NodeFileSystem, opts *FileSystemOptions) { func (n *Inode) mountFs(fs NodeFileSystem, opts *FileSystemOptions) {
n.mountPoint = &fileSystemMount{ n.mountPoint = &fileSystemMount{
fs: fs, fs: fs,
openFiles: NewHandleMap(false), openFiles: newHandleMap(false),
mountInode: n, mountInode: n,
options: opts, options: opts,
} }
......
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