Updated mounted_file_system.go.
parent
c5702ef0a2
commit
210a91dd93
|
@ -27,7 +27,11 @@ type Connection struct {
|
|||
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
|
||||
// closed the connection.
|
||||
|
@ -59,3 +63,7 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Connection) waitForReady() (err error)
|
||||
|
||||
func (c *Connection) close() (err error)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
package fuse
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/jacobsa/bazilfuse"
|
||||
|
@ -31,11 +31,6 @@ type Server func(*Connection)
|
|||
type MountedFileSystem struct {
|
||||
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.
|
||||
joinStatus error
|
||||
joinStatusAvailable chan struct{}
|
||||
|
@ -68,46 +63,6 @@ func (mfs *MountedFileSystem) Unmount() error {
|
|||
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.
|
||||
type MountConfig struct {
|
||||
// OS X only.
|
||||
|
@ -149,19 +104,42 @@ func Mount(
|
|||
dir string,
|
||||
server Server,
|
||||
config *MountConfig) (mfs *MountedFileSystem, err error) {
|
||||
logger := getLogger()
|
||||
|
||||
// Initialize the struct.
|
||||
mfs = &MountedFileSystem{
|
||||
dir: dir,
|
||||
readyStatusAvailable: make(chan struct{}),
|
||||
joinStatusAvailable: make(chan struct{}),
|
||||
dir: dir,
|
||||
joinStatusAvailable: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Mount in the background.
|
||||
go mfs.mountAndServe(server, config.bazilfuseOptions())
|
||||
// Open a bazilfuse connection.
|
||||
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.
|
||||
<-mfs.readyStatusAvailable
|
||||
err = mfs.readyStatus
|
||||
// Create our own Connection object wrapping it.
|
||||
connection, err := newConnection(logger, bfConn)
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue