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

fuse: support CopyFileRange

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