fuse: forget fs.Node instances on request by the kernel

Forget fs.Node instances once the kernel frees the corresponding nodeId.
This ensures that restic does not run out of memory on large snapshots.
This commit is contained in:
Michael Eischer
2024-09-09 22:37:51 +02:00
parent e9940f39dc
commit 51173c5003
8 changed files with 86 additions and 39 deletions

View File

@@ -12,18 +12,20 @@ import (
)
// Statically ensure that *link implements the given interface
var _ = fs.NodeForgetter(&link{})
var _ = fs.NodeGetxattrer(&link{})
var _ = fs.NodeListxattrer(&link{})
var _ = fs.NodeReadlinker(&link{})
type link struct {
root *Root
node *restic.Node
inode uint64
root *Root
forget forgetFn
node *restic.Node
inode uint64
}
func newLink(root *Root, inode uint64, node *restic.Node) (*link, error) {
return &link{root: root, inode: inode, node: node}, nil
func newLink(root *Root, forget forgetFn, inode uint64, node *restic.Node) (*link, error) {
return &link{root: root, forget: forget, inode: inode, node: node}, nil
}
func (l *link) Readlink(_ context.Context, _ *fuse.ReadlinkRequest) (string, error) {
@@ -57,3 +59,7 @@ func (l *link) Listxattr(_ context.Context, req *fuse.ListxattrRequest, resp *fu
func (l *link) Getxattr(_ context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
return nodeGetXattr(l.node, req, resp)
}
func (l *link) Forget() {
l.forget()
}