Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go-fuse
Commits
5e3fe891
Commit
5e3fe891
authored
Mar 22, 2019
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nodefs: implement CopyFileRange
parent
9f3ce49d
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
83 additions
and
0 deletions
+83
-0
fuse/nodefs/fsops.go
fuse/nodefs/fsops.go
+4
-0
nodefs/api.go
nodefs/api.go
+5
-0
nodefs/bridge.go
nodefs/bridge.go
+8
-0
nodefs/default.go
nodefs/default.go
+6
-0
nodefs/loopback.go
nodefs/loopback.go
+18
-0
nodefs/simple_test.go
nodefs/simple_test.go
+42
-0
No files found.
fuse/nodefs/fsops.go
View file @
5e3fe891
...
...
@@ -494,3 +494,7 @@ func (c *rawBridge) Flush(cancel <-chan struct{}, input *fuse.FlushIn) fuse.Stat
}
return
fuse
.
OK
}
func
(
c
*
rawBridge
)
CopyFileRange
(
cancel
<-
chan
struct
{},
input
*
fuse
.
CopyFileRangeIn
)
(
written
uint32
,
code
fuse
.
Status
)
{
return
0
,
fuse
.
ENOSYS
}
nodefs/api.go
View file @
5e3fe891
...
...
@@ -191,6 +191,11 @@ type FileOperations interface {
// FSetAttr is like SetAttr but provides a file handle if available.
FSetAttr
(
ctx
context
.
Context
,
f
FileHandle
,
in
*
fuse
.
SetAttrIn
,
out
*
fuse
.
AttrOut
)
fuse
.
Status
// CopyFileRange copies data between sections of two files.
CopyFileRange
(
ctx
context
.
Context
,
fhIn
FileHandle
,
offIn
uint64
,
out
*
Inode
,
fhOut
FileHandle
,
offOut
uint64
,
len
uint64
,
flags
uint64
)
(
uint32
,
fuse
.
Status
)
}
// LockOperations are operations for locking regions of regular files.
...
...
nodefs/bridge.go
View file @
5e3fe891
...
...
@@ -738,3 +738,11 @@ func (b *rawBridge) StatFs(cancel <-chan struct{}, input *fuse.InHeader, out *fu
func
(
b
*
rawBridge
)
Init
(
s
*
fuse
.
Server
)
{
b
.
server
=
s
}
func
(
b
*
rawBridge
)
CopyFileRange
(
cancel
<-
chan
struct
{},
in
*
fuse
.
CopyFileRangeIn
)
(
size
uint32
,
status
fuse
.
Status
)
{
n1
,
f1
:=
b
.
inode
(
in
.
NodeId
,
in
.
FhIn
)
n2
,
f2
:=
b
.
inode
(
in
.
NodeIdOut
,
in
.
FhOut
)
return
n1
.
fileOps
()
.
CopyFileRange
(
&
fuse
.
Context
{
Caller
:
in
.
Caller
,
Cancel
:
cancel
},
f1
.
file
,
in
.
OffIn
,
n2
,
f2
.
file
,
in
.
OffOut
,
in
.
Len
,
in
.
Flags
)
}
nodefs/default.go
View file @
5e3fe891
...
...
@@ -201,6 +201,12 @@ func (n *DefaultOperations) Write(ctx context.Context, f FileHandle, data []byte
return
0
,
fuse
.
EROFS
}
func
(
n
*
DefaultOperations
)
CopyFileRange
(
ctx
context
.
Context
,
fhIn
FileHandle
,
offIn
uint64
,
out
*
Inode
,
fhOut
FileHandle
,
offOut
uint64
,
len
uint64
,
flags
uint64
)
(
uint32
,
fuse
.
Status
)
{
return
0
,
fuse
.
EROFS
}
// GetLk delegates to the FileHandlef
func
(
n
*
DefaultOperations
)
GetLk
(
ctx
context
.
Context
,
f
FileHandle
,
owner
uint64
,
lk
*
fuse
.
FileLock
,
flags
uint32
,
out
*
fuse
.
FileLock
)
(
status
fuse
.
Status
)
{
if
f
!=
nil
{
...
...
nodefs/loopback.go
View file @
5e3fe891
...
...
@@ -279,6 +279,24 @@ func (n *loopbackNode) FGetAttr(ctx context.Context, f FileHandle, out *fuse.Att
return
fuse
.
OK
}
func
(
n
*
loopbackNode
)
CopyFileRange
(
ctx
context
.
Context
,
fhIn
FileHandle
,
offIn
uint64
,
out
*
Inode
,
fhOut
FileHandle
,
offOut
uint64
,
len
uint64
,
flags
uint64
)
(
uint32
,
fuse
.
Status
)
{
lfIn
,
ok
:=
fhIn
.
(
*
loopbackFile
)
if
!
ok
{
return
0
,
fuse
.
ENOTSUP
}
lfOut
,
ok
:=
fhOut
.
(
*
loopbackFile
)
if
!
ok
{
return
0
,
fuse
.
ENOTSUP
}
signedOffIn
:=
int64
(
offIn
)
signedOffOut
:=
int64
(
offOut
)
count
,
err
:=
unix
.
CopyFileRange
(
lfIn
.
fd
,
&
signedOffIn
,
lfOut
.
fd
,
&
signedOffOut
,
int
(
len
),
int
(
flags
))
return
uint32
(
count
),
fuse
.
ToStatus
(
err
)
}
// NewLoopback returns a root node for a loopback file system whose
// root is at the given root.
func
NewLoopbackRoot
(
root
string
)
(
DirOperations
,
error
)
{
...
...
nodefs/simple_test.go
View file @
5e3fe891
...
...
@@ -682,3 +682,45 @@ func TestGetAttrParallel(t *testing.T) {
}
// XXX test mknod.
func
TestCopyFileRange
(
t
*
testing
.
T
)
{
tc
:=
newTestCase
(
t
,
true
,
true
)
defer
tc
.
Clean
()
tc
.
writeOrig
(
"src"
,
"01234567890123456789"
,
0644
)
tc
.
writeOrig
(
"dst"
,
"abcdefghijabcdefghij"
,
0644
)
f1
,
err
:=
syscall
.
Open
(
tc
.
mntDir
+
"/src"
,
syscall
.
O_RDONLY
,
0
)
if
err
!=
nil
{
t
.
Fatalf
(
"Open src: %v"
,
err
)
}
defer
syscall
.
Close
(
f1
)
f2
,
err
:=
syscall
.
Open
(
tc
.
mntDir
+
"/dst"
,
syscall
.
O_RDWR
,
0
)
if
err
!=
nil
{
t
.
Fatalf
(
"Open dst: %v"
,
err
)
}
defer
syscall
.
Close
(
f2
)
srcOff
:=
int64
(
5
)
dstOff
:=
int64
(
7
)
if
sz
,
err
:=
unix
.
CopyFileRange
(
f1
,
&
srcOff
,
f2
,
&
dstOff
,
3
,
0
);
err
!=
nil
||
sz
!=
3
{
t
.
Fatalf
(
"CopyFileRange: %d,%v"
,
sz
,
err
)
}
if
err
:=
syscall
.
Close
(
f1
);
err
!=
nil
{
t
.
Fatalf
(
"Close src: %v"
,
err
)
}
if
err
:=
syscall
.
Close
(
f2
);
err
!=
nil
{
t
.
Fatalf
(
"Close dst: %v"
,
err
)
}
c
,
err
:=
ioutil
.
ReadFile
(
tc
.
mntDir
+
"/dst"
)
if
err
!=
nil
{
t
.
Fatalf
(
"ReadFile: %v"
,
err
)
}
want
:=
"abcdefg567abcdefghij"
got
:=
string
(
c
)
if
got
!=
want
{
t
.
Errorf
(
"got %q want %q"
,
got
,
want
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment