Commit 33fc3c76 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Synchronize nodeId access in notify functions.

parent 4a345b8f
......@@ -121,9 +121,10 @@ func (c *FileSystemConnector) lookupUpdate(node *Inode) uint64 {
node.nodeId = c.inodeMap.Register(&node.handled, node)
}
node.lookupCount += 1
id := node.nodeId
node.treeLock.Unlock()
return node.nodeId
return id
}
// Must run outside treeLock.
......@@ -294,6 +295,7 @@ func (c *FileSystemConnector) Mount(parent *Inode, name string, nodeFs NodeFileS
//
// EBUSY: there are open files, or submounts below this node.
func (c *FileSystemConnector) Unmount(node *Inode) Status {
// TODO - racy.
if node.mountPoint == nil {
log.Println("not a mountpoint:", node.nodeId)
return EINVAL
......@@ -324,13 +326,14 @@ func (c *FileSystemConnector) Unmount(node *Inode) Status {
delete(parentNode.children, name)
mount.fs.OnUnmount()
c.DeleteNotify(parentNode, mountInode, name)
c.fsInit.DeleteNotify(parentNode.nodeId, mountInode.nodeId, name)
return OK
}
func (c *FileSystemConnector) FileNotify(node *Inode, off int64, length int64) Status {
node.treeLock.RLock()
n := node.nodeId
node.treeLock.RUnlock()
if node == c.rootNode {
n = raw.FUSE_ROOT_ID
}
......@@ -346,7 +349,9 @@ func (c *FileSystemConnector) FileNotify(node *Inode, off int64, length int64) S
}
func (c *FileSystemConnector) EntryNotify(dir *Inode, name string) Status {
dir.treeLock.RLock()
n := dir.nodeId
dir.treeLock.RUnlock()
if dir == c.rootNode {
n = raw.FUSE_ROOT_ID
}
......@@ -357,12 +362,22 @@ func (c *FileSystemConnector) EntryNotify(dir *Inode, name string) Status {
}
func (c *FileSystemConnector) DeleteNotify(dir *Inode, child *Inode, name string) Status {
dir.treeLock.RLock()
n := dir.nodeId
var chId uint64
if child.treeLock != dir.treeLock {
child.treeLock.RLock()
chId = child.nodeId
child.treeLock.RUnlock()
}
dir.treeLock.RUnlock()
if dir == c.rootNode {
n = raw.FUSE_ROOT_ID
}
if n == 0 {
return OK
}
return c.fsInit.DeleteNotify(n, child.nodeId, name)
return c.fsInit.DeleteNotify(n, chId, name)
}
......@@ -41,8 +41,8 @@ type Inode struct {
// The nodeId is only used to communicate to the kernel. If
// it is zero, it means the kernel does not know about this
// Inode. You should probably never read nodeId, but always
// do lookupUpdate() on the node instead.
// Inode. Only forget/lookup/notify methods should nodeId
// directly.
nodeId uint64
// lookupCount registers how often the kernel got this inode
......
......@@ -27,7 +27,10 @@ func TestMountOnExisting(t *testing.T) {
t.Fatal("expect OK:", code)
}
ts.pathFs.Unmount("mnt")
code = ts.pathFs.Unmount("mnt")
if !code.Ok() {
t.Errorf("Unmount failed: %v", code)
}
}
func TestMountRename(t *testing.T) {
......
......@@ -153,7 +153,8 @@ func (ms *MountState) Unmount() (err error) {
if err == nil {
break
}
fmt.Fprintf(os.Stderr, "umount failed; retrying\n")
// Sleep for a bit. This is not pretty, but there is
// no way we can be certain that the kernel thinks all
// open files have already been closed.
......
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