Commit a626ad83 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Move splice code into fuse/splice_linux.go, to help ports to other

platforms.
parent c302d08f
......@@ -2,7 +2,6 @@ package fuse
import (
"fmt"
"io"
"log"
"os"
"strings"
......@@ -11,7 +10,6 @@ import (
"unsafe"
"github.com/hanwen/go-fuse/raw"
"github.com/hanwen/go-fuse/splice"
)
const (
......@@ -383,10 +381,10 @@ func (ms *MountState) write(req *request) Status {
}
if req.fdData != nil {
if err := ms.TrySplice(header, req, req.fdData); err == nil {
if err := ms.trySplice(header, req, req.fdData); err == nil {
return OK
} else {
log.Println("TrySplice:", err)
log.Println("trySplice:", err)
sz := req.flatDataSize()
buf := ms.AllocOut(req, uint32(sz))
req.flatData, req.status = req.fdData.Bytes(buf)
......@@ -398,62 +396,6 @@ func (ms *MountState) write(req *request) Status {
return ToStatus(err)
}
func (ms *MountState) TrySplice(header []byte, req *request, fdData *ReadResultFd) error {
pair, err := splice.Get()
if err != nil {
return err
}
defer splice.Done(pair)
total := len(header) + fdData.Size()
if !pair.Grow(total) {
return fmt.Errorf("splice.Grow failed.")
}
_, err = pair.Write(header)
if err != nil {
return err
}
var n int
if fdData.Off < 0 {
n, err = pair.LoadFrom(fdData.Fd, fdData.Size())
} else {
n, err = pair.LoadFromAt(fdData.Fd, fdData.Size(), fdData.Off)
}
if err == io.EOF || (err == nil && n < fdData.Size()) {
discard := make([]byte, len(header))
_, err = pair.Read(discard)
if err != nil {
return err
}
header = req.serializeHeader(n)
newFd := ReadResultFd{
Fd: pair.ReadFd(),
Off: -1,
Sz: n,
}
return ms.TrySplice(header, req, &newFd)
}
if err != nil {
// TODO - extract the data from splice.
return err
}
if n != fdData.Size() {
return fmt.Errorf("wrote %d, want %d", n, fdData.Size())
}
_, err = pair.WriteTo(ms.mountFile.Fd(), total)
if err != nil {
return err
}
return nil
}
func (ms *MountState) writeInodeNotify(entry *raw.NotifyInvalInodeOut) Status {
req := request{
inHeader: &raw.InHeader{
......
......@@ -8,7 +8,6 @@ import (
"unsafe"
"github.com/hanwen/go-fuse/raw"
"github.com/hanwen/go-fuse/splice"
)
var _ = log.Printf
......@@ -89,11 +88,7 @@ func doInit(state *MountState, req *request) {
state.kernelSettings = *input
state.kernelSettings.Flags = input.Flags & (raw.CAP_ASYNC_READ | raw.CAP_BIG_WRITES | raw.CAP_FILE_OPS)
if input.Minor >= 13 {
state.canSplice = true
maxW := splice.MaxPipeSize() - 4096
if !splice.Resizable() && state.opts.MaxWrite > maxW {
state.opts.MaxWrite = maxW
}
state.setSplice()
}
state.reqMu.Unlock()
......
package fuse
import (
"fmt"
"io"
"github.com/hanwen/go-fuse/splice"
)
func (s *MountState) setSplice() {
s.canSplice = true
maxW := splice.MaxPipeSize() - 4096
if !splice.Resizable() && s.opts.MaxWrite > maxW {
s.opts.MaxWrite = maxW
}
}
func (ms *MountState) trySplice(header []byte, req *request, fdData *ReadResultFd) error {
pair, err := splice.Get()
if err != nil {
return err
}
defer splice.Done(pair)
total := len(header) + fdData.Size()
if !pair.Grow(total) {
return fmt.Errorf("splice.Grow failed.")
}
_, err = pair.Write(header)
if err != nil {
return err
}
var n int
if fdData.Off < 0 {
n, err = pair.LoadFrom(fdData.Fd, fdData.Size())
} else {
n, err = pair.LoadFromAt(fdData.Fd, fdData.Size(), fdData.Off)
}
if err == io.EOF || (err == nil && n < fdData.Size()) {
discard := make([]byte, len(header))
_, err = pair.Read(discard)
if err != nil {
return err
}
header = req.serializeHeader(n)
newFd := ReadResultFd{
Fd: pair.ReadFd(),
Off: -1,
Sz: n,
}
return ms.trySplice(header, req, &newFd)
}
if err != nil {
// TODO - extract the data from splice.
return err
}
if n != fdData.Size() {
return fmt.Errorf("wrote %d, want %d", n, fdData.Size())
}
_, err = pair.WriteTo(ms.mountFile.Fd(), total)
if err != nil {
return err
}
return nil
}
package raw
// arbitrary values
const syscall_O_LARGEFILE = 1 << 29
const syscall_O_NOATIME = 1 << 30
package raw
import (
"syscall"
)
const syscall_O_LARGEFILE = syscall.O_LARGEFILE
const syscall_O_NOATIME = syscall.O_NOATIME
......@@ -54,9 +54,9 @@ func init() {
syscall.O_CLOEXEC: "CLOEXEC",
syscall.O_DIRECT: "DIRECT",
syscall.O_DIRECTORY: "DIRECTORY",
syscall.O_LARGEFILE: "LARGEFILE",
syscall.O_NOATIME: "NOATIME",
syscall.O_DIRECTORY: "DIRECTORY",
syscall_O_LARGEFILE: "LARGEFILE",
syscall_O_NOATIME: "NOATIME",
}
FuseOpenFlagNames = map[int]string{
FOPEN_DIRECT_IO: "DIRECT",
......
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