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
} }
...@@ -633,47 +641,48 @@ func init() { ...@@ -633,47 +641,48 @@ func init() {
} }
for op, v := range map[int32]operationFunc{ for op, v := range map[int32]operationFunc{
_OP_OPEN: doOpen, _OP_OPEN: doOpen,
_OP_READDIR: doReadDir, _OP_READDIR: doReadDir,
_OP_WRITE: doWrite, _OP_WRITE: doWrite,
_OP_OPENDIR: doOpenDir, _OP_OPENDIR: doOpenDir,
_OP_CREATE: doCreate, _OP_CREATE: doCreate,
_OP_SETATTR: doSetattr, _OP_SETATTR: doSetattr,
_OP_GETXATTR: doGetXAttr, _OP_GETXATTR: doGetXAttr,
_OP_LISTXATTR: doGetXAttr, _OP_LISTXATTR: doGetXAttr,
_OP_GETATTR: doGetAttr, _OP_GETATTR: doGetAttr,
_OP_FORGET: doForget, _OP_FORGET: doForget,
_OP_BATCH_FORGET: doBatchForget, _OP_BATCH_FORGET: doBatchForget,
_OP_READLINK: doReadlink, _OP_READLINK: doReadlink,
_OP_INIT: doInit, _OP_INIT: doInit,
_OP_LOOKUP: doLookup, _OP_LOOKUP: doLookup,
_OP_MKNOD: doMknod, _OP_MKNOD: doMknod,
_OP_MKDIR: doMkdir, _OP_MKDIR: doMkdir,
_OP_UNLINK: doUnlink, _OP_UNLINK: doUnlink,
_OP_RMDIR: doRmdir, _OP_RMDIR: doRmdir,
_OP_LINK: doLink, _OP_LINK: doLink,
_OP_READ: doRead, _OP_READ: doRead,
_OP_FLUSH: doFlush, _OP_FLUSH: doFlush,
_OP_RELEASE: doRelease, _OP_RELEASE: doRelease,
_OP_FSYNC: doFsync, _OP_FSYNC: doFsync,
_OP_RELEASEDIR: doReleaseDir, _OP_RELEASEDIR: doReleaseDir,
_OP_FSYNCDIR: doFsyncDir, _OP_FSYNCDIR: doFsyncDir,
_OP_SETXATTR: doSetXAttr, _OP_SETXATTR: doSetXAttr,
_OP_REMOVEXATTR: doRemoveXAttr, _OP_REMOVEXATTR: doRemoveXAttr,
_OP_GETLK: doGetLk, _OP_GETLK: doGetLk,
_OP_SETLK: doSetLk, _OP_SETLK: doSetLk,
_OP_SETLKW: doSetLkw, _OP_SETLKW: doSetLkw,
_OP_ACCESS: doAccess, _OP_ACCESS: doAccess,
_OP_SYMLINK: doSymlink, _OP_SYMLINK: doSymlink,
_OP_RENAME: doRename, _OP_RENAME: doRename,
_OP_STATFS: doStatFs, _OP_STATFS: doStatFs,
_OP_IOCTL: doIoctl, _OP_IOCTL: doIoctl,
_OP_DESTROY: doDestroy, _OP_DESTROY: doDestroy,
_OP_NOTIFY_REPLY: doNotifyReply, _OP_NOTIFY_REPLY: doNotifyReply,
_OP_FALLOCATE: doFallocate, _OP_FALLOCATE: doFallocate,
_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