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

Oops: recurse in inode.verify().

parent 41883b06
...@@ -582,6 +582,14 @@ func TestMount(t *testing.T) { ...@@ -582,6 +582,14 @@ func TestMount(t *testing.T) {
ts.testTouch() ts.testTouch()
} }
func TestOverwriteRename(t *testing.T) {
ts := new(testCase)
ts.Setup(t)
defer ts.Cleanup()
ts.testOverwriteRename()
}
func TestLargeRead(t *testing.T) { func TestLargeRead(t *testing.T) {
ts := new(testCase) ts := new(testCase)
ts.Setup(t) ts.Setup(t)
...@@ -630,6 +638,7 @@ func TestIoctl(t *testing.T) { ...@@ -630,6 +638,7 @@ func TestIoctl(t *testing.T) {
func TestRecursiveMount(t *testing.T) { func TestRecursiveMount(t *testing.T) {
ts := new(testCase) ts := new(testCase)
ts.Setup(t) ts.Setup(t)
defer ts.Cleanup()
f, err := os.OpenFile(filepath.Join(ts.mountPoint, "hello.txt"), f, err := os.OpenFile(filepath.Join(ts.mountPoint, "hello.txt"),
os.O_WRONLY|os.O_CREATE, 0777) os.O_WRONLY|os.O_CREATE, 0777)
...@@ -673,6 +682,5 @@ func TestRecursiveMount(t *testing.T) { ...@@ -673,6 +682,5 @@ func TestRecursiveMount(t *testing.T) {
if code != OK { if code != OK {
t.Error("umount failed.", code) t.Error("umount failed.", code)
} }
ts.Cleanup()
} }
...@@ -72,6 +72,11 @@ type inode struct { ...@@ -72,6 +72,11 @@ type inode struct {
Name string Name string
LookupCount int LookupCount int
OpenCount int OpenCount int
// Non-nil if this is a mountpoint.
mountPoint *mountData
// The point under which this node is.
mount *mountData mount *mountData
} }
...@@ -87,7 +92,7 @@ func (me *inode) totalOpenCount() int { ...@@ -87,7 +92,7 @@ func (me *inode) totalOpenCount() int {
// Should be called with treeLock held. // Should be called with treeLock held.
func (me *inode) totalMountCount() int { func (me *inode) totalMountCount() int {
o := 0 o := 0
if me.mount != nil && !me.mount.unmountPending { if me.mountPoint != nil && !me.mountPoint.unmountPending {
o++ o++
} }
for _, v := range me.Children { for _, v := range me.Children {
...@@ -102,10 +107,19 @@ func (me *inode) IsDir() bool { ...@@ -102,10 +107,19 @@ func (me *inode) IsDir() bool {
const initDirSize = 20 const initDirSize = 20
func (me *inode) verify() { func (me *inode) verify(cur *mountData) {
if !(me.NodeId == FUSE_ROOT_ID || me.LookupCount > 0 || len(me.Children) > 0) { if !(me.NodeId == FUSE_ROOT_ID || me.LookupCount > 0 || len(me.Children) > 0) {
panic(fmt.Sprintf("node should be dead: %v", me)) p, _ := me.GetPath()
panic(fmt.Sprintf("node %v should be dead: %v %v", p, len(me.Children), me.LookupCount))
} }
if me.mountPoint == nil {
if me.mount != cur {
// panic("me.mount not set correctly", me.mount, cur)
}
} else {
cur = me.mountPoint
}
for n, ch := range me.Children { for n, ch := range me.Children {
if ch == nil { if ch == nil {
panic("Found nil child.") panic("Found nil child.")
...@@ -118,6 +132,7 @@ func (me *inode) verify() { ...@@ -118,6 +132,7 @@ func (me *inode) verify() {
panic(fmt.Sprintf("parent/child relation corrupted %v %v %v", panic(fmt.Sprintf("parent/child relation corrupted %v %v %v",
ch.Parent, me, ch)) ch.Parent, me, ch))
} }
ch.verify(cur)
} }
} }
...@@ -125,13 +140,13 @@ func (me *inode) GetPath() (path string, mount *mountData) { ...@@ -125,13 +140,13 @@ func (me *inode) GetPath() (path string, mount *mountData) {
rev_components := make([]string, 0, 10) rev_components := make([]string, 0, 10)
inode := me inode := me
for ; inode != nil && inode.mount == nil; inode = inode.Parent { for ; inode != nil && inode.mountPoint == nil; inode = inode.Parent {
rev_components = append(rev_components, inode.Name) rev_components = append(rev_components, inode.Name)
} }
if inode == nil { if inode == nil {
panic(fmt.Sprintf("did not find parent with mount: %v", rev_components)) panic(fmt.Sprintf("did not find parent with mount: %v", rev_components))
} }
mount = inode.mount mount = inode.mountPoint
if mount.unmountPending { if mount.unmountPending {
return "", nil return "", nil
...@@ -304,7 +319,7 @@ func (me *FileSystemConnector) verify() { ...@@ -304,7 +319,7 @@ func (me *FileSystemConnector) verify() {
} }
root := me.rootNode root := me.rootNode
root.verify() root.verify(me.rootNode.mountPoint)
open := root.totalOpenCount() open := root.totalOpenCount()
openFiles := len(me.openFiles) openFiles := len(me.openFiles)
...@@ -329,7 +344,7 @@ func (me *FileSystemConnector) newInode(root bool, isDir bool) *inode { ...@@ -329,7 +344,7 @@ func (me *FileSystemConnector) newInode(root bool, isDir bool) *inode {
return data return data
} }
func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bool) *inode { func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bool, lookupCount int) *inode {
defer me.verify() defer me.verify()
me.treeLock.Lock() me.treeLock.Lock()
...@@ -341,7 +356,7 @@ func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bo ...@@ -341,7 +356,7 @@ func (me *FileSystemConnector) lookupUpdate(parent *inode, name string, isDir bo
data.Name = name data.Name = name
data.setParent(parent) data.setParent(parent)
} }
data.LookupCount += lookupCount
return data return data
} }
...@@ -366,7 +381,7 @@ func (me *FileSystemConnector) forgetUpdate(nodeId uint64, forgetCount int) { ...@@ -366,7 +381,7 @@ func (me *FileSystemConnector) forgetUpdate(nodeId uint64, forgetCount int) {
} }
func (me *FileSystemConnector) considerDropInode(n *inode) { func (me *FileSystemConnector) considerDropInode(n *inode) {
if n.LookupCount <= 0 && len(n.Children) == 0 && (n.mount == nil || n.mount.unmountPending) && if n.LookupCount <= 0 && len(n.Children) == 0 && (n.mountPoint == nil || n.mountPoint.unmountPending) &&
n.OpenCount <= 0 { n.OpenCount <= 0 {
n.setParent(nil) n.setParent(nil)
me.inodeMap[n.NodeId] = nil, false me.inodeMap[n.NodeId] = nil, false
...@@ -479,11 +494,11 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil ...@@ -479,11 +494,11 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Fil
log.Println("Mount: ", fs, "on", mountPoint, node) log.Println("Mount: ", fs, "on", mountPoint, node)
} }
node.mount = newMount(fs) node.mountPoint = newMount(fs)
if opts == nil { if opts == nil {
opts = NewFileSystemOptions() opts = NewFileSystemOptions()
} }
node.mount.options = opts node.mountPoint.options = opts
return OK return OK
} }
...@@ -499,7 +514,7 @@ func (me *FileSystemConnector) Unmount(path string) Status { ...@@ -499,7 +514,7 @@ func (me *FileSystemConnector) Unmount(path string) Status {
unmountError := OK unmountError := OK
mount := node.mount mount := node.mountPoint
if mount == nil || mount.unmountPending { if mount == nil || mount.unmountPending {
unmountError = EINVAL unmountError = EINVAL
} }
......
...@@ -42,7 +42,7 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string ...@@ -42,7 +42,7 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string
// Init. // Init.
fullPath, mount := parent.GetPath() fullPath, mount := parent.GetPath()
if mount == nil { if mount == nil {
timeout := me.rootNode.mount.options.NegativeTimeout timeout := me.rootNode.mountPoint.options.NegativeTimeout
if timeout > 0 { if timeout > 0 {
return NegativeEntry(timeout), OK, nil return NegativeEntry(timeout), OK, nil
} else { } else {
...@@ -61,8 +61,7 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string ...@@ -61,8 +61,7 @@ func (me *FileSystemConnector) internalLookupWithNode(parent *inode, name string
return nil, err, nil return nil, err, nil
} }
data := me.lookupUpdate(parent, name, fi.IsDirectory()) data := me.lookupUpdate(parent, name, fi.IsDirectory(), lookupCount)
data.LookupCount += lookupCount
out = &EntryOut{ out = &EntryOut{
NodeId: data.NodeId, NodeId: data.NodeId,
......
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