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
097754d4
Commit
097754d4
authored
May 25, 2012
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prepare read API for splicing.
parent
de0799bb
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
132 additions
and
48 deletions
+132
-48
fuse/api.go
fuse/api.go
+3
-2
fuse/copy.go
fuse/copy.go
+10
-8
fuse/defaultfile.go
fuse/defaultfile.go
+4
-2
fuse/defaultraw.go
fuse/defaultraw.go
+2
-2
fuse/files.go
fuse/files.go
+12
-10
fuse/fsetattr_test.go
fuse/fsetattr_test.go
+3
-2
fuse/fsops.go
fuse/fsops.go
+1
-1
fuse/lockingfs.go
fuse/lockingfs.go
+1
-1
fuse/mountstate.go
fuse/mountstate.go
+25
-7
fuse/opcode.go
fuse/opcode.go
+10
-4
fuse/read.go
fuse/read.go
+52
-0
fuse/request.go
fuse/request.go
+9
-9
No files found.
fuse/api.go
View file @
097754d4
...
...
@@ -77,6 +77,7 @@ type FsNode interface {
StatFs
()
*
StatfsOut
}
// A filesystem API that uses paths rather than inodes. A minimal
// file system should have at least a functional GetAttr method.
// Typically, each call happens in its own goroutine, so take care to
...
...
@@ -161,7 +162,7 @@ type File interface {
// the inner file here.
InnerFile
()
File
Read
(
dest
[]
byte
,
off
int64
)
([]
byte
,
Status
)
Read
(
dest
[]
byte
,
off
int64
)
ReadResult
Write
(
data
[]
byte
,
off
int64
)
(
written
uint32
,
code
Status
)
Flush
()
Status
Release
()
...
...
@@ -278,7 +279,7 @@ type RawFileSystem interface {
// File handling.
Create
(
out
*
raw
.
CreateOut
,
header
*
raw
.
InHeader
,
input
*
raw
.
CreateIn
,
name
string
)
(
code
Status
)
Open
(
out
*
raw
.
OpenOut
,
header
*
raw
.
InHeader
,
input
*
raw
.
OpenIn
)
(
status
Status
)
Read
(
*
raw
.
InHeader
,
*
ReadIn
,
[]
byte
)
([]
byte
,
Status
)
Read
(
*
raw
.
InHeader
,
*
ReadIn
,
[]
byte
)
ReadResult
Release
(
header
*
raw
.
InHeader
,
input
*
raw
.
ReleaseIn
)
Write
(
*
raw
.
InHeader
,
*
WriteIn
,
[]
byte
)
(
written
uint32
,
code
Status
)
...
...
fuse/copy.go
View file @
097754d4
...
...
@@ -30,24 +30,26 @@ func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *Conte
buf
:=
make
([]
byte
,
128
*
(
1
<<
10
))
off
:=
int64
(
0
)
for
{
data
,
code
:=
src
.
Read
(
buf
,
off
)
if
!
code
.
Ok
()
{
return
code
res
:=
src
.
Read
(
buf
,
off
)
if
!
res
.
Ok
()
{
return
res
.
Status
}
if
len
(
data
)
==
0
{
res
.
Read
(
buf
)
if
len
(
res
.
Data
)
==
0
{
break
}
n
,
code
:=
dst
.
Write
(
d
ata
,
off
)
n
,
code
:=
dst
.
Write
(
res
.
D
ata
,
off
)
if
!
code
.
Ok
()
{
return
code
}
if
int
(
n
)
<
len
(
d
ata
)
{
if
int
(
n
)
<
len
(
res
.
D
ata
)
{
return
EIO
}
if
len
(
d
ata
)
<
len
(
buf
)
{
if
len
(
res
.
D
ata
)
<
len
(
buf
)
{
break
}
off
+=
int64
(
len
(
d
ata
))
off
+=
int64
(
len
(
res
.
D
ata
))
}
return
OK
}
fuse/defaultfile.go
View file @
097754d4
...
...
@@ -8,6 +8,8 @@ import (
var
_
=
log
.
Println
var
_
=
(
File
)((
*
DefaultFile
)(
nil
))
func
(
f
*
DefaultFile
)
SetInode
(
*
Inode
)
{
}
...
...
@@ -19,8 +21,8 @@ func (f *DefaultFile) String() string {
return
"DefaultFile"
}
func
(
f
*
DefaultFile
)
Read
(
buf
[]
byte
,
off
int64
)
([]
byte
,
Status
)
{
return
nil
,
ENOSYS
func
(
f
*
DefaultFile
)
Read
(
buf
[]
byte
,
off
int64
)
ReadResult
{
return
ReadResult
{
Status
:
ENOSYS
}
}
func
(
f
*
DefaultFile
)
Write
(
data
[]
byte
,
off
int64
)
(
uint32
,
Status
)
{
...
...
fuse/defaultraw.go
View file @
097754d4
...
...
@@ -97,8 +97,8 @@ func (fs *DefaultRawFileSystem) OpenDir(out *raw.OpenOut, header *raw.InHeader,
return
ENOSYS
}
func
(
fs
*
DefaultRawFileSystem
)
Read
(
header
*
raw
.
InHeader
,
input
*
ReadIn
,
buf
[]
byte
)
([]
byte
,
Status
)
{
return
nil
,
ENOSYS
func
(
fs
*
DefaultRawFileSystem
)
Read
(
header
*
raw
.
InHeader
,
input
*
ReadIn
,
buf
[]
byte
)
ReadResult
{
return
ReadResult
{}
}
func
(
fs
*
DefaultRawFileSystem
)
Release
(
header
*
raw
.
InHeader
,
input
*
raw
.
ReleaseIn
)
{
...
...
fuse/files.go
View file @
097754d4
...
...
@@ -2,7 +2,6 @@ package fuse
import
(
"fmt"
"io"
"os"
"syscall"
)
...
...
@@ -40,13 +39,15 @@ func NewDataFile(data []byte) *DataFile {
return
f
}
func
(
f
*
DataFile
)
Read
(
buf
[]
byte
,
off
int64
)
(
[]
byte
,
Status
)
{
func
(
f
*
DataFile
)
Read
(
buf
[]
byte
,
off
int64
)
(
res
ReadResult
)
{
end
:=
int
(
off
)
+
int
(
len
(
buf
))
if
end
>
len
(
f
.
data
)
{
end
=
len
(
f
.
data
)
}
return
f
.
data
[
off
:
end
],
OK
res
.
Data
=
f
.
data
[
off
:
end
]
res
.
Status
=
OK
return
res
}
////////////////
...
...
@@ -66,8 +67,8 @@ func (f *DevNullFile) String() string {
return
"DevNullFile"
}
func
(
f
*
DevNullFile
)
Read
(
buf
[]
byte
,
off
int64
)
([]
byte
,
Status
)
{
return
nil
,
OK
func
(
f
*
DevNullFile
)
Read
(
buf
[]
byte
,
off
int64
)
ReadResult
{
return
ReadResult
{}
}
func
(
f
*
DevNullFile
)
Write
(
content
[]
byte
,
off
int64
)
(
uint32
,
Status
)
{
...
...
@@ -99,12 +100,13 @@ func (f *LoopbackFile) String() string {
return
fmt
.
Sprintf
(
"LoopbackFile(%s)"
,
f
.
File
.
Name
())
}
func
(
f
*
LoopbackFile
)
Read
(
buf
[]
byte
,
off
int64
)
([]
byte
,
Status
)
{
n
,
err
:=
f
.
File
.
ReadAt
(
buf
,
off
)
if
err
==
io
.
EOF
{
err
=
nil
func
(
f
*
LoopbackFile
)
Read
(
buf
[]
byte
,
off
int64
)
(
res
ReadResult
)
{
return
ReadResult
{
Fd
:
f
.
File
.
Fd
(),
FdOff
:
off
,
FdSize
:
len
(
buf
),
Status
:
OK
,
}
return
buf
[
:
n
],
ToStatus
(
err
)
}
func
(
f
*
LoopbackFile
)
Write
(
data
[]
byte
,
off
int64
)
(
uint32
,
Status
)
{
...
...
fuse/fsetattr_test.go
View file @
097754d4
...
...
@@ -22,8 +22,9 @@ func (f *MutableDataFile) String() string {
return
"MutableDataFile"
}
func
(
f
*
MutableDataFile
)
Read
(
buf
[]
byte
,
off
int64
)
([]
byte
,
Status
)
{
return
f
.
data
[
off
:
off
+
int64
(
len
(
buf
))],
OK
func
(
f
*
MutableDataFile
)
Read
(
buf
[]
byte
,
off
int64
)
(
r
ReadResult
)
{
r
.
Data
=
f
.
data
[
off
:
off
+
int64
(
len
(
buf
))]
return
r
}
func
(
f
*
MutableDataFile
)
Write
(
d
[]
byte
,
off
int64
)
(
uint32
,
Status
)
{
...
...
fuse/fsops.go
View file @
097754d4
...
...
@@ -350,7 +350,7 @@ func (c *FileSystemConnector) Write(header *raw.InHeader, input *WriteIn, data [
return
opened
.
WithFlags
.
File
.
Write
(
data
,
int64
(
input
.
Offset
))
}
func
(
c
*
FileSystemConnector
)
Read
(
header
*
raw
.
InHeader
,
input
*
ReadIn
,
buf
[]
byte
)
(
[]
byte
,
Status
)
{
func
(
c
*
FileSystemConnector
)
Read
(
header
*
raw
.
InHeader
,
input
*
ReadIn
,
buf
[]
byte
)
(
ReadResult
)
{
node
:=
c
.
toInode
(
header
.
NodeId
)
opened
:=
node
.
mount
.
getOpenedFile
(
input
.
Fh
)
...
...
fuse/lockingfs.go
View file @
097754d4
...
...
@@ -276,7 +276,7 @@ func (fs *LockingRawFileSystem) ReleaseDir(header *raw.InHeader, h *raw.ReleaseI
fs
.
RawFileSystem
.
ReleaseDir
(
header
,
h
)
}
func
(
fs
*
LockingRawFileSystem
)
Read
(
header
*
raw
.
InHeader
,
input
*
ReadIn
,
buf
[]
byte
)
([]
byte
,
Status
)
{
func
(
fs
*
LockingRawFileSystem
)
Read
(
header
*
raw
.
InHeader
,
input
*
ReadIn
,
buf
[]
byte
)
ReadResult
{
defer
fs
.
locked
()()
return
fs
.
RawFileSystem
.
Read
(
header
,
input
,
buf
)
}
...
...
fuse/mountstate.go
View file @
097754d4
...
...
@@ -322,6 +322,10 @@ func (ms *MountState) handleRequest(req *request) {
}
func
(
ms
*
MountState
)
AllocOut
(
req
*
request
,
size
uint32
)
[]
byte
{
if
cap
(
req
.
bufferPoolOutputBuf
)
>=
int
(
size
)
{
req
.
bufferPoolOutputBuf
=
req
.
bufferPoolOutputBuf
[
:
size
]
return
req
.
bufferPoolOutputBuf
}
if
req
.
bufferPoolOutputBuf
!=
nil
{
ms
.
buffers
.
FreeBuffer
(
req
.
bufferPoolOutputBuf
)
}
...
...
@@ -336,7 +340,7 @@ func (ms *MountState) write(req *request) Status {
return
OK
}
header
,
data
:=
req
.
serialize
()
header
:=
req
.
serializeHeader
()
if
ms
.
Debug
{
log
.
Println
(
req
.
OutputDebug
())
}
...
...
@@ -348,16 +352,30 @@ func (ms *MountState) write(req *request) Status {
if
header
==
nil
{
return
OK
}
var
err
error
if
data
==
nil
{
_
,
err
=
ms
.
mountFile
.
Write
(
header
)
}
else
{
_
,
err
=
Writev
(
int
(
ms
.
mountFile
.
Fd
()),
[][]
byte
{
header
,
data
})
if
req
.
flatData
.
Size
()
==
0
{
_
,
err
:=
ms
.
mountFile
.
Write
(
header
)
return
ToStatus
(
err
)
}
if
req
.
flatData
.
FdSize
>
0
{
if
ms
.
TrySplice
(
req
)
{
return
OK
}
else
{
buf
:=
ms
.
AllocOut
(
req
,
uint32
(
req
.
flatData
.
FdSize
))
req
.
flatData
.
Read
(
buf
)
}
}
_
,
err
:=
Writev
(
int
(
ms
.
mountFile
.
Fd
()),
[][]
byte
{
header
,
req
.
flatData
.
Data
})
return
ToStatus
(
err
)
}
func
(
ms
*
MountState
)
TrySplice
(
req
*
request
)
bool
{
// TODO - implement.
return
false
}
func
(
ms
*
MountState
)
writeInodeNotify
(
entry
*
raw
.
NotifyInvalInodeOut
)
Status
{
req
:=
request
{
inHeader
:
&
raw
.
InHeader
{
...
...
@@ -392,7 +410,7 @@ func (ms *MountState) writeEntryNotify(parent uint64, name string) Status {
// terminating null byte is missing.
nameBytes
:=
[]
byte
(
name
+
"
\0
00"
)
req
.
outData
=
unsafe
.
Pointer
(
entry
)
req
.
flatData
=
nameBytes
req
.
flatData
.
Data
=
nameBytes
result
:=
ms
.
write
(
&
req
)
if
ms
.
Debug
{
...
...
fuse/opcode.go
View file @
097754d4
...
...
@@ -123,7 +123,7 @@ func doReadDir(state *MountState, req *request) {
entries
:=
NewDirEntryList
(
buf
,
uint64
(
in
.
Offset
))
code
:=
state
.
fileSystem
.
ReadDir
(
entries
,
req
.
inHeader
,
in
)
req
.
flatData
=
entries
.
Bytes
()
req
.
flatData
.
Data
=
entries
.
Bytes
()
req
.
status
=
code
}
...
...
@@ -192,7 +192,7 @@ func doGetXAttr(state *MountState, req *request) {
return
}
req
.
flatData
=
data
req
.
flatData
.
Data
=
data
}
func
doGetAttr
(
state
*
MountState
,
req
*
request
)
{
...
...
@@ -223,7 +223,7 @@ func doBatchForget(state *MountState, req *request) {
}
func
doReadlink
(
state
*
MountState
,
req
*
request
)
{
req
.
flatData
,
req
.
status
=
state
.
fileSystem
.
Readlink
(
req
.
inHeader
)
req
.
flatData
.
Data
,
req
.
status
=
state
.
fileSystem
.
Readlink
(
req
.
inHeader
)
}
func
doLookup
(
state
*
MountState
,
req
*
request
)
{
...
...
@@ -260,7 +260,13 @@ func doLink(state *MountState, req *request) {
func
doRead
(
state
*
MountState
,
req
*
request
)
{
in
:=
(
*
ReadIn
)(
req
.
inData
)
buf
:=
state
.
AllocOut
(
req
,
in
.
Size
)
req
.
flatData
,
req
.
status
=
state
.
fileSystem
.
Read
(
req
.
inHeader
,
in
,
buf
)
res
:=
state
.
fileSystem
.
Read
(
req
.
inHeader
,
in
,
buf
)
if
res
.
Ok
()
{
res
.
Read
(
buf
)
}
req
.
flatData
=
res
req
.
status
=
res
.
Status
}
func
doFlush
(
state
*
MountState
,
req
*
request
)
{
...
...
fuse/read.go
0 → 100644
View file @
097754d4
package
fuse
import
(
"io"
"syscall"
)
type
ReadResult
struct
{
Status
Data
[]
byte
// If Data is nil and Status OK, splice from the following
// file.
Fd
uintptr
FdOff
int64
FdSize
int
}
func
(
r
*
ReadResult
)
Clear
()
{
*
r
=
ReadResult
{}
}
func
(
r
*
ReadResult
)
Size
()
int
{
if
r
.
Data
!=
nil
{
return
len
(
r
.
Data
)
}
return
r
.
FdSize
}
func
(
r
*
ReadResult
)
Read
(
buf
[]
byte
)
Status
{
if
r
.
Data
!=
nil
||
!
r
.
Ok
()
{
return
r
.
Status
}
if
len
(
buf
)
<
r
.
FdSize
{
r
.
Status
=
ERANGE
return
ERANGE
}
n
,
err
:=
syscall
.
Pread
(
int
(
r
.
Fd
),
buf
[
:
r
.
FdSize
],
r
.
FdOff
)
if
err
==
io
.
EOF
{
err
=
nil
}
r
.
Status
=
ToStatus
(
err
)
if
r
.
Ok
()
{
r
.
Data
=
buf
[
:
n
]
}
r
.
Fd
=
0
r
.
FdOff
=
0
r
.
FdSize
=
0
return
r
.
Status
}
fuse/request.go
View file @
097754d4
...
...
@@ -26,8 +26,8 @@ type request struct {
// Unstructured data, a pointer to the relevant XxxxOut struct.
outData
unsafe
.
Pointer
status
Status
flatData
[]
byte
flatData
ReadResult
// Start timestamp for timing info.
startNs
int64
preWriteNs
int64
...
...
@@ -58,7 +58,7 @@ func (r *request) clear() {
r
.
filenames
=
nil
r
.
outData
=
nil
r
.
status
=
OK
r
.
flatData
=
nil
r
.
flatData
.
Clear
()
r
.
preWriteNs
=
0
r
.
startNs
=
0
r
.
handler
=
nil
...
...
@@ -100,12 +100,12 @@ func (r *request) OutputDebug() string {
}
flatStr
:=
""
if
len
(
r
.
flatData
)
>
0
{
if
r
.
flatData
.
Size
(
)
>
0
{
if
r
.
handler
.
FileNameOut
{
s
:=
strings
.
TrimRight
(
string
(
r
.
flatData
),
"
\x00
"
)
s
:=
strings
.
TrimRight
(
string
(
r
.
flatData
.
Data
),
"
\x00
"
)
flatStr
=
fmt
.
Sprintf
(
" %q"
,
s
)
}
else
{
flatStr
=
fmt
.
Sprintf
(
" %d bytes data
\n
"
,
len
(
r
.
flatData
))
flatStr
=
fmt
.
Sprintf
(
" %d bytes data
\n
"
,
r
.
flatData
.
Size
(
))
}
}
...
...
@@ -175,7 +175,7 @@ func (r *request) parse() {
r
.
outData
=
unsafe
.
Pointer
(
&
r
.
outBuf
[
sizeOfOutHeader
])
}
func
(
r
*
request
)
serialize
()
(
header
[]
byte
,
data
[]
byte
)
{
func
(
r
*
request
)
serialize
Header
()
(
header
[]
byte
)
{
dataLength
:=
r
.
handler
.
OutputSize
if
r
.
outData
==
nil
||
r
.
status
>
OK
{
dataLength
=
0
...
...
@@ -187,11 +187,11 @@ func (r *request) serialize() (header []byte, data []byte) {
o
.
Unique
=
r
.
inHeader
.
Unique
o
.
Status
=
int32
(
-
r
.
status
)
o
.
Length
=
uint32
(
int
(
sizeOfOutHeader
)
+
int
(
dataLength
)
+
int
(
len
(
r
.
flatData
)
))
int
(
sizeOfOutHeader
)
+
int
(
dataLength
)
+
r
.
flatData
.
Size
(
))
var
asSlice
[]
byte
toSlice
(
&
asSlice
,
r
.
outData
,
dataLength
)
copy
(
header
[
sizeOfOutHeader
:
],
asSlice
)
return
header
,
r
.
flatData
return
header
}
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