Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jacobsa-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
jacobsa-fuse
Commits
5c332f76
Commit
5c332f76
authored
Jul 27, 2015
by
Aaron Jacobs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved the kernel response functions to a more appropriate place.
parent
4c33dd3f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
176 additions
and
169 deletions
+176
-169
conversions.go
conversions.go
+173
-0
ops.go
ops.go
+3
-169
No files found.
conversions.go
View file @
5c332f76
...
...
@@ -17,6 +17,7 @@ package fuse
import
(
"bytes"
"errors"
"fmt"
"os"
"syscall"
"time"
...
...
@@ -27,6 +28,10 @@ import (
"github.com/jacobsa/fuse/internal/fusekernel"
)
////////////////////////////////////////////////////////////////////////
// Incoming messages
////////////////////////////////////////////////////////////////////////
// Convert a kernel message to an appropriate op. If the op is unknown, a
// special unexported type will be used.
//
...
...
@@ -378,6 +383,174 @@ func convertInMessage(
return
}
////////////////////////////////////////////////////////////////////////
// Outgoing messages
////////////////////////////////////////////////////////////////////////
// Return the response that should be sent to the kernel. If the op requires no
// response, return a nil response.
func
kernelResponse
(
fuseID
uint64
,
op
interface
{},
opErr
error
,
protocol
fusekernel
.
Protocol
)
(
msg
[]
byte
)
{
// If the user replied with an error, create room enough just for the result
// header and fill it in with an error. Otherwise create an appropriate
// response.
var
b
buffer
.
OutMessage
if
opErr
!=
nil
{
b
=
buffer
.
NewOutMessage
(
0
)
if
errno
,
ok
:=
opErr
.
(
syscall
.
Errno
);
ok
{
b
.
OutHeader
()
.
Error
=
-
int32
(
errno
)
}
else
{
b
.
OutHeader
()
.
Error
=
-
int32
(
syscall
.
EIO
)
}
}
else
{
b
=
kernelResponseForOp
(
op
,
protocol
)
}
msg
=
b
.
Bytes
()
// Fill in the rest of the header, if a response is required.
if
msg
!=
nil
{
h
:=
b
.
OutHeader
()
h
.
Unique
=
fuseID
h
.
Len
=
uint32
(
len
(
msg
))
}
return
}
// Like kernelResponse, but assumes the user replied with a nil error to the
// op. Returns a nil response if no response is required.
func
kernelResponseForOp
(
op
interface
{},
protocol
fusekernel
.
Protocol
)
(
b
buffer
.
OutMessage
)
{
// Create the appropriate output message
switch
o
:=
op
.
(
type
)
{
case
*
fuseops
.
LookUpInodeOp
:
size
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
size
))
convertChildInodeEntry
(
&
o
.
Entry
,
out
)
case
*
fuseops
.
GetInodeAttributesOp
:
size
:=
fusekernel
.
AttrOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
AttrOut
)(
b
.
Grow
(
size
))
out
.
AttrValid
,
out
.
AttrValidNsec
=
convertExpirationTime
(
o
.
AttributesExpiration
)
convertAttributes
(
o
.
Inode
,
&
o
.
Attributes
,
&
out
.
Attr
)
case
*
fuseops
.
SetInodeAttributesOp
:
size
:=
fusekernel
.
AttrOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
AttrOut
)(
b
.
Grow
(
size
))
out
.
AttrValid
,
out
.
AttrValidNsec
=
convertExpirationTime
(
o
.
AttributesExpiration
)
convertAttributes
(
o
.
Inode
,
&
o
.
Attributes
,
&
out
.
Attr
)
case
*
fuseops
.
ForgetInodeOp
:
// No response.
case
*
fuseops
.
MkDirOp
:
size
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
size
))
convertChildInodeEntry
(
&
o
.
Entry
,
out
)
case
*
fuseops
.
CreateFileOp
:
eSize
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
eSize
+
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{}))
e
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
eSize
))
convertChildInodeEntry
(
&
o
.
Entry
,
e
)
oo
:=
(
*
fusekernel
.
OpenOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{})))
oo
.
Fh
=
uint64
(
o
.
Handle
)
case
*
fuseops
.
CreateSymlinkOp
:
size
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
size
))
convertChildInodeEntry
(
&
o
.
Entry
,
out
)
case
*
fuseops
.
RenameOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
RmDirOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
UnlinkOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
OpenDirOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{}))
out
:=
(
*
fusekernel
.
OpenOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{})))
out
.
Fh
=
uint64
(
o
.
Handle
)
case
*
fuseops
.
ReadDirOp
:
b
=
buffer
.
NewOutMessage
(
uintptr
(
len
(
o
.
Data
)))
b
.
Append
(
o
.
Data
)
case
*
fuseops
.
ReleaseDirHandleOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
OpenFileOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{}))
out
:=
(
*
fusekernel
.
OpenOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{})))
out
.
Fh
=
uint64
(
o
.
Handle
)
case
*
fuseops
.
ReadFileOp
:
b
=
buffer
.
NewOutMessage
(
uintptr
(
len
(
o
.
Data
)))
b
.
Append
(
o
.
Data
)
case
*
fuseops
.
WriteFileOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
WriteOut
{}))
out
:=
(
*
fusekernel
.
WriteOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
WriteOut
{})))
out
.
Size
=
uint32
(
len
(
o
.
Data
))
case
*
fuseops
.
SyncFileOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
FlushFileOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
ReleaseFileHandleOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
ReadSymlinkOp
:
b
=
buffer
.
NewOutMessage
(
uintptr
(
len
(
o
.
Target
)))
b
.
AppendString
(
o
.
Target
)
case
*
statFSOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
StatfsOut
{}))
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
StatfsOut
{}))
case
*
interruptOp
:
// No response.
case
*
initOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
InitOut
{}))
out
:=
(
*
fusekernel
.
InitOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
InitOut
{})))
out
.
Major
=
o
.
Library
.
Major
out
.
Minor
=
o
.
Library
.
Minor
out
.
MaxReadahead
=
o
.
MaxReadahead
out
.
Flags
=
uint32
(
o
.
Flags
)
out
.
MaxWrite
=
o
.
MaxWrite
default
:
panic
(
fmt
.
Sprintf
(
"Unknown op: %#v"
,
op
))
}
return
}
////////////////////////////////////////////////////////////////////////
// General conversions
////////////////////////////////////////////////////////////////////////
func
convertTime
(
t
time
.
Time
)
(
secs
uint64
,
nsec
uint32
)
{
totalNano
:=
t
.
UnixNano
()
secs
=
uint64
(
totalNano
/
1e9
)
...
...
ops.go
View file @
5c332f76
...
...
@@ -15,179 +15,10 @@
package
fuse
import
(
"fmt"
"syscall"
"unsafe"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/internal/buffer"
"github.com/jacobsa/fuse/internal/fusekernel"
)
// Return the response that should be sent to the kernel. If the op requires no
// response, return a nil response.
func
kernelResponse
(
fuseID
uint64
,
op
interface
{},
opErr
error
,
protocol
fusekernel
.
Protocol
)
(
msg
[]
byte
)
{
// If the user replied with an error, create room enough just for the result
// header and fill it in with an error. Otherwise create an appropriate
// response.
var
b
buffer
.
OutMessage
if
opErr
!=
nil
{
b
=
buffer
.
NewOutMessage
(
0
)
if
errno
,
ok
:=
opErr
.
(
syscall
.
Errno
);
ok
{
b
.
OutHeader
()
.
Error
=
-
int32
(
errno
)
}
else
{
b
.
OutHeader
()
.
Error
=
-
int32
(
syscall
.
EIO
)
}
}
else
{
b
=
kernelResponseForOp
(
op
,
protocol
)
}
msg
=
b
.
Bytes
()
// Fill in the rest of the header, if a response is required.
if
msg
!=
nil
{
h
:=
b
.
OutHeader
()
h
.
Unique
=
fuseID
h
.
Len
=
uint32
(
len
(
msg
))
}
return
}
// Like kernelResponse, but assumes the user replied with a nil error to the
// op. Returns a nil response if no response is required.
func
kernelResponseForOp
(
op
interface
{},
protocol
fusekernel
.
Protocol
)
(
b
buffer
.
OutMessage
)
{
// Create the appropriate output message
switch
o
:=
op
.
(
type
)
{
case
*
fuseops
.
LookUpInodeOp
:
size
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
size
))
convertChildInodeEntry
(
&
o
.
Entry
,
out
)
case
*
fuseops
.
GetInodeAttributesOp
:
size
:=
fusekernel
.
AttrOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
AttrOut
)(
b
.
Grow
(
size
))
out
.
AttrValid
,
out
.
AttrValidNsec
=
convertExpirationTime
(
o
.
AttributesExpiration
)
convertAttributes
(
o
.
Inode
,
&
o
.
Attributes
,
&
out
.
Attr
)
case
*
fuseops
.
SetInodeAttributesOp
:
size
:=
fusekernel
.
AttrOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
AttrOut
)(
b
.
Grow
(
size
))
out
.
AttrValid
,
out
.
AttrValidNsec
=
convertExpirationTime
(
o
.
AttributesExpiration
)
convertAttributes
(
o
.
Inode
,
&
o
.
Attributes
,
&
out
.
Attr
)
case
*
fuseops
.
ForgetInodeOp
:
// No response.
case
*
fuseops
.
MkDirOp
:
size
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
size
))
convertChildInodeEntry
(
&
o
.
Entry
,
out
)
case
*
fuseops
.
CreateFileOp
:
eSize
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
eSize
+
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{}))
e
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
eSize
))
convertChildInodeEntry
(
&
o
.
Entry
,
e
)
oo
:=
(
*
fusekernel
.
OpenOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{})))
oo
.
Fh
=
uint64
(
o
.
Handle
)
case
*
fuseops
.
CreateSymlinkOp
:
size
:=
fusekernel
.
EntryOutSize
(
protocol
)
b
=
buffer
.
NewOutMessage
(
size
)
out
:=
(
*
fusekernel
.
EntryOut
)(
b
.
Grow
(
size
))
convertChildInodeEntry
(
&
o
.
Entry
,
out
)
case
*
fuseops
.
RenameOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
RmDirOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
UnlinkOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
OpenDirOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{}))
out
:=
(
*
fusekernel
.
OpenOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{})))
out
.
Fh
=
uint64
(
o
.
Handle
)
case
*
fuseops
.
ReadDirOp
:
b
=
buffer
.
NewOutMessage
(
uintptr
(
len
(
o
.
Data
)))
b
.
Append
(
o
.
Data
)
case
*
fuseops
.
ReleaseDirHandleOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
OpenFileOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{}))
out
:=
(
*
fusekernel
.
OpenOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
OpenOut
{})))
out
.
Fh
=
uint64
(
o
.
Handle
)
case
*
fuseops
.
ReadFileOp
:
b
=
buffer
.
NewOutMessage
(
uintptr
(
len
(
o
.
Data
)))
b
.
Append
(
o
.
Data
)
case
*
fuseops
.
WriteFileOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
WriteOut
{}))
out
:=
(
*
fusekernel
.
WriteOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
WriteOut
{})))
out
.
Size
=
uint32
(
len
(
o
.
Data
))
case
*
fuseops
.
SyncFileOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
FlushFileOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
ReleaseFileHandleOp
:
b
=
buffer
.
NewOutMessage
(
0
)
case
*
fuseops
.
ReadSymlinkOp
:
b
=
buffer
.
NewOutMessage
(
uintptr
(
len
(
o
.
Target
)))
b
.
AppendString
(
o
.
Target
)
case
*
statFSOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
StatfsOut
{}))
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
StatfsOut
{}))
case
*
interruptOp
:
// No response.
case
*
initOp
:
b
=
buffer
.
NewOutMessage
(
unsafe
.
Sizeof
(
fusekernel
.
InitOut
{}))
out
:=
(
*
fusekernel
.
InitOut
)(
b
.
Grow
(
unsafe
.
Sizeof
(
fusekernel
.
InitOut
{})))
out
.
Major
=
o
.
Library
.
Major
out
.
Minor
=
o
.
Library
.
Minor
out
.
MaxReadahead
=
o
.
MaxReadahead
out
.
Flags
=
uint32
(
o
.
Flags
)
out
.
MaxWrite
=
o
.
MaxWrite
default
:
panic
(
fmt
.
Sprintf
(
"Unknown op: %#v"
,
op
))
}
return
}
////////////////////////////////////////////////////////////////////////
// Internal
////////////////////////////////////////////////////////////////////////
// A sentinel used for unknown ops. The user is expected to respond with a
// non-nil error.
type
unknownOp
struct
{
...
...
@@ -195,13 +26,16 @@ type unknownOp struct {
inode
fuseops
.
InodeID
}
// Required in order to mount on OS X.
type
statFSOp
struct
{
}
// Causes us to cancel the associated context.
type
interruptOp
struct
{
FuseID
uint64
}
// Required in order to mount on Linux and OS X.
type
initOp
struct
{
// In
Kernel
fusekernel
.
Protocol
...
...
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