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

On Linux this significantly increases gcsfuse sequential read throughput.
geesefs-0-30-9
Aaron Jacobs 2015-07-29 14:59:35 +10:00
commit 30cdb148b9
4 changed files with 32 additions and 2 deletions

View File

@ -158,7 +158,15 @@ func (c *Connection) Init() (err error) {
initOp.Library = c.protocol
initOp.MaxReadahead = maxReadahead
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)
return

View File

@ -20,6 +20,13 @@ import (
)
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()
t := v.Type()

4
ops.go
View File

@ -40,9 +40,11 @@ type initOp struct {
// In
Kernel fusekernel.Protocol
// In/out
Flags fusekernel.InitFlags
// Out
Library fusekernel.Protocol
MaxReadahead uint32
Flags fusekernel.InitFlags
MaxWrite uint32
}

View File

@ -19,6 +19,7 @@ import (
"os"
"os/exec"
"path"
"runtime"
"testing"
"time"
@ -72,6 +73,18 @@ func (t *InterruptFSTest) StatFoo() {
}
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
t.fs.EnableReadBlocking()