Fix FUSE reads for unknown attachment sizes
This commit is contained in:
@@ -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
|
||||||
a.Size = f.size
|
if f.knownSize {
|
||||||
|
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
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user