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

Access mount.treeLock directly.

parent c24ef376
package fuse
import (
"syscall"
)
......
package fuse
import (
"syscall"
)
......
......@@ -202,7 +202,6 @@ type ReadOnlyFile struct {
var _ = (File)((*ReadOnlyFile)(nil))
func (f *ReadOnlyFile) String() string {
return fmt.Sprintf("ReadOnlyFile(%s)", f.File.String())
}
......
......@@ -127,12 +127,12 @@ func (c *FileSystemConnector) forgetUpdate(nodeID uint64, forgetCount int) {
// We never got a lookup for root, so don't try to forget root.
return
}
if forgotten, handled := c.inodeMap.Forget(nodeID, forgetCount); forgotten {
node := (*Inode)(unsafe.Pointer(handled))
node.treeLock.Lock()
node.mount.treeLock.Lock()
c.recursiveConsiderDropInode(node)
node.treeLock.Unlock()
node.mount.treeLock.Unlock()
}
// TODO - try to drop children even forget was not successful.
c.verify()
......@@ -193,8 +193,8 @@ func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []st
node := parent
if node.mountPoint == nil {
node.treeLock.RLock()
defer node.treeLock.RUnlock()
node.mount.treeLock.RLock()
defer node.mount.treeLock.RUnlock()
}
for i, component := range comps {
......@@ -203,8 +203,8 @@ func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []st
}
if node.mountPoint != nil {
node.treeLock.RLock()
defer node.treeLock.RUnlock()
node.mount.treeLock.RLock()
defer node.mount.treeLock.RUnlock()
}
next := node.children[component]
......@@ -257,8 +257,8 @@ func (c *FileSystemConnector) MountRoot(nodeFs NodeFileSystem, opts *FileSystemO
// EBUSY: the intended mount point already exists.
func (c *FileSystemConnector) Mount(parent *Inode, name string, nodeFs NodeFileSystem, opts *FileSystemOptions) Status {
defer c.verify()
parent.treeLock.Lock()
defer parent.treeLock.Unlock()
parent.mount.treeLock.Lock()
defer parent.mount.treeLock.Unlock()
node := parent.children[name]
if node != nil {
return EBUSY
......@@ -298,8 +298,8 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status {
// Must lock parent to update tree structure.
parentNode := node.mountPoint.parentInode
parentNode.treeLock.Lock()
defer parentNode.treeLock.Unlock()
parentNode.mount.treeLock.Lock()
defer parentNode.mount.treeLock.Unlock()
mount := node.mountPoint
name := node.mountPoint.mountName()
......@@ -307,8 +307,8 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status {
return EBUSY
}
node.treeLock.Lock()
defer node.treeLock.Unlock()
node.mount.treeLock.Lock()
defer node.mount.treeLock.Unlock()
if mount.mountInode != node {
log.Panicf("got two different mount inodes %v vs %v",
......@@ -344,7 +344,7 @@ func (c *FileSystemConnector) FileNotify(node *Inode, off int64, length int64) S
} else {
nId = c.inodeMap.Handle(&node.handled)
}
if nId == 0 {
return OK
}
......@@ -357,7 +357,7 @@ func (c *FileSystemConnector) FileNotify(node *Inode, off int64, length int64) S
}
func (c *FileSystemConnector) EntryNotify(node *Inode, name string) Status {
var nId uint64
var nId uint64
if node == c.rootNode {
nId = raw.FUSE_ROOT_ID
} else {
......@@ -384,6 +384,6 @@ func (c *FileSystemConnector) DeleteNotify(dir *Inode, child *Inode, name string
}
chId := c.inodeMap.Handle(&child.handled)
return c.fsInit.DeleteNotify(nId, chId, name)
}
......@@ -34,6 +34,9 @@ type fileSystemMount struct {
// Protects Children hashmaps within the mount. treeLock
// should be acquired before openFilesLock.
//
// If multiple treeLocks must be acquired, the treeLocks
// closer to the root must be acquired first.
treeLock sync.RWMutex
// Manage filehandles of open files.
......
......@@ -105,7 +105,7 @@ func (c *FileSystemConnector) GetAttr(out *raw.AttrOut, context *Context, input
node := c.toInode(context.NodeId)
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 {
f = opened.WithFlags.File
}
......@@ -217,7 +217,7 @@ func (c *FileSystemConnector) SetAttr(out *raw.AttrOut, context *Context, input
func (c *FileSystemConnector) Fallocate(context *Context, in *raw.FallocateIn) (code Status) {
n := c.toInode(context.NodeId)
opened := n.mount.getOpenedFile(in.Fh)
return n.fsInode.Fallocate(opened, in.Offset, in.Length, in.Mode, context)
}
......
......@@ -24,7 +24,7 @@ type HandleMap interface {
Count() int
Decode(uint64) *Handled
Forget(handle uint64, count int) (bool, *Handled)
Handle(obj* Handled) uint64
Handle(obj *Handled) uint64
Has(uint64) bool
}
......@@ -290,7 +290,7 @@ func (m *int64HandleMap) Register(obj *Handled) (handle uint64) {
} else {
handle = m.Handle(obj)
}
obj.count ++
obj.count++
m.mutex.Unlock()
return handle
......@@ -307,7 +307,6 @@ func (m *int64HandleMap) Handle(obj *Handled) (handle uint64) {
return handle
}
func (m *int64HandleMap) Forget(handle uint64, count int) (forgotten bool, obj *Handled) {
defer m.verify()
......
......@@ -28,14 +28,6 @@ type Inode struct {
// Unmount() when it is set to nil.
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.
children map[string]*Inode
......@@ -70,12 +62,12 @@ func (n *Inode) AnyFile() (file File) {
}
func (n *Inode) Children() (out map[string]*Inode) {
n.treeLock.RLock()
n.mount.treeLock.RLock()
out = make(map[string]*Inode, len(n.children))
for k, v := range n.children {
out[k] = v
}
n.treeLock.RUnlock()
n.mount.treeLock.RUnlock()
return out
}
......@@ -83,14 +75,14 @@ func (n *Inode) Children() (out map[string]*Inode) {
// FsChildren returns all the children from the same filesystem. It
// will skip mountpoints.
func (n *Inode) FsChildren() (out map[string]*Inode) {
n.treeLock.RLock()
n.mount.treeLock.RLock()
out = map[string]*Inode{}
for k, v := range n.children {
if v.mount == n.mount {
out[k] = v
}
}
n.treeLock.RUnlock()
n.mount.treeLock.RUnlock()
return out
}
......@@ -119,15 +111,15 @@ func (n *Inode) IsDir() bool {
func (n *Inode) New(isDir bool, fsi FsNode) *Inode {
ch := newInode(isDir, fsi)
ch.mount = n.mount
ch.treeLock = n.treeLock
ch.mount.treeLock = n.mount.treeLock
n.generation = ch.mount.connector.nextGeneration()
return ch
}
func (n *Inode) GetChild(name string) (child *Inode) {
n.treeLock.RLock()
n.mount.treeLock.RLock()
child = n.children[name]
n.treeLock.RUnlock()
n.mount.treeLock.RUnlock()
return child
}
......@@ -136,15 +128,15 @@ func (n *Inode) AddChild(name string, child *Inode) {
if child == nil {
log.Panicf("adding nil child as %q", name)
}
n.treeLock.Lock()
n.mount.treeLock.Lock()
n.addChild(name, child)
n.treeLock.Unlock()
n.mount.treeLock.Unlock()
}
func (n *Inode) RmChild(name string) (ch *Inode) {
n.treeLock.Lock()
n.mount.treeLock.Lock()
ch = n.rmChild(name)
n.treeLock.Unlock()
n.mount.treeLock.Unlock()
return
}
......@@ -180,7 +172,6 @@ func (n *Inode) mountFs(fs NodeFileSystem, opts *FileSystemOptions) {
options: opts,
}
n.mount = n.mountPoint
n.treeLock = &n.mountPoint.treeLock
}
// Must be called with treeLock held.
......@@ -203,7 +194,7 @@ func (n *Inode) canUnmount() bool {
}
func (n *Inode) getMountDirEntries() (out []DirEntry) {
n.treeLock.RLock()
n.mount.treeLock.RLock()
for k, v := range n.children {
if v.mountPoint != nil {
out = append(out, DirEntry{
......@@ -212,7 +203,7 @@ func (n *Inode) getMountDirEntries() (out []DirEntry) {
})
}
}
n.treeLock.RUnlock()
n.mount.treeLock.RUnlock()
return out
}
......
......@@ -14,7 +14,7 @@ import (
type LockingFileSystem struct {
// Should be public so people reusing can access the wrapped
// FS.
FS FileSystem
FS FileSystem
lock sync.Mutex
}
......@@ -160,7 +160,7 @@ func (fs *LockingFileSystem) RemoveXAttr(name string, attr string, context *Cont
type LockingRawFileSystem struct {
RawFS RawFileSystem
lock sync.Mutex
lock sync.Mutex
}
var _ = (RawFileSystem)((*LockingRawFileSystem)(nil))
......
......@@ -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))
return &LoopbackFile{File: f}, ToStatus(err)
}
package fuse
import (
"syscall"
"syscall"
)
func (fs *LoopbackFileSystem) StatFs(name string) *StatfsOut {
......@@ -9,14 +9,13 @@ func (fs *LoopbackFileSystem) StatFs(name string) *StatfsOut {
err := syscall.Statfs(fs.GetPath(name), &s)
if err == nil {
return &StatfsOut{
Blocks: s.Blocks,
Bsize: uint32(s.Bsize),
Bfree: s.Bfree,
Bavail: s.Bavail,
Files: s.Files,
Ffree: s.Ffree,
Blocks: s.Blocks,
Bsize: uint32(s.Bsize),
Bfree: s.Bfree,
Bavail: s.Bavail,
Files: s.Files,
Ffree: s.Ffree,
}
}
return nil
}
......@@ -91,7 +91,6 @@ func CurrentOwner() *Owner {
}
}
// VerboseTest returns true if the testing framework is run with -v.
func VerboseTest() bool {
flag := flag.Lookup("test.v")
......
......@@ -6,7 +6,6 @@
package fuse
/*
// 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) {
return fd, nil
}
type mountError string
func (m mountError) Error() string {
return string(m)
}
......@@ -148,8 +147,8 @@ func unmount(mountPoint string) error {
return err
}
var umountBinary string
func init() {
var err error
umountBinary, err = exec.LookPath("umount")
......
......@@ -36,8 +36,8 @@ type MountState struct {
opts *MountOptions
started chan struct {}
started chan struct{}
reqMu sync.Mutex
reqPool []*request
readPool [][]byte
......@@ -361,7 +361,6 @@ func (ms *MountState) handleRequest(req *request) {
ms.returnRequest(req)
}
func (ms *MountState) AllocOut(req *request, size uint32) []byte {
if cap(req.bufferPoolOutputBuf) >= int(size) {
req.bufferPoolOutputBuf = req.bufferPoolOutputBuf[:size]
......
......@@ -529,7 +529,7 @@ func init() {
_OP_RENAME: doRename,
_OP_STATFS: doStatFs,
_OP_IOCTL: doIoctl,
_OP_DESTROY: doDestroy,
_OP_DESTROY: doDestroy,
_OP_FALLOCATE: doFallocate,
} {
operationHandlers[op].Func = v
......
......@@ -648,7 +648,7 @@ func (n *pathInode) Fallocate(file File, off uint64, size uint64, mode uint32, c
return code
}
}
files := n.inode.Files(O_ANYWRITE)
for _, f := range files {
// TODO - pass context
......
......@@ -77,7 +77,7 @@ func TestMemoryPressure(t *testing.T) {
}(i)
}
time.Sleep(100 * time.Millisecond)
state.reqMu.Lock()
bufs.lock.Lock()
created := bufs.createdBuffers + state.outstandingReadBufs
......@@ -85,7 +85,8 @@ func TestMemoryPressure(t *testing.T) {
state.reqMu.Unlock()
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)
}
......
......@@ -10,7 +10,7 @@ type ReadonlyFileSystem struct {
FileSystem
}
var _ = (FileSystem)((*ReadonlyFileSystem) (nil))
var _ = (FileSystem)((*ReadonlyFileSystem)(nil))
func (fs *ReadonlyFileSystem) GetAttr(name string, context *Context) (*Attr, Status) {
return fs.FileSystem.GetAttr(name, context)
......
......@@ -6,4 +6,4 @@ const (
_FUSE_KERNEL_VERSION = 7
_MINIMUM_MINOR_VERSION = 8
_OUR_MINOR_VERSION = 8
)
\ No newline at end of file
)
......@@ -7,4 +7,3 @@ const (
_MINIMUM_MINOR_VERSION = 13
_OUR_MINOR_VERSION = 20
)
......@@ -3,7 +3,7 @@ package fuse
import (
"fmt"
"io"
"github.com/hanwen/go-fuse/splice"
)
......@@ -11,7 +11,6 @@ func (s *MountState) setSplice() {
s.canSplice = splice.Resizable()
}
func (ms *MountState) trySplice(header []byte, req *request, fdData *ReadResultFd) error {
pair, err := splice.Get()
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