Skip to content

Commit

Permalink
cgofuse: don't inline lookup tables / alloc once
Browse files Browse the repository at this point in the history
Truthfully, I didn't benchmark this or look at the assembly.
But I remember this pattern being a concern in the past.

Unless the compiler has changed to optimize this out, things like the
map literal would be initialized each call.
Now we should do that only once on init.

Metrics would be nice to see on this though.
Does the compiler actually still act that way, and does the stack
climbing cost us more than doing that anyway?
Should these be lazy and initialized on the first call rather than at
init time?
  • Loading branch information
djdv committed Nov 26, 2022
1 parent a76856d commit fa0f090
Showing 1 changed file with 34 additions and 28 deletions.
62 changes: 34 additions & 28 deletions internal/filesystem/cgofuse/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,8 @@ func goToFuseFileType(m fs.FileMode) fileType {
}

// TODO: better names
func goToFusePermissions(m fs.FileMode) filePermissions {
var (
goPermissions = m.Perm()
fusePermissions filePermissions
)
for _, bit := range []struct {
var (
goToFusePermissionsTable = [...]struct {
golang fs.FileMode
fuse filePermissions
}{
Expand All @@ -100,7 +96,36 @@ func goToFusePermissions(m fs.FileMode) filePermissions {
{golang: filesystem.ExecuteUser, fuse: executeUser},
{golang: filesystem.WriteUser, fuse: writeUser},
{golang: filesystem.ReadUser, fuse: readUser},
} {
}
goFlagsFromFuseTable = [...]struct {
fuse, golang int
}{
{fuse: fuse.O_APPEND, golang: os.O_APPEND},
{fuse: fuse.O_CREAT, golang: os.O_CREATE},
{fuse: fuse.O_EXCL, golang: os.O_EXCL},
{fuse: fuse.O_TRUNC, golang: os.O_TRUNC},
}
fsErrorsTable = map[fserrors.Kind]errNo{
fserrors.Other: -fuse.EIO,
fserrors.InvalidItem: -fuse.EINVAL,
fserrors.InvalidOperation: -fuse.ENOSYS,
fserrors.Permission: -fuse.EACCES,
fserrors.IO: -fuse.EIO,
fserrors.Exist: -fuse.EEXIST,
fserrors.NotExist: -fuse.ENOENT,
fserrors.IsDir: -fuse.EISDIR,
fserrors.NotDir: -fuse.ENOTDIR,
fserrors.NotEmpty: -fuse.ENOTEMPTY,
}
)

// TODO: better names
func goToFusePermissions(m fs.FileMode) filePermissions {
var (
goPermissions = m.Perm()
fusePermissions filePermissions
)
for _, bit := range goToFusePermissionsTable {
if goPermissions&bit.golang != 0 {
fusePermissions |= bit.fuse
}
Expand All @@ -119,14 +144,7 @@ func goFlagsFromFuse(fuseFlags int) int {
case fuse.O_RDWR:
goFlags = os.O_RDWR
}
for _, bit := range []struct {
fuse, golang int
}{
{fuse: fuse.O_APPEND, golang: os.O_APPEND},
{fuse: fuse.O_CREAT, golang: os.O_CREATE},
{fuse: fuse.O_EXCL, golang: os.O_EXCL},
{fuse: fuse.O_TRUNC, golang: os.O_TRUNC},
} {
for _, bit := range goFlagsFromFuseTable {
if fuseFlags&bit.fuse != 0 {
goFlags |= bit.golang
}
Expand All @@ -138,19 +156,7 @@ func goFlagsFromFuse(fuseFlags int) int {
func interpretError(err error) errNo {
var fsErr *fserrors.Error
if errors.As(err, &fsErr) {
// Translation table for interface.Error -> FUSE error
return map[fserrors.Kind]errNo{
fserrors.Other: -fuse.EIO,
fserrors.InvalidItem: -fuse.EINVAL,
fserrors.InvalidOperation: -fuse.ENOSYS,
fserrors.Permission: -fuse.EACCES,
fserrors.IO: -fuse.EIO,
fserrors.Exist: -fuse.EEXIST,
fserrors.NotExist: -fuse.ENOENT,
fserrors.IsDir: -fuse.EISDIR,
fserrors.NotDir: -fuse.ENOTDIR,
fserrors.NotEmpty: -fuse.ENOTEMPTY,
}[fsErr.Kind]
return fsErrorsTable[fsErr.Kind]
}
panic(fmt.Sprintf("provided error is not translatable to POSIX error %#v", err))
}

0 comments on commit fa0f090

Please sign in to comment.