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

Fix overwriting renames in PathFileSystemConnector.

parent 201f145d
...@@ -3,13 +3,14 @@ package fuse ...@@ -3,13 +3,14 @@ package fuse
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"rand"
"strings" "strings"
"testing"
"syscall" "syscall"
"rand" "testing"
"time" "time"
) )
...@@ -277,22 +278,68 @@ func (me *testCase) testSymlink() { ...@@ -277,22 +278,68 @@ func (me *testCase) testSymlink() {
func (me *testCase) testRename() { func (me *testCase) testRename() {
me.tester.Log("Testing rename.") me.tester.Log("Testing rename.")
me.writeOrigFile() me.writeOrigFile()
me.makeOrigSubdir() sd := me.mountPoint+"/testRename"
err := os.MkdirAll(sd, 0777)
defer os.RemoveAll(sd)
err := os.Rename(me.mountFile, me.mountSubfile) subFile := sd+"/subfile"
err = os.Rename(me.mountFile, subFile)
CheckSuccess(err) CheckSuccess(err)
f, _ := os.Lstat(me.origFile) f, _ := os.Lstat(me.origFile)
if f != nil { if f != nil {
me.tester.Errorf("original %v still exists.", me.origFile) me.tester.Errorf("original %v still exists.", me.origFile)
} }
f, _ = os.Lstat(me.origSubfile) f, _ = os.Lstat(subFile)
if f == nil { if f == nil {
me.tester.Errorf("destination %v does not exist.", me.origSubfile) me.tester.Errorf("destination %v does not exist.", me.origSubfile)
} }
}
me.removeMountSubdir() func (me *testCase) testDelRename() {
me.tester.Log("Testing del+rename.")
sd := me.mountPoint+"/testDelRename"
err := os.MkdirAll(sd, 0755)
CheckSuccess(err)
d := sd+"/dest"
err = ioutil.WriteFile(d, []byte("blabla"), 0644)
CheckSuccess(err)
f, err := os.Open(d)
CheckSuccess(err)
err = os.Remove(d)
CheckSuccess(err)
s := sd+"/src"
err = ioutil.WriteFile(s, []byte("blabla"), 0644)
CheckSuccess(err)
err = os.Rename(s, d)
CheckSuccess(err)
f.Close()
} }
func (me *testCase) testOverwriteRename() {
me.tester.Log("Testing rename overwrite.")
sd := me.mountPoint+"/testOverwriteRename"
err := os.MkdirAll(sd, 0755)
CheckSuccess(err)
d := sd+"/dest"
err = ioutil.WriteFile(d, []byte("blabla"), 0644)
CheckSuccess(err)
s := sd+"/src"
err = ioutil.WriteFile(s, []byte("blabla"), 0644)
CheckSuccess(err)
err = os.Rename(s, d)
CheckSuccess(err)
}
func (me *testCase) testAccess() { func (me *testCase) testAccess() {
me.writeOrigFile() me.writeOrigFile()
...@@ -513,7 +560,10 @@ func (me *testCase) testLargeDirRead() { ...@@ -513,7 +560,10 @@ func (me *testCase) testLargeDirRead() {
func TestMount(t *testing.T) { func TestMount(t *testing.T) {
ts := new(testCase) ts := new(testCase)
ts.Setup(t) ts.Setup(t)
defer ts.Cleanup()
ts.testOverwriteRename()
ts.testDelRename()
ts.testOpenUnreadable() ts.testOpenUnreadable()
ts.testReadThroughFuse() ts.testReadThroughFuse()
ts.testRemove() ts.testRemove()
...@@ -523,11 +573,17 @@ func TestMount(t *testing.T) { ...@@ -523,11 +573,17 @@ func TestMount(t *testing.T) {
ts.testRename() ts.testRename()
ts.testAccess() ts.testAccess()
ts.testMknod() ts.testMknod()
ts.testReaddir()
ts.testFSync() ts.testFSync()
ts.testLargeRead() ts.testLargeRead()
ts.testLargeDirRead() ts.testLargeDirRead()
ts.Cleanup() }
func TestReadOnly(t *testing.T) {
ts := new(testCase)
ts.Setup(t)
defer ts.Cleanup()
ts.testReaddir()
} }
func TestRecursiveMount(t *testing.T) { func TestRecursiveMount(t *testing.T) {
......
...@@ -227,20 +227,25 @@ func (me *PathFileSystemConnector) verify() { ...@@ -227,20 +227,25 @@ func (me *PathFileSystemConnector) verify() {
defer me.lock.Unlock() defer me.lock.Unlock()
me.fileLock.Lock() me.fileLock.Lock()
defer me.fileLock.Unlock() defer me.fileLock.Unlock()
hiddenOpen := 0
for k, v := range me.inodeMap { for k, v := range me.inodeMap {
if v.NodeId != k { if v.NodeId != k {
panic(fmt.Sprintf("nodeid mismatch %v %v", v, k)) panic(fmt.Sprintf("nodeid mismatch %v %v", v, k))
} }
if v.Parent == nil && v.NodeId != FUSE_ROOT_ID {
hiddenOpen += v.OpenCount
}
} }
root := me.inodeMap[FUSE_ROOT_ID] root := me.inodeMap[FUSE_ROOT_ID]
root.verify() root.verify()
open := root.totalOpenCount() open := root.totalOpenCount()
openFiles := len(me.openFiles) openFiles := len(me.openFiles)
mounted := root.totalMountCount() mounted := root.totalMountCount()
if open != openFiles + mounted { if open + hiddenOpen != openFiles + mounted {
panic(fmt.Sprintf("opencount mismatch %v %v %v", open, openFiles, mounted)) panic(fmt.Sprintf("opencount mismatch totalOpen=%v openFiles=%v mounted=%v hidden=%v", open, openFiles, mounted, hiddenOpen))
} }
} }
...@@ -320,6 +325,10 @@ func (me *PathFileSystemConnector) renameUpdate(oldParent *inode, oldName string ...@@ -320,6 +325,10 @@ func (me *PathFileSystemConnector) renameUpdate(oldParent *inode, oldName string
panic("Source of rename does not exist") panic("Source of rename does not exist")
} }
dest := newParent.Children[newName]
if dest != nil {
dest.setParent(nil)
}
node.setParent(nil) node.setParent(nil)
node.Name = newName node.Name = newName
node.setParent(newParent) node.setParent(newParent)
......
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