diff --git a/cmd/restic/cmd_mount.go b/cmd/restic/cmd_mount.go index dcc4b19a5..033c98850 100644 --- a/cmd/restic/cmd_mount.go +++ b/cmd/restic/cmd_mount.go @@ -275,9 +275,7 @@ type file struct { node *restic.Node sizes []uint32 - - // cleartext contents - clearContent [][]byte + blobs [][]byte } func newFile(repo *repository.Repository, node *restic.Node) (*file, error) { @@ -291,10 +289,10 @@ func newFile(repo *repository.Repository, node *restic.Node) (*file, error) { } return &file{ - repo: repo, - node: node, - sizes: sizes, - clearContent: make([][]byte, len(node.Content)), + repo: repo, + node: node, + sizes: sizes, + blobs: make([][]byte, len(node.Content)), }, nil } @@ -305,37 +303,46 @@ func (f *file) Attr(ctx context.Context, a *fuse.Attr) error { return nil } +func (f *file) getBlobAt(i int) (blob []byte, err error) { + if f.blobs[i] != nil { + blob = f.blobs[i] + } else { + blob, err = f.repo.LoadBlob(pack.Data, f.node.Content[i]) + if err != nil { + return nil, err + } + f.blobs[i] = blob + } + + return blob, nil +} + func (f *file) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { off := req.Offset + + // Skip blobs before the offset + startContent := 0 + for off > int64(f.sizes[startContent]) { + off -= int64(f.sizes[startContent]) + startContent++ + } + content := make([]byte, req.Size) allContent := content - - for i := range f.node.Content { - if off >= int64(f.sizes[i]) { - off -= int64(f.sizes[i]) - continue + for i := startContent; i < len(f.sizes); i++ { + blob, err := f.getBlobAt(i) + if err != nil { + return err } - var subContent []byte - if f.clearContent[i] != nil { - subContent = f.clearContent[i] - } else { - var err error - subContent, err = f.repo.LoadBlob(pack.Data, f.node.Content[i]) - if err != nil { - return err - } - f.clearContent[i] = subContent - } - - subContent = subContent[off:] + blob = blob[off:] off = 0 var copied int - if len(subContent) > len(content) { - copied = copy(content[0:], subContent[:len(content)]) + if len(blob) > len(content) { + copied = copy(content[0:], blob[:len(content)]) } else { - copied = copy(content[0:], subContent) + copied = copy(content[0:], blob) } content = content[copied:] if len(content) == 0 {