fuse: changed file read implementation to avoid OOM (#620)

Changed file read implementation from ReadAll() to a Handle to avoid OOMing

We don't have automated tests for this but I verified this by restoring
13GB file over fuse and memory usage never exceeded 400MB.
This commit is contained in:
Jarek Kowalski
2020-09-16 23:04:22 -07:00
committed by GitHub
parent f2cf71d914
commit 7cdb75ab79

View File

@@ -6,8 +6,10 @@
package fusemount
import (
"io"
"io/ioutil"
"os"
"sync"
"bazil.org/fuse"
fusefs "bazil.org/fuse/fs"
@@ -36,6 +38,51 @@ type fuseFileNode struct {
fuseNode
}
var _ fusefs.NodeOpener = (*fuseFileNode)(nil)
func (f *fuseFileNode) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fusefs.Handle, error) {
reader, err := f.entry.(fs.File).Open(ctx)
if err != nil {
return nil, err
}
return &fuseFileHandle{reader: reader, size: f.entry.Size()}, nil
}
type fuseFileHandle struct {
mu sync.Mutex
reader fs.Reader
size int64
}
func (f *fuseFileHandle) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
f.mu.Lock()
defer f.mu.Unlock()
_, err := f.reader.Seek(req.Offset, io.SeekStart)
if err != nil {
return err
}
n, err := f.reader.Read(resp.Data[:req.Size])
if err != nil {
return err
}
resp.Data = resp.Data[:n]
return nil
}
func (f *fuseFileHandle) Release(ctx context.Context, req *fuse.ReleaseRequest) error {
return f.reader.Close()
}
var (
_ fusefs.HandleReleaser = (*fuseFileHandle)(nil)
_ fusefs.HandleReader = (*fuseFileHandle)(nil)
)
func (f *fuseFileNode) ReadAll(ctx context.Context) ([]byte, error) {
reader, err := f.entry.(fs.File).Open(ctx)
if err != nil {