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/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
View File
@@ -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")
}
}