Commit 03a74a9f authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Access mount.treeLock directly.

parent c24ef376
package fuse package fuse
import ( import (
"syscall" "syscall"
) )
......
package fuse package fuse
import ( import (
"syscall" "syscall"
) )
......
...@@ -202,7 +202,6 @@ type ReadOnlyFile struct { ...@@ -202,7 +202,6 @@ type ReadOnlyFile struct {
var _ = (File)((*ReadOnlyFile)(nil)) var _ = (File)((*ReadOnlyFile)(nil))
func (f *ReadOnlyFile) String() string { func (f *ReadOnlyFile) String() string {
return fmt.Sprintf("ReadOnlyFile(%s)", f.File.String()) return fmt.Sprintf("ReadOnlyFile(%s)", f.File.String())
} }
......
...@@ -130,9 +130,9 @@ func (c *FileSystemConnector) forgetUpdate(nodeID uint64, forgetCount int) { ...@@ -130,9 +130,9 @@ func (c *FileSystemConnector) forgetUpdate(nodeID uint64, forgetCount int) {
if forgotten, handled := c.inodeMap.Forget(nodeID, forgetCount); forgotten { if forgotten, handled := c.inodeMap.Forget(nodeID, forgetCount); forgotten {
node := (*Inode)(unsafe.Pointer(handled)) node := (*Inode)(unsafe.Pointer(handled))
node.treeLock.Lock() node.mount.treeLock.Lock()
c.recursiveConsiderDropInode(node) c.recursiveConsiderDropInode(node)
node.treeLock.Unlock() node.mount.treeLock.Unlock()
} }
// TODO - try to drop children even forget was not successful. // TODO - try to drop children even forget was not successful.
c.verify() c.verify()
...@@ -193,8 +193,8 @@ func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []st ...@@ -193,8 +193,8 @@ func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []st
node := parent node := parent
if node.mountPoint == nil { if node.mountPoint == nil {
node.treeLock.RLock() node.mount.treeLock.RLock()
defer node.treeLock.RUnlock() defer node.mount.treeLock.RUnlock()
} }
for i, component := range comps { for i, component := range comps {
...@@ -203,8 +203,8 @@ func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []st ...@@ -203,8 +203,8 @@ func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []st
} }
if node.mountPoint != nil { if node.mountPoint != nil {
node.treeLock.RLock() node.mount.treeLock.RLock()
defer node.treeLock.RUnlock() defer node.mount.treeLock.RUnlock()
} }
next := node.children[component] next := node.children[component]
...@@ -257,8 +257,8 @@ func (c *FileSystemConnector) MountRoot(nodeFs NodeFileSystem, opts *FileSystemO ...@@ -257,8 +257,8 @@ func (c *FileSystemConnector) MountRoot(nodeFs NodeFileSystem, opts *FileSystemO
// EBUSY: the intended mount point already exists. // EBUSY: the intended mount point already exists.
func (c *FileSystemConnector) Mount(parent *Inode, name string, nodeFs NodeFileSystem, opts *FileSystemOptions) Status { func (c *FileSystemConnector) Mount(parent *Inode, name string, nodeFs NodeFileSystem, opts *FileSystemOptions) Status {
defer c.verify() defer c.verify()
parent.treeLock.Lock() parent.mount.treeLock.Lock()
defer parent.treeLock.Unlock() defer parent.mount.treeLock.Unlock()
node := parent.children[name] node := parent.children[name]
if node != nil { if node != nil {
return EBUSY return EBUSY
...@@ -298,8 +298,8 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status { ...@@ -298,8 +298,8 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status {
// Must lock parent to update tree structure. // Must lock parent to update tree structure.
parentNode := node.mountPoint.parentInode parentNode := node.mountPoint.parentInode
parentNode.treeLock.Lock() parentNode.mount.treeLock.Lock()
defer parentNode.treeLock.Unlock() defer parentNode.mount.treeLock.Unlock()
mount := node.mountPoint mount := node.mountPoint
name := node.mountPoint.mountName() name := node.mountPoint.mountName()
...@@ -307,8 +307,8 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status { ...@@ -307,8 +307,8 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status {
return EBUSY return EBUSY
} }
node.treeLock.Lock() node.mount.treeLock.Lock()
defer node.treeLock.Unlock() defer node.mount.treeLock.Unlock()
if mount.mountInode != node { if mount.mountInode != node {
log.Panicf("got two different mount inodes %v vs %v", log.Panicf("got two different mount inodes %v vs %v",
......
...@@ -34,6 +34,9 @@ type fileSystemMount struct { ...@@ -34,6 +34,9 @@ type fileSystemMount struct {
// Protects Children hashmaps within the mount. treeLock // Protects Children hashmaps within the mount. treeLock
// should be acquired before openFilesLock. // should be acquired before openFilesLock.
//
// If multiple treeLocks must be acquired, the treeLocks
// closer to the root must be acquired first.
treeLock sync.RWMutex treeLock sync.RWMutex
// Manage filehandles of open files. // Manage filehandles of open files.
......
...@@ -105,7 +105,7 @@ func (c *FileSystemConnector) GetAttr(out *raw.AttrOut, context *Context, input ...@@ -105,7 +105,7 @@ func (c *FileSystemConnector) GetAttr(out *raw.AttrOut, context *Context, input
node := c.toInode(context.NodeId) node := c.toInode(context.NodeId)
var f File var f File
if input.Flags() & raw.FUSE_GETATTR_FH != 0 { if input.Flags()&raw.FUSE_GETATTR_FH != 0 {
if opened := node.mount.getOpenedFile(input.Fh()); opened != nil { if opened := node.mount.getOpenedFile(input.Fh()); opened != nil {
f = opened.WithFlags.File f = opened.WithFlags.File
} }
......
...@@ -24,7 +24,7 @@ type HandleMap interface { ...@@ -24,7 +24,7 @@ type HandleMap interface {
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
} }
...@@ -290,7 +290,7 @@ func (m *int64HandleMap) Register(obj *Handled) (handle uint64) { ...@@ -290,7 +290,7 @@ func (m *int64HandleMap) Register(obj *Handled) (handle uint64) {
} else { } else {
handle = m.Handle(obj) handle = m.Handle(obj)
} }
obj.count ++ obj.count++
m.mutex.Unlock() m.mutex.Unlock()
return handle return handle
...@@ -307,7 +307,6 @@ func (m *int64HandleMap) Handle(obj *Handled) (handle uint64) { ...@@ -307,7 +307,6 @@ 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()
......
...@@ -28,14 +28,6 @@ type Inode struct { ...@@ -28,14 +28,6 @@ type Inode struct {
// Unmount() when it is set to nil. // Unmount() when it is set to nil.
mount *fileSystemMount mount *fileSystemMount
// treeLock is a pointer to me.mount.treeLock. We store it
// here for convenience. Constant during lifetime of the
// inode.
//
// If multiple treeLocks must be acquired, the treeLocks
// closer to the root must be acquired first.
treeLock *sync.RWMutex
// All data below is protected by treeLock. // All data below is protected by treeLock.
children map[string]*Inode children map[string]*Inode
...@@ -70,12 +62,12 @@ func (n *Inode) AnyFile() (file File) { ...@@ -70,12 +62,12 @@ func (n *Inode) AnyFile() (file File) {
} }
func (n *Inode) Children() (out map[string]*Inode) { func (n *Inode) Children() (out map[string]*Inode) {
n.treeLock.RLock() n.mount.treeLock.RLock()
out = make(map[string]*Inode, len(n.children)) out = make(map[string]*Inode, len(n.children))
for k, v := range n.children { for k, v := range n.children {
out[k] = v out[k] = v
} }
n.treeLock.RUnlock() n.mount.treeLock.RUnlock()
return out return out
} }
...@@ -83,14 +75,14 @@ func (n *Inode) Children() (out map[string]*Inode) { ...@@ -83,14 +75,14 @@ func (n *Inode) Children() (out map[string]*Inode) {
// FsChildren returns all the children from the same filesystem. It // FsChildren returns all the children from the same filesystem. It
// will skip mountpoints. // will skip mountpoints.
func (n *Inode) FsChildren() (out map[string]*Inode) { func (n *Inode) FsChildren() (out map[string]*Inode) {
n.treeLock.RLock() n.mount.treeLock.RLock()
out = map[string]*Inode{} out = map[string]*Inode{}
for k, v := range n.children { for k, v := range n.children {
if v.mount == n.mount { if v.mount == n.mount {
out[k] = v out[k] = v
} }
} }
n.treeLock.RUnlock() n.mount.treeLock.RUnlock()
return out return out
} }
...@@ -119,15 +111,15 @@ func (n *Inode) IsDir() bool { ...@@ -119,15 +111,15 @@ func (n *Inode) IsDir() bool {
func (n *Inode) New(isDir bool, fsi FsNode) *Inode { func (n *Inode) New(isDir bool, fsi FsNode) *Inode {
ch := newInode(isDir, fsi) ch := newInode(isDir, fsi)
ch.mount = n.mount ch.mount = n.mount
ch.treeLock = n.treeLock ch.mount.treeLock = n.mount.treeLock
n.generation = ch.mount.connector.nextGeneration() n.generation = ch.mount.connector.nextGeneration()
return ch return ch
} }
func (n *Inode) GetChild(name string) (child *Inode) { func (n *Inode) GetChild(name string) (child *Inode) {
n.treeLock.RLock() n.mount.treeLock.RLock()
child = n.children[name] child = n.children[name]
n.treeLock.RUnlock() n.mount.treeLock.RUnlock()
return child return child
} }
...@@ -136,15 +128,15 @@ func (n *Inode) AddChild(name string, child *Inode) { ...@@ -136,15 +128,15 @@ func (n *Inode) AddChild(name string, child *Inode) {
if child == nil { if child == nil {
log.Panicf("adding nil child as %q", name) log.Panicf("adding nil child as %q", name)
} }
n.treeLock.Lock() n.mount.treeLock.Lock()
n.addChild(name, child) n.addChild(name, child)
n.treeLock.Unlock() n.mount.treeLock.Unlock()
} }
func (n *Inode) RmChild(name string) (ch *Inode) { func (n *Inode) RmChild(name string) (ch *Inode) {
n.treeLock.Lock() n.mount.treeLock.Lock()
ch = n.rmChild(name) ch = n.rmChild(name)
n.treeLock.Unlock() n.mount.treeLock.Unlock()
return return
} }
...@@ -180,7 +172,6 @@ func (n *Inode) mountFs(fs NodeFileSystem, opts *FileSystemOptions) { ...@@ -180,7 +172,6 @@ func (n *Inode) mountFs(fs NodeFileSystem, opts *FileSystemOptions) {
options: opts, options: opts,
} }
n.mount = n.mountPoint n.mount = n.mountPoint
n.treeLock = &n.mountPoint.treeLock
} }
// Must be called with treeLock held. // Must be called with treeLock held.
...@@ -203,7 +194,7 @@ func (n *Inode) canUnmount() bool { ...@@ -203,7 +194,7 @@ func (n *Inode) canUnmount() bool {
} }
func (n *Inode) getMountDirEntries() (out []DirEntry) { func (n *Inode) getMountDirEntries() (out []DirEntry) {
n.treeLock.RLock() n.mount.treeLock.RLock()
for k, v := range n.children { for k, v := range n.children {
if v.mountPoint != nil { if v.mountPoint != nil {
out = append(out, DirEntry{ out = append(out, DirEntry{
...@@ -212,7 +203,7 @@ func (n *Inode) getMountDirEntries() (out []DirEntry) { ...@@ -212,7 +203,7 @@ func (n *Inode) getMountDirEntries() (out []DirEntry) {
}) })
} }
} }
n.treeLock.RUnlock() n.mount.treeLock.RUnlock()
return out return out
} }
......
...@@ -166,6 +166,3 @@ func (fs *LoopbackFileSystem) Create(path string, flags uint32, mode uint32, con ...@@ -166,6 +166,3 @@ func (fs *LoopbackFileSystem) Create(path string, flags uint32, mode uint32, con
f, err := os.OpenFile(fs.GetPath(path), int(flags)|os.O_CREATE, os.FileMode(mode)) f, err := os.OpenFile(fs.GetPath(path), int(flags)|os.O_CREATE, os.FileMode(mode))
return &LoopbackFile{File: f}, ToStatus(err) return &LoopbackFile{File: f}, ToStatus(err)
} }
...@@ -19,4 +19,3 @@ func (fs *LoopbackFileSystem) StatFs(name string) *StatfsOut { ...@@ -19,4 +19,3 @@ func (fs *LoopbackFileSystem) StatFs(name string) *StatfsOut {
} }
return nil return nil
} }
...@@ -91,7 +91,6 @@ func CurrentOwner() *Owner { ...@@ -91,7 +91,6 @@ func CurrentOwner() *Owner {
} }
} }
// VerboseTest returns true if the testing framework is run with -v. // VerboseTest returns true if the testing framework is run with -v.
func VerboseTest() bool { func VerboseTest() bool {
flag := flag.Lookup("test.v") flag := flag.Lookup("test.v")
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
package fuse package fuse
/* /*
// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c, // Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
...@@ -127,8 +126,8 @@ func mount(dir string, options string) (int, error) { ...@@ -127,8 +126,8 @@ func mount(dir string, options string) (int, error) {
return fd, nil return fd, nil
} }
type mountError string type mountError string
func (m mountError) Error() string { func (m mountError) Error() string {
return string(m) return string(m)
} }
...@@ -148,8 +147,8 @@ func unmount(mountPoint string) error { ...@@ -148,8 +147,8 @@ func unmount(mountPoint string) error {
return err return err
} }
var umountBinary string var umountBinary string
func init() { func init() {
var err error var err error
umountBinary, err = exec.LookPath("umount") umountBinary, err = exec.LookPath("umount")
......
...@@ -36,7 +36,7 @@ type MountState struct { ...@@ -36,7 +36,7 @@ type MountState struct {
opts *MountOptions opts *MountOptions
started chan struct {} started chan struct{}
reqMu sync.Mutex reqMu sync.Mutex
reqPool []*request reqPool []*request
...@@ -361,7 +361,6 @@ func (ms *MountState) handleRequest(req *request) { ...@@ -361,7 +361,6 @@ func (ms *MountState) handleRequest(req *request) {
ms.returnRequest(req) ms.returnRequest(req)
} }
func (ms *MountState) AllocOut(req *request, size uint32) []byte { func (ms *MountState) AllocOut(req *request, size uint32) []byte {
if cap(req.bufferPoolOutputBuf) >= int(size) { if cap(req.bufferPoolOutputBuf) >= int(size) {
req.bufferPoolOutputBuf = req.bufferPoolOutputBuf[:size] req.bufferPoolOutputBuf = req.bufferPoolOutputBuf[:size]
......
...@@ -85,7 +85,8 @@ func TestMemoryPressure(t *testing.T) { ...@@ -85,7 +85,8 @@ func TestMemoryPressure(t *testing.T) {
state.reqMu.Unlock() state.reqMu.Unlock()
t.Logf("Have %d read bufs", state.outstandingReadBufs) t.Logf("Have %d read bufs", state.outstandingReadBufs)
if created > _MAX_READERS { // +1 due to batch forget?
if created > _MAX_READERS + 1 {
t.Errorf("created %d buffers, max reader %d", created, _MAX_READERS) t.Errorf("created %d buffers, max reader %d", created, _MAX_READERS)
} }
......
...@@ -10,7 +10,7 @@ type ReadonlyFileSystem struct { ...@@ -10,7 +10,7 @@ type ReadonlyFileSystem struct {
FileSystem FileSystem
} }
var _ = (FileSystem)((*ReadonlyFileSystem) (nil)) var _ = (FileSystem)((*ReadonlyFileSystem)(nil))
func (fs *ReadonlyFileSystem) GetAttr(name string, context *Context) (*Attr, Status) { func (fs *ReadonlyFileSystem) GetAttr(name string, context *Context) (*Attr, Status) {
return fs.FileSystem.GetAttr(name, context) return fs.FileSystem.GetAttr(name, context)
......
...@@ -7,4 +7,3 @@ const ( ...@@ -7,4 +7,3 @@ const (
_MINIMUM_MINOR_VERSION = 13 _MINIMUM_MINOR_VERSION = 13
_OUR_MINOR_VERSION = 20 _OUR_MINOR_VERSION = 20
) )
...@@ -11,7 +11,6 @@ func (s *MountState) setSplice() { ...@@ -11,7 +11,6 @@ func (s *MountState) setSplice() {
s.canSplice = splice.Resizable() s.canSplice = splice.Resizable()
} }
func (ms *MountState) trySplice(header []byte, req *request, fdData *ReadResultFd) error { func (ms *MountState) trySplice(header []byte, req *request, fdData *ReadResultFd) error {
pair, err := splice.Get() pair, err := splice.Get()
if err != nil { if err != nil {
......
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