mount: Correctly return context.Canceled for interrupted syscalls

bazil/fuse expects us to return context.Canceled to signal that a
syscall was successfully interrupted. Returning a wrapped version of
that error however causes the fuse library to signal an EIO (input/output
error). Thus unwrap context.Canceled errors before returning them.
This commit is contained in:
Michael Eischer
2022-08-19 20:26:35 +02:00
parent f7808245aa
commit a0c1ae9f90
4 changed files with 27 additions and 5 deletions

View File

@@ -5,6 +5,7 @@ package fuse
import (
"context"
"errors"
"os"
"path/filepath"
"sync"
@@ -44,6 +45,16 @@ func newDir(ctx context.Context, root *Root, inode, parentInode uint64, node *re
}, nil
}
// returing a wrapped context.Canceled error will instead result in returing
// an input / output error to the user. Thus unwrap the error to match the
// expectations of bazil/fuse
func unwrapCtxCanceled(err error) error {
if errors.Is(err, context.Canceled) {
return context.Canceled
}
return err
}
// replaceSpecialNodes replaces nodes with name "." and "/" by their contents.
// Otherwise, the node is returned.
func replaceSpecialNodes(ctx context.Context, repo restic.Repository, node *restic.Node) ([]*restic.Node, error) {
@@ -57,7 +68,7 @@ func replaceSpecialNodes(ctx context.Context, repo restic.Repository, node *rest
tree, err := restic.LoadTree(ctx, repo, *node.Subtree)
if err != nil {
return nil, err
return nil, unwrapCtxCanceled(err)
}
return tree.Nodes, nil
@@ -91,7 +102,7 @@ func (d *dir) open(ctx context.Context) error {
tree, err := restic.LoadTree(ctx, d.root.repo, *d.node.Subtree)
if err != nil {
debug.Log(" error loading tree %v: %v", d.node.Subtree, err)
return err
return unwrapCtxCanceled(err)
}
items := make(map[string]*restic.Node)
for _, n := range tree.Nodes {