From 21ac1b6da5a0e34b000dad5cc545eea2b164bd33 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Tue, 11 Aug 2015 10:54:52 +1000 Subject: [PATCH 1/2] Moved Mount into its own file. --- mount.go | 84 ++++++++++++++++++++++++++++++++++++++++++ mounted_file_system.go | 69 +--------------------------------- 2 files changed, 85 insertions(+), 68 deletions(-) create mode 100644 mount.go diff --git a/mount.go b/mount.go new file mode 100644 index 0000000..2d8a940 --- /dev/null +++ b/mount.go @@ -0,0 +1,84 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fuse + +import ( + "fmt" + + "golang.org/x/net/context" +) + +// A type that knows how to serve ops read from a connection. +type Server interface { + // Read and serve ops from the supplied connection until EOF. Do not return + // until all operations have been responded to. Must not be called more than + // once. + ServeOps(*Connection) +} + +// Attempt to mount a file system on the given directory, using the supplied +// Server to serve connection requests. This function blocks until the file +// system is successfully mounted. +func Mount( + dir string, + server Server, + config *MountConfig) (mfs *MountedFileSystem, err error) { + // Initialize the struct. + mfs = &MountedFileSystem{ + dir: dir, + joinStatusAvailable: make(chan struct{}), + } + + // Begin the mounting process, which will continue in the background. + ready := make(chan error, 1) + dev, err := mount(dir, config, ready) + if err != nil { + err = fmt.Errorf("mount: %v", err) + return + } + + // Choose a parent context for ops. + opContext := config.OpContext + if opContext == nil { + opContext = context.Background() + } + + // Create a Connection object wrapping the device. + connection, err := newConnection( + opContext, + config.DebugLogger, + config.ErrorLogger, + dev) + + if err != nil { + err = fmt.Errorf("newConnection: %v", err) + return + } + + // Serve the connection in the background. When done, set the join status. + go func() { + server.ServeOps(connection) + mfs.joinStatus = connection.close() + close(mfs.joinStatusAvailable) + }() + + // Wait for the mount process to complete. + if err = <-ready; err != nil { + err = fmt.Errorf("mount (background): %v", err) + return + } + + return +} diff --git a/mounted_file_system.go b/mounted_file_system.go index 54532bb..45811d9 100644 --- a/mounted_file_system.go +++ b/mounted_file_system.go @@ -14,19 +14,7 @@ package fuse -import ( - "fmt" - - "golang.org/x/net/context" -) - -// A type that knows how to serve ops read from a connection. -type Server interface { - // Read and serve ops from the supplied connection until EOF. Do not return - // until all operations have been responded to. Must not be called more than - // once. - ServeOps(*Connection) -} +import "golang.org/x/net/context" // A struct representing the status of a mount operation, with a method that // waits for unmounting. @@ -58,58 +46,3 @@ func (mfs *MountedFileSystem) Join(ctx context.Context) error { return ctx.Err() } } - -// Attempt to mount a file system on the given directory, using the supplied -// Server to serve connection requests. This function blocks until the file -// system is successfully mounted. -func Mount( - dir string, - server Server, - config *MountConfig) (mfs *MountedFileSystem, err error) { - // Initialize the struct. - mfs = &MountedFileSystem{ - dir: dir, - joinStatusAvailable: make(chan struct{}), - } - - // Begin the mounting process, which will continue in the background. - ready := make(chan error, 1) - dev, err := mount(dir, config, ready) - if err != nil { - err = fmt.Errorf("mount: %v", err) - return - } - - // Choose a parent context for ops. - opContext := config.OpContext - if opContext == nil { - opContext = context.Background() - } - - // Create a Connection object wrapping the device. - connection, err := newConnection( - opContext, - config.DebugLogger, - config.ErrorLogger, - dev) - - if err != nil { - err = fmt.Errorf("newConnection: %v", err) - return - } - - // Serve the connection in the background. When done, set the join status. - go func() { - server.ServeOps(connection) - mfs.joinStatus = connection.close() - close(mfs.joinStatusAvailable) - }() - - // Wait for the mount process to complete. - if err = <-ready; err != nil { - err = fmt.Errorf("mount (background): %v", err) - return - } - - return -} From 3574e9aa49d8048619fccd233d603f497975efb2 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Tue, 11 Aug 2015 10:55:43 +1000 Subject: [PATCH 2/2] Make sure the mount point exists up front. --- mount.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mount.go b/mount.go index 2d8a940..7f9c553 100644 --- a/mount.go +++ b/mount.go @@ -16,6 +16,7 @@ package fuse import ( "fmt" + "os" "golang.org/x/net/context" ) @@ -35,6 +36,22 @@ func Mount( dir string, server Server, config *MountConfig) (mfs *MountedFileSystem, err error) { + // Sanity check: make sure the mount point exists and is a directory. This + // saves us from some confusing errors later on OS X. + fi, err := os.Stat(dir) + switch { + case os.IsNotExist(err): + return + + case err != nil: + err = fmt.Errorf("Statting mount point: %v", err) + return + + case !fi.IsDir(): + err = fmt.Errorf("Mount point %s is not a directory", dir) + return + } + // Initialize the struct. mfs = &MountedFileSystem{ dir: dir,