Fix FUSE reads for unknown attachment sizes

This commit is contained in:
Jan Bader
2026-07-13 23:03:41 +02:00
parent 2e0f0939b3
commit d57724151a
2 changed files with 40 additions and 3 deletions
+19 -1
View File
@@ -12,6 +12,7 @@ import (
"bazil.org/fuse" "bazil.org/fuse"
"bazil.org/fuse/fs" "bazil.org/fuse/fs"
"bazil.org/fuse/fuseutil"
) )
type docspellFS struct { type docspellFS struct {
@@ -27,6 +28,7 @@ type fileNode struct {
name string name string
attachmentID string attachmentID string
size uint64 size uint64
knownSize bool
modTime time.Time modTime time.Time
client *DocspellClient client *DocspellClient
data []byte data []byte
@@ -100,7 +102,7 @@ func buildMountTree(client *DocspellClient, items []SearchItem) *dirNode {
name = fmt.Sprintf("%s - %02d - %s", base, i+1, name) name = fmt.Sprintf("%s - %02d - %s", base, i+1, name)
} }
name = uniqueName(dir.children, 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 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 { func (f *fileNode) Attr(ctx context.Context, a *fuse.Attr) error {
a.Mode = 0444 a.Mode = 0444
if f.knownSize {
a.Size = f.size a.Size = f.size
}
a.Mtime = f.modTime a.Mtime = f.modTime
a.Ctime = f.modTime a.Ctime = f.modTime
return nil 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) { 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 { if f.data != nil {
return f.data, nil return f.data, nil
} }
@@ -195,5 +212,6 @@ func (f *fileNode) ReadAll(ctx context.Context) ([]byte, error) {
} }
f.data = data f.data = data
f.size = uint64(len(data)) f.size = uint64(len(data))
f.knownSize = true
return data, nil return data, nil
} }
+20 -1
View File
@@ -1,6 +1,11 @@
package main package main
import "testing" import (
"context"
"testing"
"bazil.org/fuse"
)
func TestBuildMountTreeGroupsByFolderAndDate(t *testing.T) { func TestBuildMountTreeGroupsByFolderAndDate(t *testing.T) {
items := []SearchItem{{ items := []SearchItem{{
@@ -51,3 +56,17 @@ func TestBuildMountTreeDeduplicatesAttachmentNames(t *testing.T) {
t.Fatalf("expected second unique name, got %#v", date.children) 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")
}
}