Commit 30cdb148 authored by Aaron Jacobs's avatar Aaron Jacobs

Allow the kernel to send other requests while waiting for a read.

On Linux this significantly increases gcsfuse sequential read throughput.
parents 01144536 cf5cfbcc
...@@ -158,7 +158,15 @@ func (c *Connection) Init() (err error) { ...@@ -158,7 +158,15 @@ func (c *Connection) Init() (err error) {
initOp.Library = c.protocol initOp.Library = c.protocol
initOp.MaxReadahead = maxReadahead initOp.MaxReadahead = maxReadahead
initOp.MaxWrite = buffer.MaxWriteSize initOp.MaxWrite = buffer.MaxWriteSize
initOp.Flags = fusekernel.InitBigWrites
initOp.Flags = 0
// Tell the kernel not to use pitifully small 4 KiB writes.
initOp.Flags |= fusekernel.InitBigWrites
// Tell the kernel it is free to send further requests while a read request
// is in flight.
initOp.Flags |= fusekernel.InitAsyncRead
c.Reply(ctx, nil) c.Reply(ctx, nil)
return return
......
...@@ -20,6 +20,13 @@ import ( ...@@ -20,6 +20,13 @@ import (
) )
func describeRequest(op interface{}) (s string) { func describeRequest(op interface{}) (s string) {
// Handle special cases with custom formatting.
switch typed := op.(type) {
case *interruptOp:
s = fmt.Sprintf("interruptOp(fuseid=0x%08x)", typed.FuseID)
return
}
v := reflect.ValueOf(op).Elem() v := reflect.ValueOf(op).Elem()
t := v.Type() t := v.Type()
......
...@@ -40,9 +40,11 @@ type initOp struct { ...@@ -40,9 +40,11 @@ type initOp struct {
// In // In
Kernel fusekernel.Protocol Kernel fusekernel.Protocol
// In/out
Flags fusekernel.InitFlags
// Out // Out
Library fusekernel.Protocol Library fusekernel.Protocol
MaxReadahead uint32 MaxReadahead uint32
Flags fusekernel.InitFlags
MaxWrite uint32 MaxWrite uint32
} }
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"runtime"
"testing" "testing"
"time" "time"
...@@ -72,6 +73,18 @@ func (t *InterruptFSTest) StatFoo() { ...@@ -72,6 +73,18 @@ func (t *InterruptFSTest) StatFoo() {
} }
func (t *InterruptFSTest) InterruptedDuringRead() { func (t *InterruptFSTest) InterruptedDuringRead() {
// On Linux, since we have async reads enabled, the kernel sends the read and
// the flush ops in parallel. When the process receives SIGINT, the interrupt
// is delivered only for the flush, probably because that's what the process
// appears to be blocking on. So this test doesn't work.
//
// Note that this means that cancellation is not delivered for reads on
// Linux. This is unfortunate, but probably worth it due to the significant
// increase in performance.
if runtime.GOOS == "linux" {
return
}
var err error var err error
t.fs.EnableReadBlocking() t.fs.EnableReadBlocking()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment