func (m *mounter) Mount( address string, mountPoint string, shard uint64, modulus uint64, ) (retErr error) { // TODO: should we make the caller do this? if err := os.MkdirAll(mountPoint, 0777); err != nil { return err } name := namePrefix + address conn, err := fuse.Mount( mountPoint, fuse.FSName(name), fuse.VolumeName(name), fuse.Subtype(subtype), fuse.AllowOther(), fuse.WritebackCache(), fuse.MaxReadahead(1<<32-1), ) if err != nil { return err } defer func() { if err := conn.Close(); err != nil && retErr == nil { retErr = err } }() if err := fs.Serve(conn, newFilesystem(m.apiClient, shard, modulus)); err != nil { return err } <-conn.Ready return conn.MountError }
// mountOptions configures the options from the command line flags func mountOptions(device string) (options []fuse.MountOption) { options = []fuse.MountOption{ fuse.MaxReadahead(uint32(maxReadAhead)), fuse.Subtype("rclone"), fuse.FSName(device), fuse.VolumeName(device), fuse.NoAppleDouble(), fuse.NoAppleXattr(), // Options from benchmarking in the fuse module //fuse.MaxReadahead(64 * 1024 * 1024), //fuse.AsyncRead(), - FIXME this causes // ReadFileHandle.Read error: read /home/files/ISOs/xubuntu-15.10-desktop-amd64.iso: bad file descriptor // which is probably related to errors people are having //fuse.WritebackCache(), } if allowNonEmpty { options = append(options, fuse.AllowNonEmptyMount()) } if allowOther { options = append(options, fuse.AllowOther()) } if allowRoot { options = append(options, fuse.AllowRoot()) } if defaultPermissions { options = append(options, fuse.DefaultPermissions()) } if readOnly { options = append(options, fuse.ReadOnly()) } if writebackCache { options = append(options, fuse.WritebackCache()) } return options }
func (m *mounter) Mount(apiClient pfs.ApiClient, repositoryName string, mountPoint string, shard uint64, modulus uint64) (retErr error) { if err := os.MkdirAll(mountPoint, 0777); err != nil { return err } conn, err := fuse.Mount( mountPoint, fuse.FSName(namePrefix+repositoryName), fuse.VolumeName(namePrefix+repositoryName), fuse.Subtype(subtype), fuse.WritebackCache(), fuse.MaxReadahead(1<<32-1), ) if err != nil { return err } defer func() { if err := conn.Close(); err != nil && retErr == nil { retErr = err } }() close(m.ready) if err := fs.Serve(conn, &filesystem{apiClient, repositoryName, shard, modulus}); err != nil { return err } // check if the mount process has an error to report <-conn.Ready return conn.MountError }
// 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 (m *mounter) Mount( mountPoint string, shard *pfsclient.Shard, commitMounts []*CommitMount, ready chan bool, debug bool, ) (retErr error) { var once sync.Once defer once.Do(func() { if ready != nil { close(ready) } }) name := namePrefix + m.address conn, err := fuse.Mount( mountPoint, fuse.FSName(name), fuse.VolumeName(name), fuse.Subtype(subtype), fuse.AllowOther(), fuse.WritebackCache(), fuse.MaxReadahead(1<<32-1), ) if err != nil { return err } defer func() { if err := conn.Close(); err != nil && retErr == nil { retErr = err } }() sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt) go func() { <-sigChan m.Unmount(mountPoint) }() once.Do(func() { if ready != nil { close(ready) } }) config := &fs.Config{} if debug { config.Debug = func(msg interface{}) { lion.Printf("%+v", msg) } } if err := fs.New(conn, config).Serve(newFilesystem(m.apiClient, shard, commitMounts)); err != nil { return err } <-conn.Ready return conn.MountError }
// Mounts the filesystem func (this *FileSystem) Mount() (*fuse.Conn, error) { conn, err := fuse.Mount( this.MountPoint, fuse.FSName("hdfs"), fuse.Subtype("hdfs"), fuse.VolumeName("HDFS filesystem"), fuse.AllowOther(), fuse.WritebackCache(), fuse.MaxReadahead(1024*64)) //TODO: make configurable if err != nil { return nil, err } this.Mounted = true return conn, nil }
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) }
func (m *mounter) Mount( repositoryName string, commitID string, mountPoint string, shard uint64, modulus uint64, ) (retErr error) { // TODO(pedge): should we make the caller do this? if err := os.MkdirAll(mountPoint, 0777); err != nil { return err } name := namePrefix + repositoryName if commitID != "" { name = name + "-" + commitID } conn, err := fuse.Mount( mountPoint, fuse.FSName(name), fuse.VolumeName(name), fuse.Subtype(subtype), fuse.AllowOther(), fuse.WritebackCache(), fuse.MaxReadahead(1<<32-1), ) if err != nil { return err } errChan := make(chan error, 1) m.lock.Lock() if _, ok := m.mountpointToErrChan[mountPoint]; ok { m.lock.Unlock() return fmt.Errorf("mountpoint %s already exists", mountPoint) } m.mountpointToErrChan[mountPoint] = errChan m.lock.Unlock() go func() { err := fs.Serve(conn, newFilesystem(m.apiClient, repositoryName, commitID, shard, modulus)) closeErr := conn.Close() if err != nil { errChan <- err } else { errChan <- closeErr } }() <-conn.Ready return conn.MountError }
func (m *mounter) Mount( mountPoint string, shard *pfs.Shard, commitMounts []*CommitMount, ready chan bool, ) (retErr error) { var once sync.Once defer once.Do(func() { if ready != nil { close(ready) } }) // TODO: should we make the caller do this? if err := os.MkdirAll(mountPoint, 0777); err != nil { return err } name := namePrefix + m.address conn, err := fuse.Mount( mountPoint, fuse.FSName(name), fuse.VolumeName(name), fuse.Subtype(subtype), fuse.AllowOther(), fuse.WritebackCache(), fuse.MaxReadahead(1<<32-1), ) if err != nil { return err } defer func() { if err := conn.Close(); err != nil && retErr == nil { retErr = err } }() once.Do(func() { if ready != nil { close(ready) } }) if err := fs.Serve(conn, newFilesystem(m.apiClient, shard, commitMounts)); err != nil { return err } <-conn.Ready return conn.MountError }
func mountOptions(device string) (options []fuse.MountOption) { if svfs.AllowOther { options = append(options, fuse.AllowOther()) } if svfs.AllowRoot { options = append(options, fuse.AllowRoot()) } if svfs.DefaultPermissions { options = append(options, fuse.DefaultPermissions()) } if svfs.ReadOnly { options = append(options, fuse.ReadOnly()) } options = append(options, fuse.MaxReadahead(uint32(svfs.ReadAheadSize))) options = append(options, fuse.Subtype("svfs")) options = append(options, fuse.FSName(device)) return options }