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
e7a97bf9
Commit
e7a97bf9
authored
Jul 27, 2015
by
Aaron Jacobs
Browse files
Options
Browse Files
Download
Plain Diff
Killed off fuseops.Op.
parents
ef3d11e2
a99d69ab
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
13 additions
and
295 deletions
+13
-295
connection.go
connection.go
+2
-3
conversions.go
conversions.go
+3
-3
errors.go
errors.go
+1
-1
fuseops/common_op.go
fuseops/common_op.go
+0
-174
fuseops/doc.go
fuseops/doc.go
+2
-3
fuseops/ops.go
fuseops/ops.go
+0
-106
fuseutil/file_system.go
fuseutil/file_system.go
+3
-3
ops.go
ops.go
+2
-2
No files found.
connection.go
View file @
e7a97bf9
...
...
@@ -26,7 +26,6 @@ import (
"golang.org/x/net/context"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/internal/buffer"
"github.com/jacobsa/fuse/internal/fusekernel"
)
...
...
@@ -90,7 +89,7 @@ type Connection struct {
// context that the user uses to reply to the op.
type
opState
struct
{
inMsg
*
buffer
.
InMessage
op
fuseops
.
Op
op
interface
{}
opID
uint32
// For logging
}
...
...
@@ -396,7 +395,7 @@ func (c *Connection) writeMessage(msg []byte) (err error) {
// /dev/fuse. It must not be called multiple times concurrently.
//
// LOCKS_EXCLUDED(c.mu)
func
(
c
*
Connection
)
ReadOp
()
(
ctx
context
.
Context
,
op
fuseops
.
Op
,
err
error
)
{
func
(
c
*
Connection
)
ReadOp
()
(
ctx
context
.
Context
,
op
interface
{}
,
err
error
)
{
// Keep going until we find a request we know how to convert.
for
{
// Read the next message from the kernel.
...
...
conversions.go
View file @
e7a97bf9
...
...
@@ -27,13 +27,13 @@ import (
"github.com/jacobsa/fuse/internal/fusekernel"
)
// Convert a kernel message to an appropriate
implementation of fuseops.Op. If
//
the op is unknown, a
special unexported type will be used.
// Convert a kernel message to an appropriate
op. If the op is unknown, a
// special unexported type will be used.
//
// The caller is responsible for arranging for the message to be destroyed.
func
convertInMessage
(
m
*
buffer
.
InMessage
,
protocol
fusekernel
.
Protocol
)
(
o
fuseops
.
Op
,
err
error
)
{
protocol
fusekernel
.
Protocol
)
(
o
interface
{}
,
err
error
)
{
switch
m
.
Header
()
.
Opcode
{
case
fusekernel
.
OpLookup
:
buf
:=
m
.
ConsumeBytes
(
m
.
Len
())
...
...
errors.go
View file @
e7a97bf9
...
...
@@ -18,7 +18,7 @@ import "syscall"
const
(
// Errors corresponding to kernel error numbers. These may be treated
// specially by
fuseops.Op.Respond methods
.
// specially by
Connection.Reply
.
EEXIST
=
syscall
.
EEXIST
EINVAL
=
syscall
.
EINVAL
EIO
=
syscall
.
EIO
...
...
fuseops/common_op.go
deleted
100644 → 0
View file @
ef3d11e2
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fuseops
import
(
"fmt"
"log"
"reflect"
"strings"
"syscall"
"github.com/jacobsa/fuse/internal/buffer"
"github.com/jacobsa/reqtrace"
"golang.org/x/net/context"
)
// An interface that all ops inside which commonOp is embedded must
// implement.
type
internalOp
interface
{
Op
// Create a response message for the kernel, leaving the leading
// fusekernel.OutHeader untouched.
//
// Special case: a zero return value means that the kernel is not expecting a
// response.
kernelResponse
()
(
b
buffer
.
OutMessage
)
}
// A function that sends a reply message back to the kernel for the request
// with the given fuse unique ID. The error argument is for informational
// purposes only; the error to hand to the kernel is encoded in the message.
type
replyFunc
func
(
Op
,
uint64
,
[]
byte
,
error
)
error
// A helper for embedding common behavior.
type
commonOp
struct
{
// The context exposed to the user.
ctx
context
.
Context
// The op in which this struct is embedded.
op
internalOp
// The fuse unique ID of this request, as assigned by the kernel.
fuseID
uint64
// A function that can be used to send a reply to the kernel.
sendReply
replyFunc
// A function that can be used to log debug information about the op. The
// first argument is a call depth.
//
// May be nil.
debugLog
func
(
int
,
string
,
...
interface
{})
// A logger to be used for logging exceptional errors.
//
// May be nil.
errorLogger
*
log
.
Logger
}
func
(
o
*
commonOp
)
ShortDesc
()
(
desc
string
)
{
v
:=
reflect
.
ValueOf
(
o
.
op
)
opName
:=
v
.
Type
()
.
String
()
// Attempt to better handle the usual case: a string that looks like
// "*fuseops.GetInodeAttributesOp".
const
prefix
=
"*fuseops."
const
suffix
=
"Op"
if
strings
.
HasPrefix
(
opName
,
prefix
)
&&
strings
.
HasSuffix
(
opName
,
suffix
)
{
opName
=
opName
[
len
(
prefix
)
:
len
(
opName
)
-
len
(
suffix
)]
}
desc
=
opName
// Include the inode number to which the op applies, if possible.
if
f
:=
v
.
Elem
()
.
FieldByName
(
"Inode"
);
f
.
IsValid
()
{
desc
=
fmt
.
Sprintf
(
"%s(inode=%v)"
,
desc
,
f
.
Interface
())
}
return
}
func
(
o
*
commonOp
)
DebugString
()
string
{
// By default, defer to ShortDesc.
return
o
.
op
.
ShortDesc
()
}
func
(
o
*
commonOp
)
init
(
ctx
context
.
Context
,
op
internalOp
,
fuseID
uint64
,
sendReply
replyFunc
,
debugLog
func
(
int
,
string
,
...
interface
{}),
errorLogger
*
log
.
Logger
)
{
// Initialize basic fields.
o
.
ctx
=
ctx
o
.
op
=
op
o
.
fuseID
=
fuseID
o
.
sendReply
=
sendReply
o
.
debugLog
=
debugLog
o
.
errorLogger
=
errorLogger
// Set up a trace span for this op.
var
reportForTrace
reqtrace
.
ReportFunc
o
.
ctx
,
reportForTrace
=
reqtrace
.
StartSpan
(
o
.
ctx
,
o
.
op
.
ShortDesc
())
// When the op is finished, report to both reqtrace and the connection.
prevSendReply
:=
o
.
sendReply
o
.
sendReply
=
func
(
op
Op
,
fuseID
uint64
,
msg
[]
byte
,
opErr
error
)
(
err
error
)
{
reportForTrace
(
opErr
)
err
=
prevSendReply
(
op
,
fuseID
,
msg
,
opErr
)
return
}
}
func
(
o
*
commonOp
)
Context
()
context
.
Context
{
return
o
.
ctx
}
func
(
o
*
commonOp
)
Logf
(
format
string
,
v
...
interface
{})
{
if
o
.
debugLog
==
nil
{
return
}
const
calldepth
=
2
o
.
debugLog
(
calldepth
,
format
,
v
...
)
}
func
(
o
*
commonOp
)
Respond
(
err
error
)
{
// If successful, we ask the op for an appopriate response to the kernel, and
// it is responsible for leaving room for the fusekernel.OutHeader struct.
// Otherwise, create our own.
var
b
buffer
.
OutMessage
if
err
==
nil
{
b
=
o
.
op
.
kernelResponse
()
}
else
{
b
=
buffer
.
NewOutMessage
(
0
)
}
// Fill in the header if a reply is needed.
msg
:=
b
.
Bytes
()
if
msg
!=
nil
{
h
:=
b
.
OutHeader
()
h
.
Unique
=
o
.
fuseID
h
.
Len
=
uint32
(
len
(
msg
))
if
err
!=
nil
{
// If the user gave us a syscall.Errno, use that value in the reply.
// Otherwise use the generic EIO.
if
errno
,
ok
:=
err
.
(
syscall
.
Errno
);
ok
{
h
.
Error
=
-
int32
(
errno
)
}
else
{
h
.
Error
=
-
int32
(
syscall
.
EIO
)
}
}
}
// Reply.
replyErr
:=
o
.
sendReply
(
o
.
op
,
o
.
fuseID
,
msg
,
err
)
if
replyErr
!=
nil
&&
o
.
errorLogger
!=
nil
{
o
.
errorLogger
.
Printf
(
"Error from sendReply: %v"
,
replyErr
)
}
}
fuseops/doc.go
View file @
e7a97bf9
...
...
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package fuseops contains implementations of the fuse.Op interface that may
// be returned by fuse.Connection.ReadOp. See documentation in that package for
// more.
// Package fuseops contains ops that may be returned by fuse.Connection.ReadOp.
// See documentation in that package for more.
package
fuseops
fuseops/ops.go
View file @
e7a97bf9
...
...
@@ -15,24 +15,10 @@
package
fuseops
import
(
"fmt"
"os"
"time"
"github.com/jacobsa/fuse/internal/fusekernel"
)
// A common interface implemented by all ops in this package. Use a type switch
// to find particular concrete types, responding with fuse.ENOSYS if a type is
// not supported.
type
Op
interface
{
// A short description of the op, to be used in logging.
ShortDesc
()
string
// A long description of the op, to be used in debug logging.
DebugString
()
string
}
////////////////////////////////////////////////////////////////////////
// Inodes
////////////////////////////////////////////////////////////////////////
...
...
@@ -40,9 +26,6 @@ type Op interface {
// Look up a child by name within a parent directory. The kernel sends this
// when resolving user paths to dentry structs, which are then cached.
type
LookUpInodeOp
struct
{
commonOp
protocol
fusekernel
.
Protocol
// The ID of the directory inode to which the child belongs.
Parent
InodeID
...
...
@@ -64,19 +47,11 @@ type LookUpInodeOp struct {
Entry
ChildInodeEntry
}
func
(
o
*
LookUpInodeOp
)
ShortDesc
()
(
desc
string
)
{
desc
=
fmt
.
Sprintf
(
"LookUpInode(parent=%v, name=%q)"
,
o
.
Parent
,
o
.
Name
)
return
}
// Refresh the attributes for an inode whose ID was previously returned in a
// LookUpInodeOp. The kernel sends this when the FUSE VFS layer's cache of
// inode attributes is stale. This is controlled by the AttributesExpiration
// field of ChildInodeEntry, etc.
type
GetInodeAttributesOp
struct
{
commonOp
protocol
fusekernel
.
Protocol
// The inode of interest.
Inode
InodeID
...
...
@@ -87,22 +62,11 @@ type GetInodeAttributesOp struct {
AttributesExpiration
time
.
Time
}
func
(
o
*
GetInodeAttributesOp
)
DebugString
()
string
{
return
fmt
.
Sprintf
(
"Inode: %d, Exp: %v, Attr: %s"
,
o
.
Inode
,
o
.
AttributesExpiration
,
o
.
Attributes
.
DebugString
())
}
// Change attributes for an inode.
//
// The kernel sends this for obvious cases like chmod(2), and for less obvious
// cases like ftrunctate(2).
type
SetInodeAttributesOp
struct
{
commonOp
protocol
fusekernel
.
Protocol
// The inode of interest.
Inode
InodeID
...
...
@@ -159,8 +123,6 @@ type SetInodeAttributesOp struct {
// Rather they should take fuse.Connection.ReadOp returning io.EOF as
// implicitly decrementing all lookup counts to zero.
type
ForgetInodeOp
struct
{
commonOp
// The inode whose reference count should be decremented.
Inode
InodeID
...
...
@@ -184,9 +146,6 @@ type ForgetInodeOp struct {
//
// Therefore the file system should return EEXIST if the name already exists.
type
MkDirOp
struct
{
commonOp
protocol
fusekernel
.
Protocol
// The ID of parent directory inode within which to create the child.
Parent
InodeID
...
...
@@ -201,11 +160,6 @@ type MkDirOp struct {
Entry
ChildInodeEntry
}
func
(
o
*
MkDirOp
)
ShortDesc
()
(
desc
string
)
{
desc
=
fmt
.
Sprintf
(
"MkDir(parent=%v, name=%q)"
,
o
.
Parent
,
o
.
Name
)
return
}
// Create a file inode and open it.
//
// The kernel sends this when the user asks to open a file with the O_CREAT
...
...
@@ -217,9 +171,6 @@ func (o *MkDirOp) ShortDesc() (desc string) {
//
// Therefore the file system should return EEXIST if the name already exists.
type
CreateFileOp
struct
{
commonOp
protocol
fusekernel
.
Protocol
// The ID of parent directory inode within which to create the child file.
Parent
InodeID
...
...
@@ -244,17 +195,9 @@ type CreateFileOp struct {
Handle
HandleID
}
func
(
o
*
CreateFileOp
)
ShortDesc
()
(
desc
string
)
{
desc
=
fmt
.
Sprintf
(
"CreateFile(parent=%v, name=%q)"
,
o
.
Parent
,
o
.
Name
)
return
}
// Create a symlink inode. If the name already exists, the file system should
// return EEXIST (cf. the notes on CreateFileOp and MkDirOp).
type
CreateSymlinkOp
struct
{
commonOp
protocol
fusekernel
.
Protocol
// The ID of parent directory inode within which to create the child symlink.
Parent
InodeID
...
...
@@ -272,16 +215,6 @@ type CreateSymlinkOp struct {
Entry
ChildInodeEntry
}
func
(
o
*
CreateSymlinkOp
)
ShortDesc
()
(
desc
string
)
{
desc
=
fmt
.
Sprintf
(
"CreateSymlink(parent=%v, name=%q, target=%q)"
,
o
.
Parent
,
o
.
Name
,
o
.
Target
)
return
}
////////////////////////////////////////////////////////////////////////
// Unlinking
////////////////////////////////////////////////////////////////////////
...
...
@@ -321,8 +254,6 @@ func (o *CreateSymlinkOp) ShortDesc() (desc string) {
// about this.
//
type
RenameOp
struct
{
commonOp
// The old parent directory, and the name of the entry within it to be
// relocated.
OldParent
InodeID
...
...
@@ -342,8 +273,6 @@ type RenameOp struct {
//
// Sample implementation in ext2: ext2_rmdir (http://goo.gl/B9QmFf)
type
RmDirOp
struct
{
commonOp
// The ID of parent directory inode, and the name of the directory being
// removed within it.
Parent
InodeID
...
...
@@ -357,8 +286,6 @@ type RmDirOp struct {
//
// Sample implementation in ext2: ext2_unlink (http://goo.gl/hY6r6C)
type
UnlinkOp
struct
{
commonOp
// The ID of parent directory inode, and the name of the entry being removed
// within it.
Parent
InodeID
...
...
@@ -376,8 +303,6 @@ type UnlinkOp struct {
// user-space process. On OS X it may not be sent for every open(2) (cf.
// https://github.com/osxfuse/osxfuse/issues/199).
type
OpenDirOp
struct
{
commonOp
// The ID of the inode to be opened.
Inode
InodeID
...
...
@@ -394,8 +319,6 @@ type OpenDirOp struct {
// Read entries from a directory previously opened with OpenDir.
type
ReadDirOp
struct
{
commonOp
// The directory inode that we are reading, and the handle previously
// returned by OpenDir when opening that inode.
Inode
InodeID
...
...
@@ -491,8 +414,6 @@ type ReadDirOp struct {
//
// Errors from this op are ignored by the kernel (cf. http://goo.gl/RL38Do).
type
ReleaseDirHandleOp
struct
{
commonOp
// The handle ID to be released. The kernel guarantees that this ID will not
// be used in further calls to the file system (unless it is reissued by the
// file system).
...
...
@@ -510,8 +431,6 @@ type ReleaseDirHandleOp struct {
// process. On OS X it may not be sent for every open(2)
// (cf.https://github.com/osxfuse/osxfuse/issues/199).
type
OpenFileOp
struct
{
commonOp
// The ID of the inode to be opened.
Inode
InodeID
...
...
@@ -531,8 +450,6 @@ type OpenFileOp struct {
// some reads may be served by the page cache. See notes on WriteFileOp for
// more.
type
ReadFileOp
struct
{
commonOp
// The file inode that we are reading, and the handle previously returned by
// CreateFile or OpenFile when opening that inode.
Inode
InodeID
...
...
@@ -586,8 +503,6 @@ type ReadFileOp struct {
// (See also http://goo.gl/ocdTdM, fuse-devel thread "Fuse guarantees on
// concurrent requests".)
type
WriteFileOp
struct
{
commonOp
// The file inode that we are modifying, and the handle previously returned
// by CreateFile or OpenFile when opening that inode.
Inode
InodeID
...
...
@@ -641,8 +556,6 @@ type WriteFileOp struct {
// See also: FlushFileOp, which may perform a similar function when closing a
// file (but which is not used in "real" file systems).
type
SyncFileOp
struct
{
commonOp
// The file and handle being sync'd.
Inode
InodeID
Handle
HandleID
...
...
@@ -696,8 +609,6 @@ type SyncFileOp struct {
// to at least schedule a real flush, and maybe do it immediately in order to
// return any errors that occur.
type
FlushFileOp
struct
{
commonOp
// The file and handle being flushed.
Inode
InodeID
Handle
HandleID
...
...
@@ -712,35 +623,18 @@ type FlushFileOp struct {
//
// Errors from this op are ignored by the kernel (cf. http://goo.gl/RL38Do).
type
ReleaseFileHandleOp
struct
{
commonOp
// The handle ID to be released. The kernel guarantees that this ID will not
// be used in further calls to the file system (unless it is reissued by the
// file system).
Handle
HandleID
}
// A sentinel used for unknown ops. The user is expected to respond with a
// non-nil error.
type
unknownOp
struct
{
commonOp
opCode
uint32
inode
InodeID
}
func
(
o
*
unknownOp
)
ShortDesc
()
(
desc
string
)
{
desc
=
fmt
.
Sprintf
(
"<opcode %d>(inode=%v)"
,
o
.
opCode
,
o
.
inode
)
return
}
////////////////////////////////////////////////////////////////////////
// Reading symlinks
////////////////////////////////////////////////////////////////////////
// Read the target of a symlink inode.
type
ReadSymlinkOp
struct
{
commonOp
// The symlink inode that we are reading.
Inode
InodeID
...
...
fuseutil/file_system.go
View file @
e7a97bf9
...
...
@@ -29,8 +29,8 @@ import (
// loop" that switches on op types, instead receiving typed method calls
// directly.
//
// The FileSystem implementation should not call
Op.Respond, instead returning
// the error with which the caller should respond.
// The FileSystem implementation should not call
Connection.Reply, instead
//
returning
the error with which the caller should respond.
//
// See NotImplementedFileSystem for a convenient way to embed default
// implementations for methods you don't care about.
...
...
@@ -110,7 +110,7 @@ func (s *fileSystemServer) ServeOps(c *fuse.Connection) {
func
(
s
*
fileSystemServer
)
handleOp
(
c
*
fuse
.
Connection
,
ctx
context
.
Context
,
op
fuseops
.
Op
)
{
op
interface
{}
)
{
defer
s
.
opsInFlight
.
Done
()
// Dispatch to the appropriate method.
...
...
ops.go
View file @
e7a97bf9
...
...
@@ -28,7 +28,7 @@ import (
// response, return a nil response.
func
kernelResponse
(
fuseID
uint64
,
op
fuseops
.
Op
,
op
interface
{}
,
opErr
error
,
protocol
fusekernel
.
Protocol
)
(
msg
[]
byte
)
{
// If the user replied with an error, create room enough just for the result
...
...
@@ -59,7 +59,7 @@ func kernelResponse(
// Like kernelResponse, but assumes the user replied with a nil error to the
// op.
func
kernelResponseForOp
(
op
fuseops
.
Op
,
op
interface
{}
,
protocol
fusekernel
.
Protocol
)
(
b
buffer
.
OutMessage
)
{
// Create the appropriate output message
switch
o
:=
op
.
(
type
)
{
...
...
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