Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 41 additions & 90 deletions component/libfuse/libfuse2_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"io/fs"
"os"
"runtime"
"syscall"
"time"

"github.com/Seagate/cloudfuse/common"
Expand Down Expand Up @@ -286,14 +285,7 @@ func (cf *CgofuseFS) Getattr(path string, stat *fuse.Stat_t, fh uint64) int {
attr, err := fuseFS.NextComponent().GetAttr(internal.GetAttrOptions{Name: name})
if err != nil {
//log.Err("Libfuse::Getattr : Failed to get attributes of %s [%s]", name, err.Error())
switch err {
case syscall.ENOENT:
return -fuse.ENOENT
case syscall.EACCES:
return -fuse.EACCES
default:
return -fuse.EIO
}
return fuseErrnoFromError(err)
}

// Populate stat
Expand Down Expand Up @@ -372,13 +364,7 @@ func (cf *CgofuseFS) Mkdir(path string, mode uint32) int {
CreateDir(internal.CreateDirOptions{Name: name, Mode: fs.FileMode(mode)})
if err != nil {
log.Err("Libfuse::Mkdir : Failed to create %s [%s]", name, err.Error())
if os.IsPermission(err) {
return -fuse.EACCES
} else if os.IsExist(err) {
return -fuse.EEXIST
} else {
return -fuse.EIO
}
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(createDir, name, map[string]any{md: fs.FileMode(mode)})
Expand Down Expand Up @@ -546,12 +532,7 @@ func populateDirChildCache(
Token: cacheInfo.token,
})
if err != nil {
if os.IsNotExist(err) {
return -fuse.ENOENT
} else if os.IsPermission(err) {
return -fuse.EACCES
}
return -fuse.EIO
return fuseErrnoFromError(err)
}
// compile results and update cache
// let the cache grow to MaxDirListCount
Expand Down Expand Up @@ -608,11 +589,7 @@ func (cf *CgofuseFS) Rmdir(path string) int {
err := fuseFS.NextComponent().DeleteDir(internal.DeleteDirOptions{Name: name})
if err != nil {
log.Err("Libfuse::Rmdir : Failed to delete %s [%s]", name, err.Error())
if os.IsNotExist(err) {
return -fuse.ENOENT
}

return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(deleteDir, name, nil)
Expand All @@ -631,13 +608,7 @@ func (cf *CgofuseFS) Create(path string, flags int, mode uint32) (int, uint64) {
CreateFile(internal.CreateFileOptions{Name: name, Mode: fs.FileMode(mode)})
if err != nil {
log.Err("Libfuse::Create : Failed to create %s [%s]", name, err.Error())
if os.IsExist(err) {
return -fuse.EEXIST, 0
} else if os.IsPermission(err) {
return -fuse.EACCES, 0
}

return -fuse.EIO, 0
return fuseErrnoFromError(err), 0
}

fh := handlemap.Add(handle)
Expand Down Expand Up @@ -676,13 +647,7 @@ func (cf *CgofuseFS) Open(path string, flags int) (int, uint64) {

if err != nil {
log.Err("Libfuse::Open : Failed to open %s [%s]", name, err.Error())
if os.IsNotExist(err) {
return -fuse.ENOENT, 0
} else if os.IsPermission(err) {
return -fuse.EACCES, 0
}

return -fuse.EIO, 0
return fuseErrnoFromError(err), 0
}

fh := handlemap.Add(handle)
Expand Down Expand Up @@ -733,23 +698,31 @@ func (cf *CgofuseFS) Read(path string, buff []byte, ofst int64, fh uint64) int {
err = nil
}
if err != nil {
if isAccessDeniedFuseErr(err) {
return -fuse.EACCES
}
log.Err(
"Libfuse::Read : error reading file %s, handle: %d [%s]",
handle.Path,
handle.ID,
err.Error(),
)
return -fuse.EIO
return fuseErrnoFromError(err)
}

return bytesRead
}

func isAccessDeniedFuseErr(err error) bool {
return os.IsPermission(err) || errors.Is(err, syscall.EACCES) || errors.Is(err, syscall.EPERM)
func fuseErrnoFromError(err error) int {
switch {
case err == nil:
return 0
case errors.Is(err, fs.ErrNotExist):
return -fuse.ENOENT
case errors.Is(err, fs.ErrPermission):
return -fuse.EACCES
case errors.Is(err, fs.ErrExist):
return -fuse.EEXIST
default:
return -fuse.EIO
}
}

// Write writes data to a file from the buffer with the given offset.
Expand Down Expand Up @@ -778,7 +751,7 @@ func (cf *CgofuseFS) Write(path string, buff []byte, ofst int64, fh uint64) int
handle.ID,
err.Error(),
)
return -fuse.EIO
return fuseErrnoFromError(err)
}

return bytesWritten
Expand Down Expand Up @@ -813,14 +786,7 @@ func (cf *CgofuseFS) Flush(path string, fh uint64) int {
handle.ID,
err.Error(),
)
switch err {
case syscall.ENOENT:
return -fuse.ENOENT
case syscall.EACCES:
return -fuse.EACCES
default:
return -fuse.EIO
}
return fuseErrnoFromError(err)
}

return 0
Expand All @@ -843,10 +809,7 @@ func (cf *CgofuseFS) Truncate(path string, size int64, fh uint64) int {
})
if err != nil {
log.Err("Libfuse::Truncate : error truncating file %s [%s]", name, err.Error())
if os.IsNotExist(err) {
return -fuse.ENOENT
}
return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(truncateFile, name, map[string]any{"size": size})
Expand All @@ -873,14 +836,7 @@ func (cf *CgofuseFS) Release(path string, fh uint64) int {
handle.ID,
err.Error(),
)
switch err {
case syscall.ENOENT:
return -fuse.ENOENT
case syscall.EACCES:
return -fuse.EACCES
default:
return -fuse.EIO
}
return fuseErrnoFromError(err)
}

handlemap.Delete(handle.ID)
Expand All @@ -900,12 +856,7 @@ func (cf *CgofuseFS) Unlink(path string) int {
err := fuseFS.NextComponent().DeleteFile(internal.DeleteFileOptions{Name: name})
if err != nil {
log.Err("Libfuse::Unlink : error deleting file %s [%s]", name, err.Error())
if os.IsNotExist(err) {
return -fuse.ENOENT
} else if os.IsPermission(err) {
return -fuse.EACCES
}
return -fuse.EIO
return fuseErrnoFromError(err)

}

Expand Down Expand Up @@ -935,13 +886,17 @@ func (cf *CgofuseFS) Rename(oldpath string, newpath string) int {
}

srcAttr, srcErr := fuseFS.NextComponent().GetAttr(internal.GetAttrOptions{Name: srcPath})
if os.IsNotExist(srcErr) {
if srcErr != nil {
log.Err("Libfuse::Rename : Failed to get attributes of %s [%s]", srcPath, srcErr.Error())
return -fuse.ENOENT
return fuseErrnoFromError(srcErr)
}

if srcAttr.IsDir() {
dstAttr, dstErr := fuseFS.NextComponent().GetAttr(internal.GetAttrOptions{Name: dstPath})
if errors.Is(dstErr, fs.ErrPermission) {
log.Err("Libfuse::Rename : access denied for %s [%s]", dstPath, dstErr.Error())
return -fuse.EACCES
}

// ENOTDIR
if dstErr == nil && !dstAttr.IsDir() {
Expand Down Expand Up @@ -970,7 +925,7 @@ func (cf *CgofuseFS) Rename(oldpath string, newpath string) int {
dstPath,
err.Error(),
)
return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(
Expand Down Expand Up @@ -1006,6 +961,10 @@ func (cf *CgofuseFS) Rename(oldpath string, newpath string) int {
dstPath,
err.Error(),
)

if errors.Is(err, fs.ErrPermission) || errors.Is(dstErr, fs.ErrPermission) {
return -fuse.EACCES
}
return -fuse.EIO
}

Expand Down Expand Up @@ -1037,7 +996,7 @@ func (cf *CgofuseFS) Symlink(target string, newpath string) int {
targetPath,
err.Error(),
)
return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(createLink, name, map[string]any{trgt: targetPath})
Expand All @@ -1062,10 +1021,7 @@ func (cf *CgofuseFS) Readlink(path string) (int, string) {
ReadLink(internal.ReadLinkOptions{Name: name, Size: linkSize})
if err != nil {
log.Err("Libfuse::Readlink : error reading link file %s [%s]", name, err.Error())
if os.IsNotExist(err) {
return -fuse.ENOENT, targetPath
}
return -fuse.EIO, targetPath
return fuseErrnoFromError(err), targetPath
}

// Don't think we need when with using cgofuse
Expand Down Expand Up @@ -1100,7 +1056,7 @@ func (cf *CgofuseFS) Fsync(path string, datasync bool, fh uint64) int {
err := fuseFS.NextComponent().SyncFile(options)
if err != nil {
log.Err("Libfuse::Fsync : error syncing file %s [%s]", handle.Path, err.Error())
return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(syncFile, handle.Path, nil)
Expand All @@ -1122,7 +1078,7 @@ func (cf *CgofuseFS) Fsyncdir(path string, datasync bool, fh uint64) int {
err := fuseFS.NextComponent().SyncDir(options)
if err != nil {
log.Err("Libfuse::Fsyncdir : error syncing dir %s [%s]", name, err.Error())
return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(syncDir, name, nil)
Expand All @@ -1144,12 +1100,7 @@ func (cf *CgofuseFS) Chmod(path string, mode uint32) int {
})
if err != nil {
log.Err("Libfuse::Chmod : error in chmod of %s [%s]", name, err.Error())
if os.IsNotExist(err) {
return -fuse.ENOENT
} else if os.IsPermission(err) {
return -fuse.EACCES
}
return -fuse.EIO
return fuseErrnoFromError(err)
}

libfuseStatsCollector.PushEvents(chmod, name, map[string]any{md: fs.FileMode(mode)})
Expand Down
Loading
Loading