Skip to content
This repository has been archived by the owner on Jun 2, 2022. It is now read-only.

Commit

Permalink
Determine size on Open if unknown
Browse files Browse the repository at this point in the history
This makes editors that rely on size read the entire file. Saves size
from the last open on the fs node so we can use it to serve attribute
requests.

Fixes #656.

Signed-off-by: Michael Smith <[email protected]>
  • Loading branch information
MikaelSmith committed Dec 16, 2019
1 parent 6fa5c5e commit 8458a1c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
13 changes: 13 additions & 0 deletions fuse/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type file struct {
writers uint
// Only valid if writers > 0
data []byte
// Size for content with unspecified size attribute
size uint64
}

func newFile(p *dir, e plugin.Entry) *file {
Expand Down Expand Up @@ -60,6 +62,10 @@ func (f *file) fillAttr(a *fuse.Attr) {
if f.writers != 0 {
// Override with local size.
a.Size = uint64(len(f.data))
} else if !attr.HasSize() {
// Use whatever size we know locally. Retrieving content can be expensive so we settle for
// including size only when it's been retreived previously by opening the file.
a.Size = f.size
}
}

Expand Down Expand Up @@ -102,6 +108,13 @@ func (f *file) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenR
// The entry's content size is unknown so open the file in direct IO mode. This enables FUSE
// to still read the entry's content so that built-in tools like cat and grep still work.
resp.Flags |= fuse.OpenDirectIO

// Also set the size for editors that won't read anything on an apparently empty file. This
// doesn't help with cat/grep because they check attributes before opening the file.
f.size, err = plugin.Size(ctx, entry)
if err != nil {
return nil, err
}
}
return f, nil
}
Expand Down
2 changes: 1 addition & 1 deletion fuse/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (suite *fileTestSuite) TestOpen_NoSize() {
var attr fuse.Attr
err = f.Attr(ctx, &attr)
suite.NoError(err)
suite.Equal(uint64(0), attr.Size)
suite.Equal(uint64(5), attr.Size)
}

func (suite *fileTestSuite) TestOpenWithSize() {
Expand Down
13 changes: 13 additions & 0 deletions plugin/methodWrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,19 @@ func Read(ctx context.Context, e Entry, size int64, offset int64) (data []byte,
return
}

// Size returns the size of readable content (if we can determine it).
func Size(ctx context.Context, e Entry) (uint64, error) {
if !ReadAction().IsSupportedOn(e) {
panic("plugin.Read called on a non-readable entry")
}

data, err := cachedRead(ctx, e)
if err != nil {
return 0, err
}
return data.size(), nil
}

// Metadata returns the entry's metadata. Note that Metadata's results could be cached.
func Metadata(ctx context.Context, e Entry) (JSONObject, error) {
return cachedMetadata(ctx, e)
Expand Down

0 comments on commit 8458a1c

Please sign in to comment.