Fix FUSE reads for unknown attachment sizes
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"bazil.org/fuse"
|
||||
"bazil.org/fuse/fs"
|
||||
"bazil.org/fuse/fuseutil"
|
||||
)
|
||||
|
||||
type docspellFS struct {
|
||||
@@ -27,6 +28,7 @@ type fileNode struct {
|
||||
name string
|
||||
attachmentID string
|
||||
size uint64
|
||||
knownSize bool
|
||||
modTime time.Time
|
||||
client *DocspellClient
|
||||
data []byte
|
||||
@@ -100,7 +102,7 @@ func buildMountTree(client *DocspellClient, items []SearchItem) *dirNode {
|
||||
name = fmt.Sprintf("%s - %02d - %s", base, i+1, name)
|
||||
}
|
||||
name = uniqueName(dir.children, name)
|
||||
dir.children[name] = &fileNode{name: name, attachmentID: att.ID, size: uint64(att.Size), modTime: modTime, client: client}
|
||||
dir.children[name] = &fileNode{name: name, attachmentID: att.ID, size: uint64(att.Size), knownSize: att.Size > 0, modTime: modTime, client: client}
|
||||
}
|
||||
}
|
||||
return root
|
||||
@@ -179,13 +181,28 @@ func (d *dirNode) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||
|
||||
func (f *fileNode) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||
a.Mode = 0444
|
||||
if f.knownSize {
|
||||
a.Size = f.size
|
||||
}
|
||||
a.Mtime = f.modTime
|
||||
a.Ctime = f.modTime
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fileNode) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||
data, err := f.load(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fuseutil.HandleRead(req, resp, data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fileNode) ReadAll(ctx context.Context) ([]byte, error) {
|
||||
return f.load(ctx)
|
||||
}
|
||||
|
||||
func (f *fileNode) load(ctx context.Context) ([]byte, error) {
|
||||
if f.data != nil {
|
||||
return f.data, nil
|
||||
}
|
||||
@@ -195,5 +212,6 @@ func (f *fileNode) ReadAll(ctx context.Context) ([]byte, error) {
|
||||
}
|
||||
f.data = data
|
||||
f.size = uint64(len(data))
|
||||
f.knownSize = true
|
||||
return data, nil
|
||||
}
|
||||
|
||||
+20
-1
@@ -1,6 +1,11 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"bazil.org/fuse"
|
||||
)
|
||||
|
||||
func TestBuildMountTreeGroupsByFolderAndDate(t *testing.T) {
|
||||
items := []SearchItem{{
|
||||
@@ -51,3 +56,17 @@ func TestBuildMountTreeDeduplicatesAttachmentNames(t *testing.T) {
|
||||
t.Fatalf("expected second unique name, got %#v", date.children)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileNodeUnknownSizeDoesNotAdvertiseZeroLength(t *testing.T) {
|
||||
f := &fileNode{size: 0, knownSize: false}
|
||||
var attr fuse.Attr
|
||||
if err := f.Attr(context.Background(), &attr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if attr.Size != 0 {
|
||||
t.Fatalf("expected absent size to remain zero, got %d", attr.Size)
|
||||
}
|
||||
if f.knownSize {
|
||||
t.Fatal("expected unknown size before download")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user