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

MemUnionFs: centralize locking, implement Reap/Clear.

parent 9da364b3
...@@ -19,7 +19,7 @@ type MemUnionFs struct { ...@@ -19,7 +19,7 @@ type MemUnionFs struct {
backingStore string backingStore string
root *memNode root *memNode
mutex sync.Mutex mutex sync.RWMutex
nextFree int nextFree int
readonly fuse.FileSystem readonly fuse.FileSystem
...@@ -29,20 +29,39 @@ type memNode struct { ...@@ -29,20 +29,39 @@ type memNode struct {
fuse.DefaultFsNode fuse.DefaultFsNode
fs *MemUnionFs fs *MemUnionFs
original string
// protects mutable data below. // protects mutable data below.
mutex sync.RWMutex mutex *sync.RWMutex
backing string backing string
original string
changed bool changed bool
link string link string
info os.FileInfo info os.FileInfo
deleted map[string]bool deleted map[string]bool
} }
func (me *MemUnionFs) getFilename() string { type Result struct {
Info *os.FileInfo
Original string
Backing string
Link string
}
func (me *MemUnionFs) Reap() map[string]*Result {
me.mutex.RLock()
defer me.mutex.RUnlock()
m := map[string]*Result{}
me.root.Reap("", m)
return m
}
func (me *MemUnionFs) Clear() {
me.mutex.Lock() me.mutex.Lock()
defer me.mutex.Unlock() defer me.mutex.Unlock()
me.root.Clear("")
}
func (me *MemUnionFs) getFilename() string {
id := me.nextFree id := me.nextFree
me.nextFree++ me.nextFree++
return fmt.Sprintf("%s/%d", me.backingStore, id) return fmt.Sprintf("%s/%d", me.backingStore, id)
...@@ -60,6 +79,7 @@ func (me *MemUnionFs) StatFs() *fuse.StatfsOut { ...@@ -60,6 +79,7 @@ func (me *MemUnionFs) StatFs() *fuse.StatfsOut {
func (me *MemUnionFs) newNode(isdir bool) *memNode { func (me *MemUnionFs) newNode(isdir bool) *memNode {
n := &memNode{ n := &memNode{
fs: me, fs: me,
mutex: &me.mutex,
} }
if isdir { if isdir {
n.deleted = map[string]bool{} n.deleted = map[string]bool{}
...@@ -171,6 +191,7 @@ func (me *memNode) Symlink(name string, content string, context *fuse.Context) ( ...@@ -171,6 +191,7 @@ func (me *memNode) Symlink(name string, content string, context *fuse.Context) (
n := me.newNode(false) n := me.newNode(false)
n.info.Mode = fuse.S_IFLNK | 0777 n.info.Mode = fuse.S_IFLNK | 0777
n.link = content n.link = content
n.changed = true
me.Inode().AddChild(name, n.Inode()) me.Inode().AddChild(name, n.Inode())
me.touch() me.touch()
me.deleted[name] = false, false me.deleted[name] = false, false
...@@ -190,10 +211,11 @@ func (me *memNode) Rename(oldName string, newParent fuse.FsNode, newName string, ...@@ -190,10 +211,11 @@ func (me *memNode) Rename(oldName string, newParent fuse.FsNode, newName string,
} }
func (me *memNode) Link(name string, existing fuse.FsNode, context *fuse.Context) (fi *os.FileInfo, newNode fuse.FsNode, code fuse.Status) { func (me *memNode) Link(name string, existing fuse.FsNode, context *fuse.Context) (fi *os.FileInfo, newNode fuse.FsNode, code fuse.Status) {
me.mutex.Lock()
defer me.mutex.Unlock()
me.Inode().AddChild(name, existing.Inode()) me.Inode().AddChild(name, existing.Inode())
fi, code = existing.GetAttr(nil, context) fi, code = existing.GetAttr(nil, context)
me.mutex.Lock()
defer me.mutex.Unlock()
me.touch() me.touch()
me.deleted[name] = false, false me.deleted[name] = false, false
return fi, existing, code return fi, existing, code
...@@ -202,6 +224,7 @@ func (me *memNode) Link(name string, existing fuse.FsNode, context *fuse.Context ...@@ -202,6 +224,7 @@ func (me *memNode) Link(name string, existing fuse.FsNode, context *fuse.Context
func (me *memNode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, fi *os.FileInfo, newNode fuse.FsNode, code fuse.Status) { func (me *memNode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file fuse.File, fi *os.FileInfo, newNode fuse.FsNode, code fuse.Status) {
me.mutex.Lock() me.mutex.Lock()
defer me.mutex.Unlock() defer me.mutex.Unlock()
n := me.newNode(false) n := me.newNode(false)
n.info.Mode = mode | fuse.S_IFREG n.info.Mode = mode | fuse.S_IFREG
n.changed = true n.changed = true
...@@ -229,9 +252,10 @@ func (me *memNodeFile) InnerFile() fuse.File { ...@@ -229,9 +252,10 @@ func (me *memNodeFile) InnerFile() fuse.File {
func (me *memNodeFile) Flush() fuse.Status { func (me *memNodeFile) Flush() fuse.Status {
code := me.File.Flush() code := me.File.Flush()
if me.writable { if me.writable {
fi, _ := me.File.GetAttr()
me.node.mutex.Lock() me.node.mutex.Lock()
defer me.node.mutex.Unlock() defer me.node.mutex.Unlock()
fi, _ := me.File.GetAttr()
me.node.info.Size = fi.Size me.node.info.Size = fi.Size
me.node.info.Blocks = fi.Blocks me.node.info.Blocks = fi.Blocks
} }
...@@ -253,7 +277,7 @@ func (me *memNode) promote() { ...@@ -253,7 +277,7 @@ func (me *memNode) promote() {
destfs := &fuse.LoopbackFileSystem{Root: "/"} destfs := &fuse.LoopbackFileSystem{Root: "/"}
fuse.CopyFile(me.fs.readonly, destfs, fuse.CopyFile(me.fs.readonly, destfs,
me.original, strings.TrimLeft(me.backing, "/"), nil) me.original, strings.TrimLeft(me.backing, "/"), nil)
me.original = ""
files := me.Inode().Files(0) files := me.Inode().Files(0)
for _, f := range files { for _, f := range files {
mf := f.File.(*memNodeFile) mf := f.File.(*memNodeFile)
...@@ -272,12 +296,14 @@ func (me *memNode) promote() { ...@@ -272,12 +296,14 @@ func (me *memNode) promote() {
func (me *memNode) Open(flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) { func (me *memNode) Open(flags uint32, context *fuse.Context) (file fuse.File, code fuse.Status) {
if flags&fuse.O_ANYWRITE != 0 { if flags&fuse.O_ANYWRITE != 0 {
me.mutex.Lock() me.mutex.Lock()
defer me.mutex.Unlock()
me.promote() me.promote()
me.touch() me.touch()
me.mutex.Unlock()
} }
me.mutex.RLock()
defer me.mutex.RUnlock()
if me.backing != "" { if me.backing != "" {
f, err := os.OpenFile(me.backing, int(flags), 0666) f, err := os.OpenFile(me.backing, int(flags), 0666)
if err != nil { if err != nil {
...@@ -383,3 +409,37 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co ...@@ -383,3 +409,37 @@ func (me *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, co
close(stream) close(stream)
return stream, fuse.OK return stream, fuse.OK
} }
func (me *memNode) Reap(path string, results map[string]*Result) {
for name, _ := range me.deleted {
p := filepath.Join(path, name)
results[p] = &Result{}
}
if me.changed {
info := me.info
results[path] = &Result{
Info: &info,
Link: me.link,
Backing: me.backing,
Original: me.original,
}
}
for n, ch := range me.Inode().FsChildren() {
p := filepath.Join(path, n)
ch.FsNode().(*memNode).Reap(p, results)
}
}
func (me *memNode) Clear(path string) {
me.original = path
me.changed = false
me.backing = ""
me.deleted = make(map[string]bool)
for n, ch := range me.Inode().FsChildren() {
p := filepath.Join(path, n)
mn := ch.FsNode().(*memNode)
mn.Clear(p)
}
}
...@@ -18,7 +18,7 @@ var _ = log.Print ...@@ -18,7 +18,7 @@ var _ = log.Print
var CheckSuccess = fuse.CheckSuccess var CheckSuccess = fuse.CheckSuccess
func setupMemUfs(t *testing.T) (workdir string, cleanup func()) { func setupMemUfs(t *testing.T) (workdir string, ufs *MemUnionFs, cleanup func()) {
// Make sure system setting does not affect test. // Make sure system setting does not affect test.
syscall.Umask(0) syscall.Umask(0)
...@@ -49,14 +49,14 @@ func setupMemUfs(t *testing.T) (workdir string, cleanup func()) { ...@@ -49,14 +49,14 @@ func setupMemUfs(t *testing.T) (workdir string, cleanup func()) {
state.Debug = fuse.VerboseTest() state.Debug = fuse.VerboseTest()
go state.Loop() go state.Loop()
return wd, func() { return wd, memFs, func() {
state.Unmount() state.Unmount()
os.RemoveAll(wd) os.RemoveAll(wd)
} }
} }
func TestMemUnionFsSymlink(t *testing.T) { func TestMemUnionFsSymlink(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.Symlink("/foobar", wd+"/mount/link") err := os.Symlink("/foobar", wd+"/mount/link")
...@@ -68,10 +68,15 @@ func TestMemUnionFsSymlink(t *testing.T) { ...@@ -68,10 +68,15 @@ func TestMemUnionFsSymlink(t *testing.T) {
if val != "/foobar" { if val != "/foobar" {
t.Errorf("symlink mismatch: %v", val) t.Errorf("symlink mismatch: %v", val)
} }
r := ufs.Reap()
if len(r) != 2 || r["link"] == nil || r["link"].Link != "/foobar" {
t.Errorf("expect 1 symlink reap result: %v", r)
}
} }
func TestMemUnionFsSymlinkPromote(t *testing.T) { func TestMemUnionFsSymlinkPromote(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.Mkdir(wd+"/ro/subdir", 0755) err := os.Mkdir(wd+"/ro/subdir", 0755)
...@@ -79,10 +84,15 @@ func TestMemUnionFsSymlinkPromote(t *testing.T) { ...@@ -79,10 +84,15 @@ func TestMemUnionFsSymlinkPromote(t *testing.T) {
err = os.Symlink("/foobar", wd+"/mount/subdir/link") err = os.Symlink("/foobar", wd+"/mount/subdir/link")
CheckSuccess(err) CheckSuccess(err)
r := ufs.Reap()
if len(r) != 2 || r["subdir"] == nil || r["subdir/link"] == nil || r["subdir/link"].Link != "/foobar" {
t.Errorf("expect 1 symlink reap result: %v", r)
}
} }
func TestMemUnionFsChtimes(t *testing.T) { func TestMemUnionFsChtimes(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
writeToFile(wd+"/ro/file", "a") writeToFile(wd+"/ro/file", "a")
...@@ -96,10 +106,15 @@ func TestMemUnionFsChtimes(t *testing.T) { ...@@ -96,10 +106,15 @@ func TestMemUnionFsChtimes(t *testing.T) {
if fi.Atime_ns != 82e9 || fi.Mtime_ns != 83e9 { if fi.Atime_ns != 82e9 || fi.Mtime_ns != 83e9 {
t.Error("Incorrect timestamp", fi) t.Error("Incorrect timestamp", fi)
} }
r := ufs.Reap()
if r["file"] == nil || r["file"].Original == "" {
t.Errorf("expect 1 file reap result: %v", r)
}
} }
func TestMemUnionFsChmod(t *testing.T) { func TestMemUnionFsChmod(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
ro_fn := wd + "/ro/file" ro_fn := wd + "/ro/file"
...@@ -113,10 +128,15 @@ func TestMemUnionFsChmod(t *testing.T) { ...@@ -113,10 +128,15 @@ func TestMemUnionFsChmod(t *testing.T) {
if fi.Mode&07777 != 07070 { if fi.Mode&07777 != 07070 {
t.Errorf("Unexpected mode found: %o", fi.Mode) t.Errorf("Unexpected mode found: %o", fi.Mode)
} }
r := ufs.Reap()
if r["file"] == nil || r["file"].Original == "" {
t.Errorf("expect 1 file reap result: %v", r)
}
} }
func TestMemUnionFsChown(t *testing.T) { func TestMemUnionFsChown(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
ro_fn := wd + "/ro/file" ro_fn := wd + "/ro/file"
...@@ -131,7 +151,7 @@ func TestMemUnionFsChown(t *testing.T) { ...@@ -131,7 +151,7 @@ func TestMemUnionFsChown(t *testing.T) {
} }
func TestMemUnionFsDelete(t *testing.T) { func TestMemUnionFsDelete(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
writeToFile(wd+"/ro/file", "a") writeToFile(wd+"/ro/file", "a")
...@@ -145,10 +165,15 @@ func TestMemUnionFsDelete(t *testing.T) { ...@@ -145,10 +165,15 @@ func TestMemUnionFsDelete(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("should have disappeared.") t.Fatal("should have disappeared.")
} }
r := ufs.Reap()
if r["file"] == nil || r["file"].Info != nil {
t.Errorf("expect 1 deletion reap result: %v", r)
}
} }
func TestMemUnionFsBasic(t *testing.T) { func TestMemUnionFsBasic(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
writeToFile(wd+"/mount/rw", "a") writeToFile(wd+"/mount/rw", "a")
...@@ -184,17 +209,22 @@ func TestMemUnionFsBasic(t *testing.T) { ...@@ -184,17 +209,22 @@ func TestMemUnionFsBasic(t *testing.T) {
} }
func TestMemUnionFsPromote(t *testing.T) { func TestMemUnionFsPromote(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.Mkdir(wd+"/ro/subdir", 0755) err := os.Mkdir(wd+"/ro/subdir", 0755)
CheckSuccess(err) CheckSuccess(err)
writeToFile(wd+"/ro/subdir/file", "content") writeToFile(wd+"/ro/subdir/file", "content")
writeToFile(wd+"/mount/subdir/file", "other-content") writeToFile(wd+"/mount/subdir/file", "other-content")
r := ufs.Reap()
if r["subdir/file"] == nil || r["subdir/file"].Backing == "" {
t.Errorf("expect 1 file reap result: %v", r)
}
} }
func TestMemUnionFsCreate(t *testing.T) { func TestMemUnionFsCreate(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.MkdirAll(wd+"/ro/subdir/sub2", 0755) err := os.MkdirAll(wd+"/ro/subdir/sub2", 0755)
...@@ -202,10 +232,15 @@ func TestMemUnionFsCreate(t *testing.T) { ...@@ -202,10 +232,15 @@ func TestMemUnionFsCreate(t *testing.T) {
writeToFile(wd+"/mount/subdir/sub2/file", "other-content") writeToFile(wd+"/mount/subdir/sub2/file", "other-content")
_, err = os.Lstat(wd + "/mount/subdir/sub2/file") _, err = os.Lstat(wd + "/mount/subdir/sub2/file")
CheckSuccess(err) CheckSuccess(err)
r := ufs.Reap()
if r["subdir/sub2/file"] == nil || r["subdir/sub2/file"].Backing == "" {
t.Errorf("expect 1 file reap result: %v", r)
}
} }
func TestMemUnionFsOpenUndeletes(t *testing.T) { func TestMemUnionFsOpenUndeletes(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
writeToFile(wd+"/ro/file", "X") writeToFile(wd+"/ro/file", "X")
...@@ -213,11 +248,10 @@ func TestMemUnionFsOpenUndeletes(t *testing.T) { ...@@ -213,11 +248,10 @@ func TestMemUnionFsOpenUndeletes(t *testing.T) {
CheckSuccess(err) CheckSuccess(err)
writeToFile(wd+"/mount/file", "X") writeToFile(wd+"/mount/file", "X")
_, err = os.Lstat(wd + "/mount/file") _, err = os.Lstat(wd + "/mount/file")
CheckSuccess(err)
} }
func TestMemUnionFsMkdir(t *testing.T) { func TestMemUnionFsMkdir(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
dirname := wd + "/mount/subdir" dirname := wd + "/mount/subdir"
...@@ -226,10 +260,15 @@ func TestMemUnionFsMkdir(t *testing.T) { ...@@ -226,10 +260,15 @@ func TestMemUnionFsMkdir(t *testing.T) {
err = os.Remove(dirname) err = os.Remove(dirname)
CheckSuccess(err) CheckSuccess(err)
r := ufs.Reap()
if len(r) > 2 || r[""] == nil || r["subdir"] == nil {
t.Errorf("expect 1 file reap result: %v", r)
}
} }
func TestMemUnionFsMkdirPromote(t *testing.T) { func TestMemUnionFsMkdirPromote(t *testing.T) {
wd, clean := setupMemUfs(t) wd, ufs, clean := setupMemUfs(t)
defer clean() defer clean()
dirname := wd + "/ro/subdir/subdir2" dirname := wd + "/ro/subdir/subdir2"
...@@ -238,10 +277,15 @@ func TestMemUnionFsMkdirPromote(t *testing.T) { ...@@ -238,10 +277,15 @@ func TestMemUnionFsMkdirPromote(t *testing.T) {
err = os.Mkdir(wd+"/mount/subdir/subdir2/dir3", 0755) err = os.Mkdir(wd+"/mount/subdir/subdir2/dir3", 0755)
CheckSuccess(err) CheckSuccess(err)
r := ufs.Reap()
if r["subdir/subdir2/dir3"] == nil || r["subdir/subdir2/dir3"].Info.Mode & fuse.S_IFDIR == 0 {
t.Errorf("expect 1 file reap result: %v", r)
}
} }
func TestMemUnionFsRmdirMkdir(t *testing.T) { func TestMemUnionFsRmdirMkdir(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.Mkdir(wd+"/ro/subdir", 0755) err := os.Mkdir(wd+"/ro/subdir", 0755)
...@@ -256,7 +300,7 @@ func TestMemUnionFsRmdirMkdir(t *testing.T) { ...@@ -256,7 +300,7 @@ func TestMemUnionFsRmdirMkdir(t *testing.T) {
} }
func TestMemUnionFsLink(t *testing.T) { func TestMemUnionFsLink(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
content := "blabla" content := "blabla"
...@@ -282,7 +326,7 @@ func TestMemUnionFsLink(t *testing.T) { ...@@ -282,7 +326,7 @@ func TestMemUnionFsLink(t *testing.T) {
} }
func TestMemUnionFsTruncate(t *testing.T) { func TestMemUnionFsTruncate(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
writeToFile(wd+"/ro/file", "hello") writeToFile(wd+"/ro/file", "hello")
...@@ -295,7 +339,7 @@ func TestMemUnionFsTruncate(t *testing.T) { ...@@ -295,7 +339,7 @@ func TestMemUnionFsTruncate(t *testing.T) {
func TestMemUnionFsCopyChmod(t *testing.T) { func TestMemUnionFsCopyChmod(t *testing.T) {
t.Log("TestCopyChmod") t.Log("TestCopyChmod")
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
contents := "hello" contents := "hello"
...@@ -321,7 +365,7 @@ func TestMemUnionFsCopyChmod(t *testing.T) { ...@@ -321,7 +365,7 @@ func TestMemUnionFsCopyChmod(t *testing.T) {
func TestMemUnionFsTruncateTimestamp(t *testing.T) { func TestMemUnionFsTruncateTimestamp(t *testing.T) {
t.Log("TestTruncateTimestamp") t.Log("TestTruncateTimestamp")
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
contents := "hello" contents := "hello"
...@@ -344,7 +388,7 @@ func TestMemUnionFsTruncateTimestamp(t *testing.T) { ...@@ -344,7 +388,7 @@ func TestMemUnionFsTruncateTimestamp(t *testing.T) {
func TestMemUnionFsRemoveAll(t *testing.T) { func TestMemUnionFsRemoveAll(t *testing.T) {
t.Log("TestRemoveAll") t.Log("TestRemoveAll")
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.MkdirAll(wd+"/ro/dir/subdir", 0755) err := os.MkdirAll(wd+"/ro/dir/subdir", 0755)
...@@ -368,7 +412,7 @@ func TestMemUnionFsRemoveAll(t *testing.T) { ...@@ -368,7 +412,7 @@ func TestMemUnionFsRemoveAll(t *testing.T) {
} }
func TestMemUnionFsRmRf(t *testing.T) { func TestMemUnionFsRmRf(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
err := os.MkdirAll(wd+"/ro/dir/subdir", 0755) err := os.MkdirAll(wd+"/ro/dir/subdir", 0755)
...@@ -394,7 +438,7 @@ func TestMemUnionFsRmRf(t *testing.T) { ...@@ -394,7 +438,7 @@ func TestMemUnionFsRmRf(t *testing.T) {
} }
func TestMemUnionFsDeletedGetAttr(t *testing.T) { func TestMemUnionFsDeletedGetAttr(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
err := ioutil.WriteFile(wd+"/ro/file", []byte("blabla"), 0644) err := ioutil.WriteFile(wd+"/ro/file", []byte("blabla"), 0644)
...@@ -413,7 +457,7 @@ func TestMemUnionFsDeletedGetAttr(t *testing.T) { ...@@ -413,7 +457,7 @@ func TestMemUnionFsDeletedGetAttr(t *testing.T) {
} }
func TestMemUnionFsDoubleOpen(t *testing.T) { func TestMemUnionFsDoubleOpen(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
err := ioutil.WriteFile(wd+"/ro/file", []byte("blablabla"), 0644) err := ioutil.WriteFile(wd+"/ro/file", []byte("blablabla"), 0644)
CheckSuccess(err) CheckSuccess(err)
...@@ -451,7 +495,7 @@ func TestMemUnionFsFdLeak(t *testing.T) { ...@@ -451,7 +495,7 @@ func TestMemUnionFsFdLeak(t *testing.T) {
beforeEntries, err := ioutil.ReadDir("/proc/self/fd") beforeEntries, err := ioutil.ReadDir("/proc/self/fd")
CheckSuccess(err) CheckSuccess(err)
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
err = ioutil.WriteFile(wd+"/ro/file", []byte("blablabla"), 0644) err = ioutil.WriteFile(wd+"/ro/file", []byte("blablabla"), 0644)
CheckSuccess(err) CheckSuccess(err)
...@@ -472,7 +516,7 @@ func TestMemUnionFsFdLeak(t *testing.T) { ...@@ -472,7 +516,7 @@ func TestMemUnionFsFdLeak(t *testing.T) {
} }
func TestMemUnionFsStatFs(t *testing.T) { func TestMemUnionFsStatFs(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
s1 := syscall.Statfs_t{} s1 := syscall.Statfs_t{}
...@@ -486,7 +530,7 @@ func TestMemUnionFsStatFs(t *testing.T) { ...@@ -486,7 +530,7 @@ func TestMemUnionFsStatFs(t *testing.T) {
} }
func TestMemUnionFsFlushSize(t *testing.T) { func TestMemUnionFsFlushSize(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
fn := wd + "/mount/file" fn := wd + "/mount/file"
...@@ -507,7 +551,7 @@ func TestMemUnionFsFlushSize(t *testing.T) { ...@@ -507,7 +551,7 @@ func TestMemUnionFsFlushSize(t *testing.T) {
} }
func TestMemUnionFsFlushRename(t *testing.T) { func TestMemUnionFsFlushRename(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
err := ioutil.WriteFile(wd+"/mount/file", []byte("x"), 0644) err := ioutil.WriteFile(wd+"/mount/file", []byte("x"), 0644)
...@@ -534,7 +578,7 @@ func TestMemUnionFsFlushRename(t *testing.T) { ...@@ -534,7 +578,7 @@ func TestMemUnionFsFlushRename(t *testing.T) {
} }
func TestMemUnionFsTruncGetAttr(t *testing.T) { func TestMemUnionFsTruncGetAttr(t *testing.T) {
wd, clean := setupMemUfs(t) wd, _, clean := setupMemUfs(t)
defer clean() defer clean()
c := []byte("hello") c := []byte("hello")
......
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