Commit 9f3ce49d authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fuse: support CopyFileRange

parent e12761ce
......@@ -247,6 +247,8 @@ type RawFileSystem interface {
Release(input *ReleaseIn)
Write(cancel <-chan struct{}, input *WriteIn, data []byte) (written uint32, code Status)
CopyFileRange(cancel <-chan struct{}, input *CopyFileRangeIn) (written uint32, code Status)
Flush(cancel <-chan struct{}, input *FlushIn) Status
Fsync(cancel <-chan struct{}, input *FsyncIn) (code Status)
Fallocate(cancel <-chan struct{}, input *FallocateIn) (code Status)
......
......@@ -158,3 +158,7 @@ func (fs *defaultRawFileSystem) FsyncDir(cancel <-chan struct{}, input *FsyncIn)
func (fs *defaultRawFileSystem) Fallocate(cancel <-chan struct{}, in *FallocateIn) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) CopyFileRange(cancel <-chan struct{}, input *CopyFileRangeIn) (written uint32, code Status) {
return 0, ENOSYS
}
......@@ -218,3 +218,8 @@ func (fs *lockingRawFileSystem) String() string {
defer fs.locked()()
return fmt.Sprintf("Locked(%s)", fs.RawFS.String())
}
func (fs *lockingRawFileSystem) CopyFileRange(cancel <-chan struct{}, input *CopyFileRangeIn) (written uint32, code Status) {
defer fs.locked()()
return fs.RawFS.CopyFileRange(cancel, input)
}
......@@ -441,6 +441,13 @@ func doSetLkw(server *Server, req *request) {
req.status = server.fileSystem.SetLkw(req.cancel, (*LkIn)(req.inData))
}
func doCopyFileRange(server *Server, req *request) {
in := (*CopyFileRangeIn)(req.inData)
out := (*WriteOut)(req.outData())
out.Size, req.status = server.fileSystem.CopyFileRange(req.cancel, in)
}
func doInterrupt(server *Server, req *request) {
input := (*InterruptIn)(req.inData)
server.reqMu.Lock()
......@@ -573,6 +580,7 @@ func init() {
_OP_NOTIFY_RETRIEVE_CACHE: unsafe.Sizeof(NotifyRetrieveOut{}),
_OP_NOTIFY_DELETE: unsafe.Sizeof(NotifyInvalDeleteOut{}),
_OP_LSEEK: unsafe.Sizeof(LseekOut{}),
_OP_COPY_FILE_RANGE: unsafe.Sizeof(WriteOut{}),
} {
operationHandlers[op].OutputSize = sz
}
......@@ -674,6 +682,7 @@ func init() {
_OP_READDIRPLUS: doReadDirPlus,
_OP_RENAME2: doRename2,
_OP_INTERRUPT: doInterrupt,
_OP_COPY_FILE_RANGE: doCopyFileRange,
} {
operationHandlers[op].Func = v
}
......@@ -698,6 +707,7 @@ func init() {
_OP_SYMLINK: func(ptr unsafe.Pointer) interface{} { return (*EntryOut)(ptr) },
_OP_GETLK: func(ptr unsafe.Pointer) interface{} { return (*LkOut)(ptr) },
_OP_LSEEK: func(ptr unsafe.Pointer) interface{} { return (*LseekOut)(ptr) },
_OP_COPY_FILE_RANGE: func(ptr unsafe.Pointer) interface{} { return (*WriteOut)(ptr) },
} {
operationHandlers[op].DecodeOut = f
}
......
......@@ -269,6 +269,15 @@ func (f *LinkIn) string() string {
return fmt.Sprintf("{Oldnodeid: %d}", f.Oldnodeid)
}
func (o *WriteOut) string() string {
return fmt.Sprintf("{%db }", o.Size)
}
func (i *CopyFileRangeIn) string() string {
return fmt.Sprintf("{Fh %d [%d +%d) => i%d Fh %d [%d, %d)}",
i.FhIn, i.OffIn, i.Len, i.NodeIdOut, i.FhOut, i.OffOut, i.Len)
}
func (in *InterruptIn) string() string {
return fmt.Sprintf("{ix %d}", in.Unique)
}
......
......@@ -510,6 +510,7 @@ type FlushIn struct {
}
type LseekIn struct {
InHeader
Fh uint64
Offset uint64
Whence uint32
......@@ -521,6 +522,7 @@ type LseekOut struct {
}
type CopyFileRangeIn struct {
InHeader
FhIn uint64
OffIn uint64
NodeIdOut uint64
......
......@@ -520,3 +520,12 @@ func (fs *wrappingFS) Fallocate(cancel <-chan struct{}, in *FallocateIn) (code S
}
return ENOSYS
}
func (fs *wrappingFS) CopyFileRange(cancel <-chan struct{}, in *CopyFileRangeIn) (written uint32, code Status) {
if s, ok := fs.fs.(interface {
CopyFileRange(cancel <-chan struct{}, in *CopyFileRangeIn) (uint32, Status)
}); ok {
return s.CopyFileRange(cancel, in)
}
return 0, ENOSYS
}
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