[ARVADOS] updated: 1.1.1-251-gc4995c2

Git user git at public.curoverse.com
Sun Dec 17 20:16:37 EST 2017


Summary of changes:
 lib/mount/fs.go | 63 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 43 insertions(+), 20 deletions(-)

       via  c4995c2790925a9abe9c04f0d5efc30b3eef86e6 (commit)
      from  fd4f528b055d4167d3b9e8c803db0641b2e0b2e8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit c4995c2790925a9abe9c04f0d5efc30b3eef86e6
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Sun Dec 17 20:14:54 2017 -0500

    go-fuse: Fix seek/read/write race.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/lib/mount/fs.go b/lib/mount/fs.go
index 331c3cb..488622f 100644
--- a/lib/mount/fs.go
+++ b/lib/mount/fs.go
@@ -10,6 +10,14 @@ import (
 	"github.com/curoverse/cgofuse/fuse"
 )
 
+// sharedFile wraps arvados.File with a sync.Mutex, so fuse can safely
+// use a single filehandle concurrently on behalf of multiple
+// threads/processes.
+type sharedFile struct {
+	arvados.File
+	sync.Mutex
+}
+
 type keepFS struct {
 	fuse.FileSystemBase
 	Client     *arvados.Client
@@ -19,7 +27,7 @@ type keepFS struct {
 	Gid        int
 
 	root   arvados.FileSystem
-	open   map[uint64]arvados.File
+	open   map[uint64]*sharedFile
 	lastFH uint64
 	sync.Mutex
 }
@@ -32,14 +40,20 @@ func (fs *keepFS) newFH(f arvados.File) uint64 {
 	fs.Lock()
 	defer fs.Unlock()
 	if fs.open == nil {
-		fs.open = make(map[uint64]arvados.File)
+		fs.open = make(map[uint64]*sharedFile)
 	}
 	fs.lastFH++
 	fh := fs.lastFH
-	fs.open[fh] = f
+	fs.open[fh] = &sharedFile{File: f}
 	return fh
 }
 
+func (fs *keepFS) lookupFH(fh uint64) *sharedFile {
+	fs.Lock()
+	defer fs.Unlock()
+	return fs.open[fh]
+}
+
 func (fs *keepFS) Init() {
 	fs.root = fs.Client.SiteFileSystem(fs.KeepClient)
 }
@@ -165,14 +179,18 @@ func (fs *keepFS) Truncate(path string, size int64, fh uint64) (errc int) {
 	if fs.ReadOnly {
 		return -fuse.EROFS
 	}
-	f := fs.lookupFH(fh)
-	if f == nil {
-		var err error
-		if f, err = fs.root.OpenFile(path, os.O_RDWR, 0); err != nil {
-			return fs.errCode(err)
-		}
-		defer f.Close()
+
+	// Sometimes fh is a valid filehandle and we don't need to
+	// waste a name lookup.
+	if f := fs.lookupFH(fh); f != nil {
+		return fs.errCode(f.Truncate(size))
+	}
+
+	// Other times, fh is invalid and we need to lookup path.
+	if f, err := fs.root.OpenFile(path, os.O_RDWR, 0); err != nil {
+		return fs.errCode(err)
 	}
+	defer f.Close()
 	return fs.errCode(f.Truncate(size))
 }
 
@@ -180,8 +198,10 @@ func (fs *keepFS) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int)
 	var fi os.FileInfo
 	var err error
 	if f := fs.lookupFH(fh); f != nil {
+		// Valid filehandle -- ignore path.
 		fi, err = f.Stat()
 	} else {
+		// Invalid filehandle -- lookup path.
 		fi, err = fs.root.Stat(path)
 	}
 	if err != nil {
@@ -233,9 +253,14 @@ func (fs *keepFS) fillStat(stat *fuse.Stat_t, fi os.FileInfo) {
 func (fs *keepFS) Write(path string, buf []byte, ofst int64, fh uint64) (n int) {
 	if fs.ReadOnly {
 		return -fuse.EROFS
-	} else if f := fs.lookupFH(fh); f == nil {
+	}
+	f := fs.lookupFH(fh)
+	if f == nil {
 		return -fuse.EBADF
-	} else if _, err := f.Seek(ofst, io.SeekStart); err != nil {
+	}
+	f.Lock()
+	defer f.Unlock()
+	if _, err := f.Seek(ofst, io.SeekStart); err != nil {
 		return fs.errCode(err)
 	} else {
 		n, _ = f.Write(buf)
@@ -244,9 +269,13 @@ func (fs *keepFS) Write(path string, buf []byte, ofst int64, fh uint64) (n int)
 }
 
 func (fs *keepFS) Read(path string, buf []byte, ofst int64, fh uint64) (n int) {
-	if f := fs.lookupFH(fh); f == nil {
+	f := fs.lookupFH(fh)
+	if f == nil {
 		return -fuse.EBADF
-	} else if _, err := f.Seek(ofst, io.SeekStart); err != nil {
+	}
+	f.Lock()
+	defer f.Unlock()
+	if _, err := f.Seek(ofst, io.SeekStart); err != nil {
 		return fs.errCode(err)
 	} else {
 		n, _ = f.Read(buf)
@@ -275,9 +304,3 @@ func (fs *keepFS) Readdir(path string,
 	}
 	return 0
 }
-
-func (fs *keepFS) lookupFH(fh uint64) arvados.File {
-	fs.Lock()
-	defer fs.Unlock()
-	return fs.open[fh]
-}

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list