// Mount makes the contents of the volume visible at the given // mountpoint. If Mount returns with a nil error, the mount has // occurred. func (ref *VolumeRef) Mount(mountpoint string) error { ref.app.volumes.Lock() defer ref.app.volumes.Unlock() // TODO obey `bazil -debug server run` if ref.mounted { return errors.New("volume already mounted") } conn, err := fuse.Mount(mountpoint, fuse.MaxReadahead(32*1024*1024), fuse.AsyncRead(), ) if err != nil { return fmt.Errorf("mount fail: %v", err) } srv := fusefs.New(conn, nil) serveErr := make(chan error, 1) go func() { defer func() { // remove map entry on unmount or failed mount ref.app.volumes.Lock() ref.mounted = false ref.conn = nil ref.app.volumes.Unlock() ref.app.volumes.Broadcast() ref.Close() }() defer conn.Close() ref.fs.SetFUSE(srv) defer func() { ref.fs.SetFUSE(nil) }() serveErr <- srv.Serve(ref.fs) }() select { case <-conn.Ready: if err := conn.MountError; err != nil { return fmt.Errorf("mount fail (delayed): %v", err) } ref.refs++ ref.mounted = true ref.conn = conn ref.app.volumes.Broadcast() return nil case err := <-serveErr: // Serve quit early if err != nil { return fmt.Errorf("filesystem failure: %v", err) } return errors.New("Serve exited early") } }
func benchmark(b *testing.B, fn func(b *testing.B, mnt string), conf *benchConfig) { filesys := benchFS{ conf: conf, } mnt, err := fstestutil.Mounted(filesys, nil, fuse.MaxReadahead(64*1024*1024), fuse.AsyncRead(), fuse.WritebackCache(), ) if err != nil { b.Fatal(err) } defer mnt.Close() fn(b, mnt.Dir) }