Updated mounted_file_system.go.
parent
c5702ef0a2
commit
210a91dd93
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue