diff --git a/internal/agent/vssfs/vssfs.go b/internal/agent/vssfs/vssfs.go index 5162a954..b93a3465 100644 --- a/internal/agent/vssfs/vssfs.go +++ b/internal/agent/vssfs/vssfs.go @@ -422,8 +422,8 @@ func (s *VSSFSServer) handleFstat(req arpc.Request) (arpc.Response, error) { } func (s *VSSFSServer) abs(filename string) (string, error) { - if filename == s.rootDir { - filename = string(filepath.Separator) + if filename == "" || filename == "." { + return s.rootDir, nil } path, err := securejoin.SecureJoin(s.rootDir, filename) diff --git a/internal/backend/arpc/fs.go b/internal/backend/arpc/fs.go index 0a5fabb4..99c9bae7 100644 --- a/internal/backend/arpc/fs.go +++ b/internal/backend/arpc/fs.go @@ -12,7 +12,6 @@ import ( "github.com/go-git/go-billy/v5" "github.com/sonroyaalmerol/pbs-plus/internal/arpc" - "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc/fuse" "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc/types" "github.com/sonroyaalmerol/pbs-plus/internal/syslog" "github.com/sonroyaalmerol/pbs-plus/internal/utils" @@ -25,27 +24,14 @@ func NewARPCFS(ctx context.Context, session *arpc.Session, hostname string, driv return &ARPCFS{ ctx: ctx, session: session, - drive: drive, - hostname: hostname, + Drive: drive, + Hostname: hostname, } } -func (f *ARPCFS) Mount(mountpoint string) error { - fsName := "agent://" + utils.Slugify(f.hostname) + "/" + f.drive - server, err := fuse.Mount(mountpoint, fsName, f, nil) - if err != nil { - return err - } - - f.mount = server - - f.mount.WaitMount() - return nil -} - func (f *ARPCFS) Unmount() { - if f.mount != nil { - _ = f.mount.Unmount() + if f.Mount != nil { + _ = f.Mount.Unmount() } } @@ -76,7 +62,7 @@ func (fs *ARPCFS) OpenFile(filename string, flag int, perm os.FileMode) (billy.F ctx, cancel := TimeoutCtx() defer cancel() - err := fs.session.CallJSON(ctx, fs.drive+"/OpenFile", OpenRequest{ + err := fs.session.CallJSON(ctx, fs.Drive+"/OpenFile", OpenRequest{ Path: filename, Flag: flag, Perm: int(perm), @@ -93,7 +79,7 @@ func (fs *ARPCFS) OpenFile(filename string, flag int, perm os.FileMode) (billy.F fs: fs, name: filename, handleID: resp.HandleID, - drive: fs.drive, + drive: fs.Drive, }, nil } @@ -107,7 +93,7 @@ func (fs *ARPCFS) Stat(filename string) (os.FileInfo, error) { ctx, cancel := TimeoutCtx() defer cancel() - err := fs.session.CallJSON(ctx, fs.drive+"/Stat", struct { + err := fs.session.CallJSON(ctx, fs.Drive+"/Stat", struct { Path string `json:"path"` }{ Path: filename, @@ -143,7 +129,7 @@ func (fs *ARPCFS) StatFS() (types.StatFS, error) { ctx, cancel := TimeoutCtx() defer cancel() - err := fs.session.CallJSON(ctx, fs.drive+"/FSstat", struct{}{}, &fsStat) + err := fs.session.CallJSON(ctx, fs.Drive+"/FSstat", struct{}{}, &fsStat) if err != nil { syslog.L.Errorf("StatFS RPC failed: %v", err) return types.StatFS{}, os.ErrInvalid @@ -170,7 +156,7 @@ func (fs *ARPCFS) ReadDir(path string) ([]os.FileInfo, error) { ctx, cancel := TimeoutCtx() defer cancel() - err := fs.session.CallJSON(ctx, fs.drive+"/ReadDir", struct { + err := fs.session.CallJSON(ctx, fs.Drive+"/ReadDir", struct { Path string `json:"path"` }{ Path: path, @@ -227,7 +213,7 @@ func (fs *ARPCFS) Join(elem ...string) string { } func (fs *ARPCFS) Chroot(path string) (billy.Filesystem, error) { - return NewARPCFS(fs.ctx, fs.session, fs.hostname, fs.drive), nil + return NewARPCFS(fs.ctx, fs.session, fs.Hostname, fs.Drive), nil } func (fs *ARPCFS) Root() string { diff --git a/internal/backend/arpc/fuse/fuse.go b/internal/backend/arpc/fuse/fuse.go index a3578e4b..bab9124d 100644 --- a/internal/backend/arpc/fuse/fuse.go +++ b/internal/backend/arpc/fuse/fuse.go @@ -13,32 +13,18 @@ import ( "github.com/go-git/go-billy/v5" "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" - "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc/types" - "github.com/sonroyaalmerol/pbs-plus/internal/syslog" + arpcfs "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc" ) -type StatFSer interface { - StatFS() (types.StatFS, error) -} - -// CallHook is the callback called before every FUSE operation -type CallHook func(ctx context.Context) error - -func newRoot(underlying billy.Basic, callHook CallHook) fs.InodeEmbedder { - if callHook == nil { - callHook = func(ctx context.Context) error { - return nil - } - } - return &BillyRoot{ - underlying: underlying, - callHook: callHook, +func newRoot(fs *arpcfs.ARPCFS) fs.InodeEmbedder { + return &BillyNode{ + fs: fs, } } // Mount mounts the billy filesystem at the specified mountpoint -func Mount(mountpoint string, fsName string, underlying billy.Basic, callHook CallHook) (*fuse.Server, error) { - root := newRoot(underlying, callHook) +func Mount(mountpoint string, fsName string, afs *arpcfs.ARPCFS) (*fuse.Server, error) { + root := newRoot(afs) timeout := time.Second @@ -61,229 +47,10 @@ func Mount(mountpoint string, fsName string, underlying billy.Basic, callHook Ca return server, nil } -// BillyRoot is the root node of the filesystem -type BillyRoot struct { - fs.Inode - underlying billy.Basic - callHook CallHook -} - -var _ = (fs.NodeGetattrer)((*BillyRoot)(nil)) -var _ = (fs.NodeLookuper)((*BillyRoot)(nil)) -var _ = (fs.NodeReaddirer)((*BillyRoot)(nil)) -var _ = (fs.NodeOpener)((*BillyRoot)(nil)) -var _ = (fs.NodeStatfser)((*BillyRoot)(nil)) -var _ = (fs.NodeAccesser)((*BillyRoot)(nil)) -var _ = (fs.NodeOpendirHandler)((*BillyRoot)(nil)) -var _ = (fs.NodeStatxer)((*BillyRoot)(nil)) - -func (r *BillyRoot) Access(ctx context.Context, mask uint32) syscall.Errno { - if err := r.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - - // For read-only filesystem, deny write access (bit 1) - if mask&2 != 0 { // 2 = write bit (traditional W_OK) - return syscall.EROFS - } - - return 0 -} - -func (r *BillyRoot) OpendirHandle(ctx context.Context, flags uint32) (fs.FileHandle, uint32, syscall.Errno) { - if err := r.callHook(ctx); err != nil { - return nil, 0, fs.ToErrno(err) - } - - return &BillyDirHandle{ - root: r, - path: "", - }, fuse.FOPEN_CACHE_DIR, 0 -} - -func (r *BillyRoot) Statx(ctx context.Context, f fs.FileHandle, flags uint32, mask uint32, out *fuse.StatxOut) syscall.Errno { - if err := r.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - - // Get file stats the regular way, then populate StatxOut - var attrOut fuse.AttrOut - errno := r.Getattr(ctx, f, &attrOut) - if errno != 0 { - return errno - } - - // Use actual STATX mask values - const ( - STATX_TYPE = 0x00000001 // Want stx_mode & S_IFMT - STATX_MODE = 0x00000002 // Want stx_mode & ~S_IFMT - STATX_NLINK = 0x00000004 // Want stx_nlink - STATX_SIZE = 0x00000200 // Want stx_size - STATX_MTIME = 0x00000020 // Want stx_mtime - ) - - // Set basic attributes - out.Mask = STATX_TYPE | STATX_MODE | STATX_NLINK | STATX_SIZE - out.Mode = uint16(attrOut.Mode) - out.Size = attrOut.Size - out.Nlink = attrOut.Nlink - - // Add timestamps if requested - if mask&STATX_MTIME != 0 { - out.Mask |= STATX_MTIME - out.Mtime.Sec = attrOut.Mtime - out.Mtime.Nsec = attrOut.Mtimensec - } - - return 0 -} - -// Getattr implements NodeGetattrer -func (r *BillyRoot) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno { - if err := r.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - - fi, err := r.underlying.Stat("") - if err != nil { - return fs.ToErrno(err) - } - - out.Mode = uint32(fi.Mode()) | syscall.S_IFDIR - out.Size = uint64(fi.Size()) - mtime := fi.ModTime() - out.SetTimes(nil, &mtime, nil) - - return 0 -} - -// Lookup implements NodeLookuper -func (r *BillyRoot) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - if err := r.callHook(ctx); err != nil { - return nil, fs.ToErrno(err) - } - - childPath := name - fi, err := r.underlying.Stat(childPath) - if err != nil { - return nil, fs.ToErrno(err) - } - - node := &BillyNode{ - root: r, - path: childPath, - } - - mode := uint32(fi.Mode().Perm()) - if fi.IsDir() { - mode |= syscall.S_IFDIR - } else if fi.Mode()&os.ModeSymlink != 0 { - mode |= syscall.S_IFLNK - } else { - mode |= syscall.S_IFREG - } - - stable := fs.StableAttr{ - Mode: mode, - } - - child := r.NewInode(ctx, node, stable) - - out.Mode = mode - out.Size = uint64(fi.Size()) - mtime := fi.ModTime() - out.SetTimes(nil, &mtime, nil) - - return child, 0 -} - -// Readdir implements NodeReaddirer -func (r *BillyRoot) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { - if err := r.callHook(ctx); err != nil { - return nil, fs.ToErrno(err) - } - - if dfs, ok := r.underlying.(billy.Dir); ok { - entries, err := dfs.ReadDir("") - if err != nil { - return nil, fs.ToErrno(err) - } - - result := make([]fuse.DirEntry, 0, len(entries)) - for _, e := range entries { - entryType := uint32(0) // DT_Unknown - if e.IsDir() { - entryType = syscall.DT_DIR - } else if e.Mode()&os.ModeSymlink != 0 { - entryType = syscall.DT_LNK - } else { - entryType = syscall.DT_REG - } - - result = append(result, fuse.DirEntry{ - Name: e.Name(), - Mode: entryType << 12, // Convert to type bits - }) - } - - return fs.NewListDirStream(result), 0 - } - - return nil, syscall.ENOSYS -} - -// Open implements NodeOpener -func (r *BillyRoot) Open(ctx context.Context, flags uint32) (fs.FileHandle, uint32, syscall.Errno) { - if err := r.callHook(ctx); err != nil { - return nil, 0, fs.ToErrno(err) - } - - return &BillyDirHandle{ - root: r, - path: "", - }, 0, 0 -} - -func (r *BillyRoot) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { - if err := r.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - - // Try to use StatFSer interface if available - if statfser, ok := r.underlying.(StatFSer); ok { - stats, err := statfser.StatFS() - if err == nil { - out.Blocks = stats.Blocks - out.Bfree = stats.Bfree - out.Bavail = stats.Bavail - out.Files = stats.Files - out.Ffree = stats.Ffree - out.Bsize = uint32(stats.Bsize) - out.NameLen = uint32(stats.NameLen) - out.Frsize = uint32(stats.Bsize) - return 0 - } - // Fall through to defaults if error occurs - syslog.L.Warnf("Failed to get StatFS info: %v", err) - } - - // Fallback to reasonable defaults for a read-only filesystem - out.Blocks = 1000000 // Just a reasonable number - out.Bfree = 0 // No free blocks (read-only) - out.Bavail = 0 // No available blocks (read-only) - out.Files = 1000 // Reasonable number of inodes - out.Ffree = 0 // No free inodes (read-only) - out.Bsize = 4096 // Standard block size - out.NameLen = 255 // Standard name length - out.Frsize = 4096 // Fragment size - - return 0 -} - // BillyNode represents a file or directory in the filesystem type BillyNode struct { fs.Inode - root *BillyRoot + fs *arpcfs.ARPCFS path string } @@ -294,22 +61,18 @@ var _ = (fs.NodeOpener)((*BillyNode)(nil)) var _ = (fs.NodeReadlinker)((*BillyNode)(nil)) var _ = (fs.NodeStatfser)((*BillyNode)(nil)) var _ = (fs.NodeAccesser)((*BillyNode)(nil)) -var _ = (fs.NodeOpendirHandler)((*BillyNode)(nil)) +var _ = (fs.NodeOpendirer)((*BillyNode)(nil)) var _ = (fs.NodeReleaser)((*BillyNode)(nil)) var _ = (fs.NodeStatxer)((*BillyNode)(nil)) func (n *BillyNode) Access(ctx context.Context, mask uint32) syscall.Errno { - if err := n.root.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - // For read-only filesystem, deny write access (bit 1) if mask&2 != 0 { // 2 = write bit (traditional W_OK) return syscall.EROFS } // Check if the file exists (that's sufficient for read-only fs) - _, err := n.root.underlying.Stat(n.path) + _, err := n.fs.Stat(n.path) if err != nil { return fs.ToErrno(err) } @@ -317,23 +80,20 @@ func (n *BillyNode) Access(ctx context.Context, mask uint32) syscall.Errno { return 0 } -func (n *BillyNode) OpendirHandle(ctx context.Context, flags uint32) (fs.FileHandle, uint32, syscall.Errno) { - if err := n.root.callHook(ctx); err != nil { - return nil, 0, fs.ToErrno(err) +func (n *BillyNode) Opendir(ctx context.Context) syscall.Errno { + info, err := n.fs.Stat(n.path) + if err != nil { + return fs.ToErrno(err) + } + + if !info.IsDir() { + return syscall.ENOTDIR } - // Return the directory handle with potential caching hint - return &BillyDirHandle{ - root: n.root, - path: n.path, - }, fuse.FOPEN_CACHE_DIR, 0 // Enable directory caching for better performance + return 0 } func (n *BillyNode) Release(ctx context.Context, f fs.FileHandle) syscall.Errno { - if err := n.root.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - if fh, ok := f.(fs.FileReleaser); ok { return fh.Release(ctx) } @@ -342,10 +102,6 @@ func (n *BillyNode) Release(ctx context.Context, f fs.FileHandle) syscall.Errno } func (n *BillyNode) Statx(ctx context.Context, f fs.FileHandle, flags uint32, mask uint32, out *fuse.StatxOut) syscall.Errno { - if err := n.root.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - // Get file stats the regular way, then populate StatxOut var attrOut fuse.AttrOut errno := n.Getattr(ctx, f, &attrOut) @@ -381,11 +137,7 @@ func (n *BillyNode) Statx(ctx context.Context, f fs.FileHandle, flags uint32, ma // Getattr implements NodeGetattrer func (n *BillyNode) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno { - if err := n.root.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - - fi, err := n.root.underlying.Stat(n.path) + fi, err := n.fs.Stat(n.path) if err != nil { return fs.ToErrno(err) } @@ -409,18 +161,14 @@ func (n *BillyNode) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.Att // Lookup implements NodeLookuper func (n *BillyNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - if err := n.root.callHook(ctx); err != nil { - return nil, fs.ToErrno(err) - } - childPath := filepath.Join(n.path, name) - fi, err := n.root.underlying.Stat(childPath) + fi, err := n.fs.Stat(childPath) if err != nil { return nil, fs.ToErrno(err) } childNode := &BillyNode{ - root: n.root, + fs: n.fs, path: childPath, } @@ -449,87 +197,74 @@ func (n *BillyNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) // Readdir implements NodeReaddirer func (n *BillyNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { - if err := n.root.callHook(ctx); err != nil { + entries, err := n.fs.ReadDir(n.path) + if err != nil { return nil, fs.ToErrno(err) } - if dfs, ok := n.root.underlying.(billy.Dir); ok { - entries, err := dfs.ReadDir(n.path) - if err != nil { - return nil, fs.ToErrno(err) + result := make([]fuse.DirEntry, 0, len(entries)) + for _, e := range entries { + entryType := uint32(0) // DT_Unknown + if e.IsDir() { + entryType = syscall.DT_DIR + } else if e.Mode()&os.ModeSymlink != 0 { + entryType = syscall.DT_LNK + } else { + entryType = syscall.DT_REG } - result := make([]fuse.DirEntry, 0, len(entries)) - for _, e := range entries { - entryType := uint32(0) // DT_Unknown - if e.IsDir() { - entryType = syscall.DT_DIR - } else if e.Mode()&os.ModeSymlink != 0 { - entryType = syscall.DT_LNK - } else { - entryType = syscall.DT_REG - } - - result = append(result, fuse.DirEntry{ - Name: e.Name(), - Mode: entryType << 12, // Convert to type bits - }) - } - - return fs.NewListDirStream(result), 0 + result = append(result, fuse.DirEntry{ + Name: e.Name(), + Mode: entryType << 12, // Convert to type bits + }) } - return nil, syscall.ENOSYS + return fs.NewListDirStream(result), 0 } // Open implements NodeOpener func (n *BillyNode) Open(ctx context.Context, flags uint32) (fs.FileHandle, uint32, syscall.Errno) { - if err := n.root.callHook(ctx); err != nil { - return nil, 0, fs.ToErrno(err) - } - - if n.IsDir() { - return &BillyDirHandle{ - root: n.root, - path: n.path, - }, 0, 0 - } - - file, err := n.root.underlying.OpenFile(n.path, int(flags), 0) + file, err := n.fs.OpenFile(n.path, int(flags), 0) if err != nil { return nil, 0, fs.ToErrno(err) } return &BillyFileHandle{ - root: n.root, + fs: n.fs, file: file, }, 0, 0 } // Readlink implements NodeReadlinker func (n *BillyNode) Readlink(ctx context.Context) ([]byte, syscall.Errno) { - if err := n.root.callHook(ctx); err != nil { + target, err := n.fs.Readlink(n.path) + if err != nil { return nil, fs.ToErrno(err) } + return []byte(target), 0 +} - if sfs, ok := n.root.underlying.(billy.Symlink); ok { - target, err := sfs.Readlink(n.path) - if err != nil { - return nil, fs.ToErrno(err) - } - return []byte(target), 0 +func (n *BillyNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { + stat, err := n.fs.StatFS() + if err != nil { + return fs.ToErrno(err) } - return nil, syscall.ENOSYS -} + out.Blocks = stat.Blocks + out.Bfree = stat.Bfree + out.Bavail = stat.Bavail + out.Files = stat.Files + out.Ffree = stat.Ffree + out.Bsize = uint32(stat.Bsize) + out.NameLen = uint32(stat.NameLen) + out.Frsize = uint32(stat.Bsize) -func (n *BillyNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { - return n.root.Statfs(ctx, out) + return 0 } // BillyFileHandle handles file operations type BillyFileHandle struct { - root *BillyRoot + fs *arpcfs.ARPCFS file billy.File } @@ -538,10 +273,6 @@ var _ = (fs.FileReleaser)((*BillyFileHandle)(nil)) // Read implements FileReader func (fh *BillyFileHandle) Read(ctx context.Context, dest []byte, offset int64) (fuse.ReadResult, syscall.Errno) { - if err := fh.root.callHook(ctx); err != nil { - return nil, fs.ToErrno(err) - } - n, err := fh.file.ReadAt(dest, offset) if err != nil && err != io.EOF { return nil, fs.ToErrno(err) @@ -552,16 +283,6 @@ func (fh *BillyFileHandle) Read(ctx context.Context, dest []byte, offset int64) // Release implements FileReleaser func (fh *BillyFileHandle) Release(ctx context.Context) syscall.Errno { - if err := fh.root.callHook(ctx); err != nil { - return fs.ToErrno(err) - } - err := fh.file.Close() return fs.ToErrno(err) } - -// BillyDirHandle handles directory operations -type BillyDirHandle struct { - root *BillyRoot - path string -} diff --git a/internal/backend/arpc/fuse/helpers.go b/internal/backend/arpc/fuse/helpers.go new file mode 100644 index 00000000..9ecf45a0 --- /dev/null +++ b/internal/backend/arpc/fuse/helpers.go @@ -0,0 +1,22 @@ +package fuse + +import ( + "os" + + "github.com/hanwen/go-fuse/v2/fuse" +) + +func getMode(node os.FileInfo) uint32 { + vfsMode := node.Mode() + Mode := vfsMode.Perm() + if vfsMode&os.ModeDir != 0 { + Mode |= fuse.S_IFDIR + } else if vfsMode&os.ModeSymlink != 0 { + Mode |= fuse.S_IFLNK + } else if vfsMode&os.ModeNamedPipe != 0 { + Mode |= fuse.S_IFIFO + } else { + Mode |= fuse.S_IFREG + } + return uint32(Mode) +} diff --git a/internal/backend/arpc/mount/mount.go b/internal/backend/arpc/mount/mount.go new file mode 100644 index 00000000..7cc2b281 --- /dev/null +++ b/internal/backend/arpc/mount/mount.go @@ -0,0 +1,20 @@ +package mount + +import ( + arpcfs "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc" + "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc/fuse" + "github.com/sonroyaalmerol/pbs-plus/internal/utils" +) + +func Mount(f *arpcfs.ARPCFS, mountpoint string) error { + fsName := "agent://" + utils.Slugify(f.Hostname) + "/" + f.Drive + server, err := fuse.Mount(mountpoint, fsName, f) + if err != nil { + return err + } + + f.Mount = server + + f.Mount.WaitMount() + return nil +} diff --git a/internal/backend/arpc/types.go b/internal/backend/arpc/types.go index 5abbd640..b0123f54 100644 --- a/internal/backend/arpc/types.go +++ b/internal/backend/arpc/types.go @@ -12,9 +12,9 @@ import ( type ARPCFS struct { ctx context.Context session *arpc.Session - drive string - hostname string - mount *gofuse.Server + Drive string + Hostname string + Mount *gofuse.Server } // ARPCFile implements billy.File for remote files diff --git a/internal/proxy/controllers/plus/plus.go b/internal/proxy/controllers/plus/plus.go index 6ca037c8..d92b746c 100644 --- a/internal/proxy/controllers/plus/plus.go +++ b/internal/proxy/controllers/plus/plus.go @@ -14,6 +14,7 @@ import ( "time" arpcfs "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc" + "github.com/sonroyaalmerol/pbs-plus/internal/backend/arpc/mount" "github.com/sonroyaalmerol/pbs-plus/internal/store" "github.com/sonroyaalmerol/pbs-plus/internal/store/constants" "github.com/sonroyaalmerol/pbs-plus/internal/syslog" @@ -56,7 +57,7 @@ func MountHandler(storeInstance *store.Store) http.HandlerFunc { mntPath := filepath.Join(constants.AgentMountBasePath, strings.ReplaceAll(targetName, " ", "-")) - err = arpcFS.Mount(mntPath) + err = mount.Mount(arpcFS, mntPath) if err != nil { syslog.L.Errorf("MountHandler: Failed to create fuse connection for target -> %v", err) http.Error(w, fmt.Sprintf("MountHandler: Failed to create fuse connection for target -> %v", err), http.StatusInternalServerError)