From c6768d88756fb402e6cd43a8c3d53a6d4f3755c4 Mon Sep 17 00:00:00 2001 From: Dustin Sallings Date: Thu, 26 Dec 2013 21:46:26 -0800 Subject: [PATCH] fuse: Enable tests on Linux; make them pass This is essentially two things: 1. Trivial changes to fs_test to make it not skip on Linux 2. Move much of the logic that was in *mutFile.Release into *mutFile.Flush See http://sourceforge.net/apps/mediawiki/fuse/index.php?title=FUSE_tutorial and the FUSE FAQ for an explanation of Flush vs. Release. Change-Id: Id63312b3f8ebf12917338b836beb8a7a736d4fe6 --- pkg/fs/fs_test.go | 6 +++++- pkg/fs/mut.go | 35 +++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/pkg/fs/fs_test.go b/pkg/fs/fs_test.go index 6cc01bf6b..1e6630820 100644 --- a/pkg/fs/fs_test.go +++ b/pkg/fs/fs_test.go @@ -50,7 +50,7 @@ func condSkip(t *testing.T) { if lasterr != nil { t.Skipf("Skipping test; some other test already failed.") } - if runtime.GOOS != "darwin" { + if !(runtime.GOOS == "darwin" || runtime.GOOS == "linux") { t.Skipf("Skipping test on OS %q", runtime.GOOS) } if runtime.GOOS == "darwin" { @@ -567,6 +567,10 @@ func dirToBeFUSE(dir string) func() bool { } return false } + if runtime.GOOS == "linux" { + return strings.Contains(string(out), "/dev/fuse") && + strings.Contains(string(out), dir) + } return false } } diff --git a/pkg/fs/mut.go b/pkg/fs/mut.go index ccd987d89..a5acb8357 100644 --- a/pkg/fs/mut.go +++ b/pkg/fs/mut.go @@ -646,25 +646,48 @@ func (h *mutFileHandle) Write(req *fuse.WriteRequest, res *fuse.WriteResponse, i return nil } -func (h *mutFileHandle) Release(req *fuse.ReleaseRequest, intr fuse.Intr) fuse.Error { +// Flush is called to let the file system clean up any data buffers +// and to pass any errors in the process of closing a file to the user +// application. +// +// Flush *may* be called more than once in the case where a file is +// opened more than once, but it's not possible to detect from the +// call itself whether this is a final flush. +// +// This is generally the last opportunity to finalize data and the +// return value sets the return value of the Close that led to the +// calling of Flush. +// +// Note that this is distinct from Fsync -- which is a user-requested +// flush (fsync, etc...) +func (h *mutFileHandle) Flush(*fuse.FlushRequest, fuse.Intr) fuse.Error { if h.tmp == nil { - log.Printf("Release called on camli mutFileHandle without a tempfile set") + log.Printf("Flush called on camli mutFileHandle without a tempfile set") return fuse.EIO } - log.Printf("mutFileHandle release.") _, err := h.tmp.Seek(0, 0) if err != nil { - log.Println("mutFileHandle.Release:", err) + log.Println("mutFileHandle.Flush:", err) return fuse.EIO } var n int64 br, err := schema.WriteFileFromReader(h.f.fs.client, h.f.name, readerutil.CountingReader{Reader: h.tmp, N: &n}) if err != nil { - log.Println("mutFileHandle.Release:", err) + log.Println("mutFileHandle.Flush:", err) + return fuse.EIO + } + err = h.f.setContent(br, n) + if err != nil { + log.Printf("mutFileHandle.Flush: %v", err) return fuse.EIO } - h.f.setContent(br, n) + return nil +} + +// Release is called when a file handle is no longer needed. This is +// called asynchronously after the last handle to a file is closed. +func (h *mutFileHandle) Release(req *fuse.ReleaseRequest, intr fuse.Intr) fuse.Error { h.tmp.Close() os.Remove(h.tmp.Name()) h.tmp = nil