Updated mounted_file_system.go.

geesefs-0-30-9
Aaron Jacobs 2015-03-24 15:34:50 +11:00
parent c5702ef0a2
commit 210a91dd93
2 changed files with 41 additions and 55 deletions

View File

@ -27,7 +27,11 @@ type Connection struct {
wrapped *bazilfuse.Conn wrapped *bazilfuse.Conn
} }
func newConnection(wrapped *bazilfuse.Conn) (c *Connection, err error) // Responsibility for closing the wrapped connection is transferred to the
// result. You must call c.close() eventually.
func newConnection(
logger *log.Logger,
wrapped *bazilfuse.Conn) (c *Connection, err error)
// Read the next op from the kernel process. Return io.EOF if the kernel has // Read the next op from the kernel process. Return io.EOF if the kernel has
// closed the connection. // closed the connection.
@ -59,3 +63,7 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
return return
} }
} }
func (c *Connection) waitForReady() (err error)
func (c *Connection) close() (err error)

View File

@ -15,7 +15,7 @@
package fuse package fuse
import ( import (
"errors" "fmt"
"runtime" "runtime"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/bazilfuse"
@ -31,11 +31,6 @@ type Server func(*Connection)
type MountedFileSystem struct { type MountedFileSystem struct {
dir string dir string
// The result of opening a bazilfuse connection and beginning to serve. Not
// valid until the channel is closed.
readyStatus error
readyStatusAvailable chan struct{}
// The result to return from Join. Not valid until the channel is closed. // The result to return from Join. Not valid until the channel is closed.
joinStatus error joinStatus error
joinStatusAvailable chan struct{} joinStatusAvailable chan struct{}
@ -68,46 +63,6 @@ func (mfs *MountedFileSystem) Unmount() error {
return bazilfuse.Unmount(mfs.dir) return bazilfuse.Unmount(mfs.dir)
} }
// Runs in the background.
func (mfs *MountedFileSystem) mountAndServe(
server *server,
options []bazilfuse.MountOption) {
logger := getLogger()
// Open a FUSE connection.
logger.Println("Opening a FUSE connection.")
c, err := bazilfuse.Mount(mfs.dir, options...)
if err != nil {
mfs.readyStatus = errors.New("bazilfuse.Mount: " + err.Error())
close(mfs.readyStatusAvailable)
return
}
defer c.Close()
// Start a goroutine that will notify the MountedFileSystem object when the
// connection says it is ready (or it fails to become ready).
go func() {
logger.Println("Waiting for the FUSE connection to be ready.")
<-c.Ready
logger.Println("The FUSE connection is ready.")
mfs.readyStatus = c.MountError
close(mfs.readyStatusAvailable)
}()
// Serve the connection using the file system object.
logger.Println("Serving the FUSE connection.")
if err := server.Serve(c); err != nil {
mfs.joinStatus = errors.New("Serve: " + err.Error())
close(mfs.joinStatusAvailable)
return
}
// Signal that everything is okay.
close(mfs.joinStatusAvailable)
}
// Optional configuration accepted by Mount. // Optional configuration accepted by Mount.
type MountConfig struct { type MountConfig struct {
// OS X only. // OS X only.
@ -149,19 +104,42 @@ func Mount(
dir string, dir string,
server Server, server Server,
config *MountConfig) (mfs *MountedFileSystem, err error) { config *MountConfig) (mfs *MountedFileSystem, err error) {
logger := getLogger()
// Initialize the struct. // Initialize the struct.
mfs = &MountedFileSystem{ mfs = &MountedFileSystem{
dir: dir, dir: dir,
readyStatusAvailable: make(chan struct{}), joinStatusAvailable: make(chan struct{}),
joinStatusAvailable: make(chan struct{}),
} }
// Mount in the background. // Open a bazilfuse connection.
go mfs.mountAndServe(server, config.bazilfuseOptions()) logger.Println("Opening a bazilfuse connection.")
bfConn, err := bazilfuse.Mount(mfs.dir, config.bazilfuseOptions()...)
if err != nil {
err = fmt.Errorf("bazilfuse.Mount: %v", err)
return
}
// Wait for ready. // Create our own Connection object wrapping it.
<-mfs.readyStatusAvailable connection, err := newConnection(logger, bfConn)
err = mfs.readyStatus if err != nil {
bfConn.Close()
err = fmt.Errorf("newConnection: %v", err)
return
}
// Serve the connection in the background. When done, set the join status.
go func() {
server(connection)
mfs.joinStatus = connection.close()
close(mfs.joinStatusAvailable)
}()
// Wait for the connection to say it is ready.
if err = connection.waitForReady(); err != nil {
err = fmt.Errorf("WaitForReady: %v", err)
return
}
return return
} }