Commit f4231ede authored by Aaron Jacobs's avatar Aaron Jacobs

Copied over the juicy bits of bazilfuse, and made them work.

parents df9f2b75 aa32dd92
...@@ -23,15 +23,15 @@ import ( ...@@ -23,15 +23,15 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"github.com/jacobsa/bazilfuse"
"github.com/jacobsa/fuse/fuseops" "github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/internal/fuseshim"
) )
// A connection to the fuse kernel process. // A connection to the fuse kernel process.
type Connection struct { type Connection struct {
debugLogger *log.Logger debugLogger *log.Logger
errorLogger *log.Logger errorLogger *log.Logger
wrapped *bazilfuse.Conn wrapped *fuseshim.Conn
// The context from which all op contexts inherit. // The context from which all op contexts inherit.
parentCtx context.Context parentCtx context.Context
...@@ -41,11 +41,11 @@ type Connection struct { ...@@ -41,11 +41,11 @@ type Connection struct {
mu sync.Mutex mu sync.Mutex
// A map from bazilfuse request ID (*not* the op ID for logging used above) // A map from fuseshim request ID (*not* the op ID for logging used above) to
// to a function that cancel's its associated context. // a function that cancel's its associated context.
// //
// GUARDED_BY(mu) // GUARDED_BY(mu)
cancelFuncs map[bazilfuse.RequestID]func() cancelFuncs map[fuseshim.RequestID]func()
} }
// Responsibility for closing the wrapped connection is transferred to the // Responsibility for closing the wrapped connection is transferred to the
...@@ -56,13 +56,13 @@ func newConnection( ...@@ -56,13 +56,13 @@ func newConnection(
parentCtx context.Context, parentCtx context.Context,
debugLogger *log.Logger, debugLogger *log.Logger,
errorLogger *log.Logger, errorLogger *log.Logger,
wrapped *bazilfuse.Conn) (c *Connection, err error) { wrapped *fuseshim.Conn) (c *Connection, err error) {
c = &Connection{ c = &Connection{
debugLogger: debugLogger, debugLogger: debugLogger,
errorLogger: errorLogger, errorLogger: errorLogger,
wrapped: wrapped, wrapped: wrapped,
parentCtx: parentCtx, parentCtx: parentCtx,
cancelFuncs: make(map[bazilfuse.RequestID]func()), cancelFuncs: make(map[fuseshim.RequestID]func()),
} }
return return
...@@ -104,7 +104,7 @@ func (c *Connection) debugLog( ...@@ -104,7 +104,7 @@ func (c *Connection) debugLog(
// LOCKS_EXCLUDED(c.mu) // LOCKS_EXCLUDED(c.mu)
func (c *Connection) recordCancelFunc( func (c *Connection) recordCancelFunc(
reqID bazilfuse.RequestID, reqID fuseshim.RequestID,
f func()) { f func()) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
...@@ -117,13 +117,13 @@ func (c *Connection) recordCancelFunc( ...@@ -117,13 +117,13 @@ func (c *Connection) recordCancelFunc(
} }
// Set up state for an op that is about to be returned to the user, given its // Set up state for an op that is about to be returned to the user, given its
// underlying bazilfuse request. // underlying fuseshim request.
// //
// Return a context that should be used for the op. // Return a context that should be used for the op.
// //
// LOCKS_EXCLUDED(c.mu) // LOCKS_EXCLUDED(c.mu)
func (c *Connection) beginOp( func (c *Connection) beginOp(
bfReq bazilfuse.Request) (ctx context.Context) { bfReq fuseshim.Request) (ctx context.Context) {
reqID := bfReq.Hdr().ID reqID := bfReq.Hdr().ID
// Start with the parent context. // Start with the parent context.
...@@ -137,7 +137,7 @@ func (c *Connection) beginOp( ...@@ -137,7 +137,7 @@ func (c *Connection) beginOp(
// should not record any state keyed on their ID. // should not record any state keyed on their ID.
// //
// Cf. https://github.com/osxfuse/osxfuse/issues/208 // Cf. https://github.com/osxfuse/osxfuse/issues/208
if _, ok := bfReq.(*bazilfuse.ForgetRequest); !ok { if _, ok := bfReq.(*fuseshim.ForgetRequest); !ok {
var cancel func() var cancel func()
ctx, cancel = context.WithCancel(ctx) ctx, cancel = context.WithCancel(ctx)
c.recordCancelFunc(reqID, cancel) c.recordCancelFunc(reqID, cancel)
...@@ -147,12 +147,12 @@ func (c *Connection) beginOp( ...@@ -147,12 +147,12 @@ func (c *Connection) beginOp(
} }
// Clean up all state associated with an op to which the user has responded, // Clean up all state associated with an op to which the user has responded,
// given its underlying bazilfuse request. This must be called before a // given its underlying fuseshim request. This must be called before a response
// response is sent to the kernel, to avoid a race where the request's ID might // is sent to the kernel, to avoid a race where the request's ID might be
// be reused by osxfuse. // reused by osxfuse.
// //
// LOCKS_EXCLUDED(c.mu) // LOCKS_EXCLUDED(c.mu)
func (c *Connection) finishOp(bfReq bazilfuse.Request) { func (c *Connection) finishOp(bfReq fuseshim.Request) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
...@@ -164,7 +164,7 @@ func (c *Connection) finishOp(bfReq bazilfuse.Request) { ...@@ -164,7 +164,7 @@ func (c *Connection) finishOp(bfReq bazilfuse.Request) {
// //
// Special case: we don't do this for Forget requests. See the note in // Special case: we don't do this for Forget requests. See the note in
// beginOp above. // beginOp above.
if _, ok := bfReq.(*bazilfuse.ForgetRequest); !ok { if _, ok := bfReq.(*fuseshim.ForgetRequest); !ok {
cancel, ok := c.cancelFuncs[reqID] cancel, ok := c.cancelFuncs[reqID]
if !ok { if !ok {
panic(fmt.Sprintf("Unknown request ID in finishOp: %v", reqID)) panic(fmt.Sprintf("Unknown request ID in finishOp: %v", reqID))
...@@ -176,7 +176,7 @@ func (c *Connection) finishOp(bfReq bazilfuse.Request) { ...@@ -176,7 +176,7 @@ func (c *Connection) finishOp(bfReq bazilfuse.Request) {
} }
// LOCKS_EXCLUDED(c.mu) // LOCKS_EXCLUDED(c.mu)
func (c *Connection) handleInterrupt(req *bazilfuse.InterruptRequest) { func (c *Connection) handleInterrupt(req *fuseshim.InterruptRequest) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
...@@ -212,8 +212,8 @@ func (c *Connection) handleInterrupt(req *bazilfuse.InterruptRequest) { ...@@ -212,8 +212,8 @@ func (c *Connection) handleInterrupt(req *bazilfuse.InterruptRequest) {
func (c *Connection) ReadOp() (op fuseops.Op, err error) { func (c *Connection) ReadOp() (op fuseops.Op, err error) {
// Keep going until we find a request we know how to convert. // Keep going until we find a request we know how to convert.
for { for {
// Read a bazilfuse request. // Read a fuseshim request.
var bfReq bazilfuse.Request var bfReq fuseshim.Request
bfReq, err = c.wrapped.ReadRequest() bfReq, err = c.wrapped.ReadRequest()
if err != nil { if err != nil {
...@@ -230,14 +230,14 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) { ...@@ -230,14 +230,14 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
// Special case: responding to statfs is required to make mounting work on // Special case: responding to statfs is required to make mounting work on
// OS X. We don't currently expose the capability for the file system to // OS X. We don't currently expose the capability for the file system to
// intercept this. // intercept this.
if statfsReq, ok := bfReq.(*bazilfuse.StatfsRequest); ok { if statfsReq, ok := bfReq.(*fuseshim.StatfsRequest); ok {
c.debugLog(opID, 1, "-> (Statfs) OK") c.debugLog(opID, 1, "-> (Statfs) OK")
statfsReq.Respond(&bazilfuse.StatfsResponse{}) statfsReq.Respond(&fuseshim.StatfsResponse{})
continue continue
} }
// Special case: handle interrupt requests. // Special case: handle interrupt requests.
if interruptReq, ok := bfReq.(*bazilfuse.InterruptRequest); ok { if interruptReq, ok := bfReq.(*fuseshim.InterruptRequest); ok {
c.handleInterrupt(interruptReq) c.handleInterrupt(interruptReq)
continue continue
} }
......
...@@ -17,17 +17,17 @@ package fuse ...@@ -17,17 +17,17 @@ package fuse
import ( import (
"syscall" "syscall"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/fuse/internal/fuseshim"
) )
const ( const (
// Errors corresponding to kernel error numbers. These may be treated // Errors corresponding to kernel error numbers. These may be treated
// specially by fuseops.Op.Respond methods. // specially by fuseops.Op.Respond methods.
EEXIST = bazilfuse.EEXIST EEXIST = fuseshim.EEXIST
EINVAL = bazilfuse.Errno(syscall.EINVAL) EINVAL = fuseshim.Errno(syscall.EINVAL)
EIO = bazilfuse.EIO EIO = fuseshim.EIO
ENOENT = bazilfuse.ENOENT ENOENT = fuseshim.ENOENT
ENOSYS = bazilfuse.ENOSYS ENOSYS = fuseshim.ENOSYS
ENOTDIR = bazilfuse.Errno(syscall.ENOTDIR) ENOTDIR = fuseshim.Errno(syscall.ENOTDIR)
ENOTEMPTY = bazilfuse.Errno(syscall.ENOTEMPTY) ENOTEMPTY = fuseshim.Errno(syscall.ENOTEMPTY)
) )
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/fuse/internal/fuseshim"
"github.com/jacobsa/reqtrace" "github.com/jacobsa/reqtrace"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
type internalOp interface { type internalOp interface {
Op Op
// Respond to the underlying bazilfuse request, successfully. // Respond to the underlying fuseshim request, successfully.
respond() respond()
} }
...@@ -42,8 +42,8 @@ type commonOp struct { ...@@ -42,8 +42,8 @@ type commonOp struct {
// The op in which this struct is embedded. // The op in which this struct is embedded.
op internalOp op internalOp
// The underlying bazilfuse request for this op. // The underlying fuseshim request for this op.
bazilReq bazilfuse.Request bazilReq fuseshim.Request
// A function that can be used to log debug information about the op. The // A function that can be used to log debug information about the op. The
// first argument is a call depth. // first argument is a call depth.
...@@ -81,7 +81,7 @@ func (o *commonOp) ShortDesc() (desc string) { ...@@ -81,7 +81,7 @@ func (o *commonOp) ShortDesc() (desc string) {
func (o *commonOp) init( func (o *commonOp) init(
ctx context.Context, ctx context.Context,
op internalOp, op internalOp,
bazilReq bazilfuse.Request, bazilReq fuseshim.Request,
debugLog func(int, string, ...interface{}), debugLog func(int, string, ...interface{}),
errorLogger *log.Logger, errorLogger *log.Logger,
finished func(error)) { finished func(error)) {
...@@ -122,7 +122,7 @@ func (o *commonOp) Respond(err error) { ...@@ -122,7 +122,7 @@ func (o *commonOp) Respond(err error) {
// Report that the user is responding. // Report that the user is responding.
o.finished(err) o.finished(err)
// If successful, we should respond to bazilfuse with the appropriate struct. // If successful, we should respond to fuseshim with the appropriate struct.
if err == nil { if err == nil {
o.op.respond() o.op.respond()
return return
......
...@@ -18,15 +18,15 @@ import ( ...@@ -18,15 +18,15 @@ import (
"log" "log"
"time" "time"
"github.com/jacobsa/fuse/internal/fusekernel"
"github.com/jacobsa/fuse/internal/fuseshim"
"golang.org/x/net/context" "golang.org/x/net/context"
"github.com/jacobsa/bazilfuse"
) )
// This function is an implementation detail of the fuse package, and must not // This function is an implementation detail of the fuse package, and must not
// be called by anyone else. // be called by anyone else.
// //
// Convert the supplied bazilfuse request struct to an Op. finished will be // Convert the supplied fuseshim request struct to an Op. finished will be
// called with the error supplied to o.Respond when the user invokes that // called with the error supplied to o.Respond when the user invokes that
// method, before a response is sent to the kernel. // method, before a response is sent to the kernel.
// //
...@@ -36,7 +36,7 @@ import ( ...@@ -36,7 +36,7 @@ import (
// The debug logging function and error logger may be nil. // The debug logging function and error logger may be nil.
func Convert( func Convert(
opCtx context.Context, opCtx context.Context,
r bazilfuse.Request, r fuseshim.Request,
debugLogForOp func(int, string, ...interface{}), debugLogForOp func(int, string, ...interface{}),
errorLogger *log.Logger, errorLogger *log.Logger,
finished func(error)) (o Op) { finished func(error)) (o Op) {
...@@ -44,7 +44,7 @@ func Convert( ...@@ -44,7 +44,7 @@ func Convert(
var io internalOp var io internalOp
switch typed := r.(type) { switch typed := r.(type) {
case *bazilfuse.LookupRequest: case *fuseshim.LookupRequest:
to := &LookUpInodeOp{ to := &LookUpInodeOp{
bfReq: typed, bfReq: typed,
Parent: InodeID(typed.Header.Node), Parent: InodeID(typed.Header.Node),
...@@ -53,7 +53,7 @@ func Convert( ...@@ -53,7 +53,7 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.GetattrRequest: case *fuseshim.GetattrRequest:
to := &GetInodeAttributesOp{ to := &GetInodeAttributesOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
...@@ -61,32 +61,32 @@ func Convert( ...@@ -61,32 +61,32 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.SetattrRequest: case *fuseshim.SetattrRequest:
to := &SetInodeAttributesOp{ to := &SetInodeAttributesOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
} }
if typed.Valid&bazilfuse.SetattrSize != 0 { if typed.Valid&fusekernel.SetattrSize != 0 {
to.Size = &typed.Size to.Size = &typed.Size
} }
if typed.Valid&bazilfuse.SetattrMode != 0 { if typed.Valid&fusekernel.SetattrMode != 0 {
to.Mode = &typed.Mode to.Mode = &typed.Mode
} }
if typed.Valid&bazilfuse.SetattrAtime != 0 { if typed.Valid&fusekernel.SetattrAtime != 0 {
to.Atime = &typed.Atime to.Atime = &typed.Atime
} }
if typed.Valid&bazilfuse.SetattrMtime != 0 { if typed.Valid&fusekernel.SetattrMtime != 0 {
to.Mtime = &typed.Mtime to.Mtime = &typed.Mtime
} }
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.ForgetRequest: case *fuseshim.ForgetRequest:
to := &ForgetInodeOp{ to := &ForgetInodeOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
...@@ -95,7 +95,7 @@ func Convert( ...@@ -95,7 +95,7 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.MkdirRequest: case *fuseshim.MkdirRequest:
to := &MkDirOp{ to := &MkDirOp{
bfReq: typed, bfReq: typed,
Parent: InodeID(typed.Header.Node), Parent: InodeID(typed.Header.Node),
...@@ -105,18 +105,17 @@ func Convert( ...@@ -105,18 +105,17 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.CreateRequest: case *fuseshim.CreateRequest:
to := &CreateFileOp{ to := &CreateFileOp{
bfReq: typed, bfReq: typed,
Parent: InodeID(typed.Header.Node), Parent: InodeID(typed.Header.Node),
Name: typed.Name, Name: typed.Name,
Mode: typed.Mode, Mode: typed.Mode,
Flags: typed.Flags,
} }
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.SymlinkRequest: case *fuseshim.SymlinkRequest:
to := &CreateSymlinkOp{ to := &CreateSymlinkOp{
bfReq: typed, bfReq: typed,
Parent: InodeID(typed.Header.Node), Parent: InodeID(typed.Header.Node),
...@@ -126,7 +125,7 @@ func Convert( ...@@ -126,7 +125,7 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.RenameRequest: case *fuseshim.RenameRequest:
to := &RenameOp{ to := &RenameOp{
bfReq: typed, bfReq: typed,
OldParent: InodeID(typed.Header.Node), OldParent: InodeID(typed.Header.Node),
...@@ -137,7 +136,7 @@ func Convert( ...@@ -137,7 +136,7 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.RemoveRequest: case *fuseshim.RemoveRequest:
if typed.Dir { if typed.Dir {
to := &RmDirOp{ to := &RmDirOp{
bfReq: typed, bfReq: typed,
...@@ -156,12 +155,11 @@ func Convert( ...@@ -156,12 +155,11 @@ func Convert(
co = &to.commonOp co = &to.commonOp
} }
case *bazilfuse.OpenRequest: case *fuseshim.OpenRequest:
if typed.Dir { if typed.Dir {
to := &OpenDirOp{ to := &OpenDirOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
Flags: typed.Flags,
} }
io = to io = to
co = &to.commonOp co = &to.commonOp
...@@ -169,13 +167,12 @@ func Convert( ...@@ -169,13 +167,12 @@ func Convert(
to := &OpenFileOp{ to := &OpenFileOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
Flags: typed.Flags,
} }
io = to io = to
co = &to.commonOp co = &to.commonOp
} }
case *bazilfuse.ReadRequest: case *fuseshim.ReadRequest:
if typed.Dir { if typed.Dir {
to := &ReadDirOp{ to := &ReadDirOp{
bfReq: typed, bfReq: typed,
...@@ -198,7 +195,7 @@ func Convert( ...@@ -198,7 +195,7 @@ func Convert(
co = &to.commonOp co = &to.commonOp
} }
case *bazilfuse.ReleaseRequest: case *fuseshim.ReleaseRequest:
if typed.Dir { if typed.Dir {
to := &ReleaseDirHandleOp{ to := &ReleaseDirHandleOp{
bfReq: typed, bfReq: typed,
...@@ -215,7 +212,7 @@ func Convert( ...@@ -215,7 +212,7 @@ func Convert(
co = &to.commonOp co = &to.commonOp
} }
case *bazilfuse.WriteRequest: case *fuseshim.WriteRequest:
to := &WriteFileOp{ to := &WriteFileOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
...@@ -226,7 +223,7 @@ func Convert( ...@@ -226,7 +223,7 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.FsyncRequest: case *fuseshim.FsyncRequest:
// We don't currently support this for directories. // We don't currently support this for directories.
if typed.Dir { if typed.Dir {
to := &unknownOp{} to := &unknownOp{}
...@@ -242,7 +239,7 @@ func Convert( ...@@ -242,7 +239,7 @@ func Convert(
co = &to.commonOp co = &to.commonOp
} }
case *bazilfuse.FlushRequest: case *fuseshim.FlushRequest:
to := &FlushFileOp{ to := &FlushFileOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
...@@ -251,7 +248,7 @@ func Convert( ...@@ -251,7 +248,7 @@ func Convert(
io = to io = to
co = &to.commonOp co = &to.commonOp
case *bazilfuse.ReadlinkRequest: case *fuseshim.ReadlinkRequest:
to := &ReadSymlinkOp{ to := &ReadSymlinkOp{
bfReq: typed, bfReq: typed,
Inode: InodeID(typed.Header.Node), Inode: InodeID(typed.Header.Node),
...@@ -280,8 +277,8 @@ func Convert( ...@@ -280,8 +277,8 @@ func Convert(
func convertAttributes( func convertAttributes(
inode InodeID, inode InodeID,
attr InodeAttributes, attr InodeAttributes,
expiration time.Time) bazilfuse.Attr { expiration time.Time) fuseshim.Attr {
return bazilfuse.Attr{ return fuseshim.Attr{
Inode: uint64(inode), Inode: uint64(inode),
Size: attr.Size, Size: attr.Size,
Mode: attr.Mode, Mode: attr.Mode,
...@@ -317,8 +314,8 @@ func convertExpirationTime(t time.Time) (d time.Duration) { ...@@ -317,8 +314,8 @@ func convertExpirationTime(t time.Time) (d time.Duration) {
func convertChildInodeEntry( func convertChildInodeEntry(
in *ChildInodeEntry, in *ChildInodeEntry,
out *bazilfuse.LookupResponse) { out *fuseshim.LookupResponse) {
out.Node = bazilfuse.NodeID(in.Child) out.Node = fuseshim.NodeID(in.Child)
out.Generation = uint64(in.Generation) out.Generation = uint64(in.Generation)
out.Attr = convertAttributes(in.Child, in.Attributes, in.AttributesExpiration) out.Attr = convertAttributes(in.Child, in.Attributes, in.AttributesExpiration)
out.EntryValid = convertExpirationTime(in.EntryExpiration) out.EntryValid = convertExpirationTime(in.EntryExpiration)
......
...@@ -19,7 +19,7 @@ import ( ...@@ -19,7 +19,7 @@ import (
"os" "os"
"time" "time"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/fuse/internal/fuseshim"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
...@@ -55,7 +55,7 @@ type Op interface { ...@@ -55,7 +55,7 @@ type Op interface {
// when resolving user paths to dentry structs, which are then cached. // when resolving user paths to dentry structs, which are then cached.
type LookUpInodeOp struct { type LookUpInodeOp struct {
commonOp commonOp
bfReq *bazilfuse.LookupRequest bfReq *fuseshim.LookupRequest
// The ID of the directory inode to which the child belongs. // The ID of the directory inode to which the child belongs.
Parent InodeID Parent InodeID
...@@ -84,7 +84,7 @@ func (o *LookUpInodeOp) ShortDesc() (desc string) { ...@@ -84,7 +84,7 @@ func (o *LookUpInodeOp) ShortDesc() (desc string) {
} }
func (o *LookUpInodeOp) respond() { func (o *LookUpInodeOp) respond() {
resp := bazilfuse.LookupResponse{} resp := fuseshim.LookupResponse{}
convertChildInodeEntry(&o.Entry, &resp) convertChildInodeEntry(&o.Entry, &resp)
o.bfReq.Respond(&resp) o.bfReq.Respond(&resp)
...@@ -97,7 +97,7 @@ func (o *LookUpInodeOp) respond() { ...@@ -97,7 +97,7 @@ func (o *LookUpInodeOp) respond() {
// field of ChildInodeEntry, etc. // field of ChildInodeEntry, etc.
type GetInodeAttributesOp struct { type GetInodeAttributesOp struct {
commonOp commonOp
bfReq *bazilfuse.GetattrRequest bfReq *fuseshim.GetattrRequest
// The inode of interest. // The inode of interest.
Inode InodeID Inode InodeID
...@@ -110,7 +110,7 @@ type GetInodeAttributesOp struct { ...@@ -110,7 +110,7 @@ type GetInodeAttributesOp struct {
} }
func (o *GetInodeAttributesOp) respond() { func (o *GetInodeAttributesOp) respond() {
resp := bazilfuse.GetattrResponse{ resp := fuseshim.GetattrResponse{
Attr: convertAttributes(o.Inode, o.Attributes, o.AttributesExpiration), Attr: convertAttributes(o.Inode, o.Attributes, o.AttributesExpiration),
} }
...@@ -124,7 +124,7 @@ func (o *GetInodeAttributesOp) respond() { ...@@ -124,7 +124,7 @@ func (o *GetInodeAttributesOp) respond() {
// cases like ftrunctate(2). // cases like ftrunctate(2).
type SetInodeAttributesOp struct { type SetInodeAttributesOp struct {
commonOp commonOp
bfReq *bazilfuse.SetattrRequest bfReq *fuseshim.SetattrRequest
// The inode of interest. // The inode of interest.
Inode InodeID Inode InodeID
...@@ -143,7 +143,7 @@ type SetInodeAttributesOp struct { ...@@ -143,7 +143,7 @@ type SetInodeAttributesOp struct {
} }
func (o *SetInodeAttributesOp) respond() { func (o *SetInodeAttributesOp) respond() {
resp := bazilfuse.SetattrResponse{ resp := fuseshim.SetattrResponse{
Attr: convertAttributes(o.Inode, o.Attributes, o.AttributesExpiration), Attr: convertAttributes(o.Inode, o.Attributes, o.AttributesExpiration),
} }
...@@ -192,7 +192,7 @@ func (o *SetInodeAttributesOp) respond() { ...@@ -192,7 +192,7 @@ func (o *SetInodeAttributesOp) respond() {
// implicitly decrementing all lookup counts to zero. // implicitly decrementing all lookup counts to zero.
type ForgetInodeOp struct { type ForgetInodeOp struct {
commonOp commonOp
bfReq *bazilfuse.ForgetRequest bfReq *fuseshim.ForgetRequest
// The inode whose reference count should be decremented. // The inode whose reference count should be decremented.
Inode InodeID Inode InodeID
...@@ -223,7 +223,7 @@ func (o *ForgetInodeOp) respond() { ...@@ -223,7 +223,7 @@ func (o *ForgetInodeOp) respond() {
// Therefore the file system should return EEXIST if the name already exists. // Therefore the file system should return EEXIST if the name already exists.
type MkDirOp struct { type MkDirOp struct {
commonOp commonOp
bfReq *bazilfuse.MkdirRequest bfReq *fuseshim.MkdirRequest
// The ID of parent directory inode within which to create the child. // The ID of parent directory inode within which to create the child.
Parent InodeID Parent InodeID
...@@ -245,7 +245,7 @@ func (o *MkDirOp) ShortDesc() (desc string) { ...@@ -245,7 +245,7 @@ func (o *MkDirOp) ShortDesc() (desc string) {
} }
func (o *MkDirOp) respond() { func (o *MkDirOp) respond() {
resp := bazilfuse.MkdirResponse{} resp := fuseshim.MkdirResponse{}
convertChildInodeEntry(&o.Entry, &resp.LookupResponse) convertChildInodeEntry(&o.Entry, &resp.LookupResponse)
o.bfReq.Respond(&resp) o.bfReq.Respond(&resp)
...@@ -264,7 +264,7 @@ func (o *MkDirOp) respond() { ...@@ -264,7 +264,7 @@ func (o *MkDirOp) respond() {
// Therefore the file system should return EEXIST if the name already exists. // Therefore the file system should return EEXIST if the name already exists.
type CreateFileOp struct { type CreateFileOp struct {
commonOp commonOp
bfReq *bazilfuse.CreateRequest bfReq *fuseshim.CreateRequest
// The ID of parent directory inode within which to create the child file. // The ID of parent directory inode within which to create the child file.
Parent InodeID Parent InodeID
...@@ -273,9 +273,6 @@ type CreateFileOp struct { ...@@ -273,9 +273,6 @@ type CreateFileOp struct {
Name string Name string
Mode os.FileMode Mode os.FileMode
// Flags for the open operation.
Flags bazilfuse.OpenFlags
// Set by the file system: information about the inode that was created. // Set by the file system: information about the inode that was created.
// //
// The lookup count for the inode is implicitly incremented. See notes on // The lookup count for the inode is implicitly incremented. See notes on
...@@ -299,9 +296,9 @@ func (o *CreateFileOp) ShortDesc() (desc string) { ...@@ -299,9 +296,9 @@ func (o *CreateFileOp) ShortDesc() (desc string) {
} }
func (o *CreateFileOp) respond() { func (o *CreateFileOp) respond() {
resp := bazilfuse.CreateResponse{ resp := fuseshim.CreateResponse{
OpenResponse: bazilfuse.OpenResponse{ OpenResponse: fuseshim.OpenResponse{
Handle: bazilfuse.HandleID(o.Handle), Handle: fuseshim.HandleID(o.Handle),
}, },
} }
...@@ -315,7 +312,7 @@ func (o *CreateFileOp) respond() { ...@@ -315,7 +312,7 @@ func (o *CreateFileOp) respond() {
// return EEXIST (cf. the notes on CreateFileOp and MkDirOp). // return EEXIST (cf. the notes on CreateFileOp and MkDirOp).
type CreateSymlinkOp struct { type CreateSymlinkOp struct {
commonOp commonOp
bfReq *bazilfuse.SymlinkRequest bfReq *fuseshim.SymlinkRequest
// The ID of parent directory inode within which to create the child symlink. // The ID of parent directory inode within which to create the child symlink.
Parent InodeID Parent InodeID
...@@ -345,7 +342,7 @@ func (o *CreateSymlinkOp) ShortDesc() (desc string) { ...@@ -345,7 +342,7 @@ func (o *CreateSymlinkOp) ShortDesc() (desc string) {
} }
func (o *CreateSymlinkOp) respond() { func (o *CreateSymlinkOp) respond() {
resp := bazilfuse.SymlinkResponse{} resp := fuseshim.SymlinkResponse{}
convertChildInodeEntry(&o.Entry, &resp.LookupResponse) convertChildInodeEntry(&o.Entry, &resp.LookupResponse)
o.bfReq.Respond(&resp) o.bfReq.Respond(&resp)
...@@ -392,7 +389,7 @@ func (o *CreateSymlinkOp) respond() { ...@@ -392,7 +389,7 @@ func (o *CreateSymlinkOp) respond() {
// //
type RenameOp struct { type RenameOp struct {
commonOp commonOp
bfReq *bazilfuse.RenameRequest bfReq *fuseshim.RenameRequest
// The old parent directory, and the name of the entry within it to be // The old parent directory, and the name of the entry within it to be
// relocated. // relocated.
...@@ -419,7 +416,7 @@ func (o *RenameOp) respond() { ...@@ -419,7 +416,7 @@ func (o *RenameOp) respond() {
// Sample implementation in ext2: ext2_rmdir (http://goo.gl/B9QmFf) // Sample implementation in ext2: ext2_rmdir (http://goo.gl/B9QmFf)
type RmDirOp struct { type RmDirOp struct {
commonOp commonOp
bfReq *bazilfuse.RemoveRequest bfReq *fuseshim.RemoveRequest
// The ID of parent directory inode, and the name of the directory being // The ID of parent directory inode, and the name of the directory being
// removed within it. // removed within it.
...@@ -440,7 +437,7 @@ func (o *RmDirOp) respond() { ...@@ -440,7 +437,7 @@ func (o *RmDirOp) respond() {
// Sample implementation in ext2: ext2_unlink (http://goo.gl/hY6r6C) // Sample implementation in ext2: ext2_unlink (http://goo.gl/hY6r6C)
type UnlinkOp struct { type UnlinkOp struct {
commonOp commonOp
bfReq *bazilfuse.RemoveRequest bfReq *fuseshim.RemoveRequest
// The ID of parent directory inode, and the name of the entry being removed // The ID of parent directory inode, and the name of the entry being removed
// within it. // within it.
...@@ -465,14 +462,11 @@ func (o *UnlinkOp) respond() { ...@@ -465,14 +462,11 @@ func (o *UnlinkOp) respond() {
// https://github.com/osxfuse/osxfuse/issues/199). // https://github.com/osxfuse/osxfuse/issues/199).
type OpenDirOp struct { type OpenDirOp struct {
commonOp commonOp
bfReq *bazilfuse.OpenRequest bfReq *fuseshim.OpenRequest
// The ID of the inode to be opened. // The ID of the inode to be opened.
Inode InodeID Inode InodeID
// Mode and options flags.
Flags bazilfuse.OpenFlags
// Set by the file system: an opaque ID that will be echoed in follow-up // Set by the file system: an opaque ID that will be echoed in follow-up
// calls for this directory using the same struct file in the kernel. In // calls for this directory using the same struct file in the kernel. In
// practice this usually means follow-up calls using the file descriptor // practice this usually means follow-up calls using the file descriptor
...@@ -485,8 +479,8 @@ type OpenDirOp struct { ...@@ -485,8 +479,8 @@ type OpenDirOp struct {
} }
func (o *OpenDirOp) respond() { func (o *OpenDirOp) respond() {
resp := bazilfuse.OpenResponse{ resp := fuseshim.OpenResponse{
Handle: bazilfuse.HandleID(o.Handle), Handle: fuseshim.HandleID(o.Handle),
} }
o.bfReq.Respond(&resp) o.bfReq.Respond(&resp)
...@@ -496,7 +490,7 @@ func (o *OpenDirOp) respond() { ...@@ -496,7 +490,7 @@ func (o *OpenDirOp) respond() {
// Read entries from a directory previously opened with OpenDir. // Read entries from a directory previously opened with OpenDir.
type ReadDirOp struct { type ReadDirOp struct {
commonOp commonOp
bfReq *bazilfuse.ReadRequest bfReq *fuseshim.ReadRequest
// The directory inode that we are reading, and the handle previously // The directory inode that we are reading, and the handle previously
// returned by OpenDir when opening that inode. // returned by OpenDir when opening that inode.
...@@ -585,7 +579,7 @@ type ReadDirOp struct { ...@@ -585,7 +579,7 @@ type ReadDirOp struct {
} }
func (o *ReadDirOp) respond() { func (o *ReadDirOp) respond() {
resp := bazilfuse.ReadResponse{ resp := fuseshim.ReadResponse{
Data: o.Data, Data: o.Data,
} }
...@@ -603,7 +597,7 @@ func (o *ReadDirOp) respond() { ...@@ -603,7 +597,7 @@ func (o *ReadDirOp) respond() {
// Errors from this op are ignored by the kernel (cf. http://goo.gl/RL38Do). // Errors from this op are ignored by the kernel (cf. http://goo.gl/RL38Do).
type ReleaseDirHandleOp struct { type ReleaseDirHandleOp struct {
commonOp commonOp
bfReq *bazilfuse.ReleaseRequest bfReq *fuseshim.ReleaseRequest
// The handle ID to be released. The kernel guarantees that this ID will not // 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 // be used in further calls to the file system (unless it is reissued by the
...@@ -628,14 +622,11 @@ func (o *ReleaseDirHandleOp) respond() { ...@@ -628,14 +622,11 @@ func (o *ReleaseDirHandleOp) respond() {
// (cf.https://github.com/osxfuse/osxfuse/issues/199). // (cf.https://github.com/osxfuse/osxfuse/issues/199).
type OpenFileOp struct { type OpenFileOp struct {
commonOp commonOp
bfReq *bazilfuse.OpenRequest bfReq *fuseshim.OpenRequest
// The ID of the inode to be opened. // The ID of the inode to be opened.
Inode InodeID Inode InodeID
// Mode and options flags.
Flags bazilfuse.OpenFlags
// An opaque ID that will be echoed in follow-up calls for this file using // An opaque ID that will be echoed in follow-up calls for this file using
// the same struct file in the kernel. In practice this usually means // the same struct file in the kernel. In practice this usually means
// follow-up calls using the file descriptor returned by open(2). // follow-up calls using the file descriptor returned by open(2).
...@@ -647,8 +638,8 @@ type OpenFileOp struct { ...@@ -647,8 +638,8 @@ type OpenFileOp struct {
} }
func (o *OpenFileOp) respond() { func (o *OpenFileOp) respond() {
resp := bazilfuse.OpenResponse{ resp := fuseshim.OpenResponse{
Handle: bazilfuse.HandleID(o.Handle), Handle: fuseshim.HandleID(o.Handle),
} }
o.bfReq.Respond(&resp) o.bfReq.Respond(&resp)
...@@ -662,7 +653,7 @@ func (o *OpenFileOp) respond() { ...@@ -662,7 +653,7 @@ func (o *OpenFileOp) respond() {
// more. // more.
type ReadFileOp struct { type ReadFileOp struct {
commonOp commonOp
bfReq *bazilfuse.ReadRequest bfReq *fuseshim.ReadRequest
// The file inode that we are reading, and the handle previously returned by // The file inode that we are reading, and the handle previously returned by
// CreateFile or OpenFile when opening that inode. // CreateFile or OpenFile when opening that inode.
...@@ -686,7 +677,7 @@ type ReadFileOp struct { ...@@ -686,7 +677,7 @@ type ReadFileOp struct {
} }
func (o *ReadFileOp) respond() { func (o *ReadFileOp) respond() {
resp := bazilfuse.ReadResponse{ resp := fuseshim.ReadResponse{
Data: o.Data, Data: o.Data,
} }
...@@ -727,7 +718,7 @@ func (o *ReadFileOp) respond() { ...@@ -727,7 +718,7 @@ func (o *ReadFileOp) respond() {
// concurrent requests".) // concurrent requests".)
type WriteFileOp struct { type WriteFileOp struct {
commonOp commonOp
bfReq *bazilfuse.WriteRequest bfReq *fuseshim.WriteRequest
// The file inode that we are modifying, and the handle previously returned // The file inode that we are modifying, and the handle previously returned
// by CreateFile or OpenFile when opening that inode. // by CreateFile or OpenFile when opening that inode.
...@@ -766,7 +757,7 @@ type WriteFileOp struct { ...@@ -766,7 +757,7 @@ type WriteFileOp struct {
} }
func (o *WriteFileOp) respond() { func (o *WriteFileOp) respond() {
resp := bazilfuse.WriteResponse{ resp := fuseshim.WriteResponse{
Size: len(o.Data), Size: len(o.Data),
} }
...@@ -792,7 +783,7 @@ func (o *WriteFileOp) respond() { ...@@ -792,7 +783,7 @@ func (o *WriteFileOp) respond() {
// file (but which is not used in "real" file systems). // file (but which is not used in "real" file systems).
type SyncFileOp struct { type SyncFileOp struct {
commonOp commonOp
bfReq *bazilfuse.FsyncRequest bfReq *fuseshim.FsyncRequest
// The file and handle being sync'd. // The file and handle being sync'd.
Inode InodeID Inode InodeID
...@@ -853,7 +844,7 @@ func (o *SyncFileOp) respond() { ...@@ -853,7 +844,7 @@ func (o *SyncFileOp) respond() {
// return any errors that occur. // return any errors that occur.
type FlushFileOp struct { type FlushFileOp struct {
commonOp commonOp
bfReq *bazilfuse.FlushRequest bfReq *fuseshim.FlushRequest
// The file and handle being flushed. // The file and handle being flushed.
Inode InodeID Inode InodeID
...@@ -875,7 +866,7 @@ func (o *FlushFileOp) respond() { ...@@ -875,7 +866,7 @@ func (o *FlushFileOp) respond() {
// Errors from this op are ignored by the kernel (cf. http://goo.gl/RL38Do). // Errors from this op are ignored by the kernel (cf. http://goo.gl/RL38Do).
type ReleaseFileHandleOp struct { type ReleaseFileHandleOp struct {
commonOp commonOp
bfReq *bazilfuse.ReleaseRequest bfReq *fuseshim.ReleaseRequest
// The handle ID to be released. The kernel guarantees that this ID will not // 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 // be used in further calls to the file system (unless it is reissued by the
...@@ -910,7 +901,7 @@ func (o *unknownOp) respond() { ...@@ -910,7 +901,7 @@ func (o *unknownOp) respond() {
// Read the target of a symlink inode. // Read the target of a symlink inode.
type ReadSymlinkOp struct { type ReadSymlinkOp struct {
commonOp commonOp
bfReq *bazilfuse.ReadlinkRequest bfReq *fuseshim.ReadlinkRequest
// The symlink inode that we are reading. // The symlink inode that we are reading.
Inode InodeID Inode InodeID
......
...@@ -19,7 +19,7 @@ import ( ...@@ -19,7 +19,7 @@ import (
"os" "os"
"time" "time"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/fuse/internal/fuseshim"
) )
// A 64-bit number used to uniquely identify a file or directory in the file // A 64-bit number used to uniquely identify a file or directory in the file
...@@ -38,7 +38,7 @@ const RootInodeID = 1 ...@@ -38,7 +38,7 @@ const RootInodeID = 1
func init() { func init() {
// Make sure the constant above is correct. We do this at runtime rather than // Make sure the constant above is correct. We do this at runtime rather than
// defining the constant in terms of bazilfuse.RootID for two reasons: // defining the constant in terms of fuseshim.RootID for two reasons:
// //
// 1. Users can more clearly see that the root ID is low and can therefore // 1. Users can more clearly see that the root ID is low and can therefore
// be used as e.g. an array index, with space reserved up to the root. // be used as e.g. an array index, with space reserved up to the root.
...@@ -46,12 +46,12 @@ func init() { ...@@ -46,12 +46,12 @@ func init() {
// 2. The constant can be untyped and can therefore more easily be used as // 2. The constant can be untyped and can therefore more easily be used as
// an array index. // an array index.
// //
if RootInodeID != bazilfuse.RootID { if RootInodeID != fuseshim.RootID {
panic( panic(
fmt.Sprintf( fmt.Sprintf(
"Oops, RootInodeID is wrong: %v vs. %v", "Oops, RootInodeID is wrong: %v vs. %v",
RootInodeID, RootInodeID,
bazilfuse.RootID)) fuseshim.RootID))
} }
} }
......
This diff is collapsed.
package fusekernel
import (
"time"
)
type Attr struct {
Ino uint64
Size uint64
Blocks uint64
Atime uint64
Mtime uint64
Ctime uint64
Crtime_ uint64 // OS X only
AtimeNsec uint32
MtimeNsec uint32
CtimeNsec uint32
CrtimeNsec uint32 // OS X only
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
Rdev uint32
Flags_ uint32 // OS X only; see chflags(2)
Blksize uint32
padding uint32
}
func (a *Attr) SetCrtime(s uint64, ns uint32) {
a.Crtime_, a.CrtimeNsec = s, ns
}
func (a *Attr) SetFlags(f uint32) {
a.Flags_ = f
}
type SetattrIn struct {
setattrInCommon
// OS X only
Bkuptime_ uint64
Chgtime_ uint64
Crtime uint64
BkuptimeNsec uint32
ChgtimeNsec uint32
CrtimeNsec uint32
Flags_ uint32 // see chflags(2)
}
func (in *SetattrIn) BkupTime() time.Time {
return time.Unix(int64(in.Bkuptime_), int64(in.BkuptimeNsec))
}
func (in *SetattrIn) Chgtime() time.Time {
return time.Unix(int64(in.Chgtime_), int64(in.ChgtimeNsec))
}
func (in *SetattrIn) Flags() uint32 {
return in.Flags_
}
func openFlags(flags uint32) OpenFlags {
return OpenFlags(flags)
}
type GetxattrIn struct {
getxattrInCommon
// OS X only
Position uint32
Padding uint32
}
func (g *GetxattrIn) GetPosition() uint32 {
return g.Position
}
type SetxattrIn struct {
setxattrInCommon
// OS X only
Position uint32
Padding uint32
}
func (s *SetxattrIn) GetPosition() uint32 {
return s.Position
}
package fuseshim
import "time"
type attr struct {
Ino uint64
Size uint64
Blocks uint64
Atime uint64
Mtime uint64
Ctime uint64
AtimeNsec uint32
MtimeNsec uint32
CtimeNsec uint32
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
Rdev uint32
Blksize uint32
padding uint32
}
func (a *attr) Crtime() time.Time {
return time.Time{}
}
func (a *attr) SetCrtime(s uint64, ns uint32) {
// ignored on freebsd
}
func (a *attr) SetFlags(f uint32) {
// ignored on freebsd
}
type setattrIn struct {
setattrInCommon
}
func (in *setattrIn) BkupTime() time.Time {
return time.Time{}
}
func (in *setattrIn) Chgtime() time.Time {
return time.Time{}
}
func (in *setattrIn) Flags() uint32 {
return 0
}
func openFlags(flags uint32) OpenFlags {
return OpenFlags(flags)
}
type getxattrIn struct {
getxattrInCommon
}
type setxattrIn struct {
setxattrInCommon
}
package fuseshim
import "time"
type attr struct {
Ino uint64
Size uint64
Blocks uint64
Atime uint64
Mtime uint64
Ctime uint64
AtimeNsec uint32
MtimeNsec uint32
CtimeNsec uint32
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
Rdev uint32
Blksize uint32
padding uint32
}
func (a *attr) Crtime() time.Time {
return time.Time{}
}
func (a *attr) SetCrtime(s uint64, ns uint32) {
// Ignored on Linux.
}
func (a *attr) SetFlags(f uint32) {
// Ignored on Linux.
}
type setattrIn struct {
setattrInCommon
}
func (in *setattrIn) BkupTime() time.Time {
return time.Time{}
}
func (in *setattrIn) Chgtime() time.Time {
return time.Time{}
}
func (in *setattrIn) Flags() uint32 {
return 0
}
func openFlags(flags uint32) OpenFlags {
// on amd64, the 32-bit O_LARGEFILE flag is always seen;
// on i386, the flag probably depends on the app
// requesting, but in any case should be utterly
// uninteresting to us here; our kernel protocol messages
// are not directly related to the client app's kernel
// API/ABI
flags &^= 0x8000
return OpenFlags(flags)
}
type getxattrIn struct {
getxattrInCommon
}
type setxattrIn struct {
setxattrInCommon
}
package fusekernel_test
import (
"os"
"testing"
fuse "github.com/jacobsa/bazilfuse"
)
func TestOpenFlagsAccmodeMask(t *testing.T) {
var f = fuse.OpenFlags(os.O_RDWR | os.O_SYNC)
if g, e := f&fuse.OpenAccessModeMask, fuse.OpenReadWrite; g != e {
t.Fatalf("OpenAccessModeMask behaves wrong: %v: %o != %o", f, g, e)
}
if f.IsReadOnly() {
t.Fatalf("IsReadOnly is wrong: %v", f)
}
if f.IsWriteOnly() {
t.Fatalf("IsWriteOnly is wrong: %v", f)
}
if !f.IsReadWrite() {
t.Fatalf("IsReadWrite is wrong: %v", f)
}
}
func TestOpenFlagsString(t *testing.T) {
var f = fuse.OpenFlags(os.O_RDWR | os.O_SYNC | os.O_APPEND)
if g, e := f.String(), "OpenReadWrite+OpenAppend+OpenSync"; g != e {
t.Fatalf("OpenFlags.String: %q != %q", g, e)
}
}
package fusekernel
import (
"fmt"
)
// Protocol is a FUSE protocol version number.
type Protocol struct {
Major uint32
Minor uint32
}
func (p Protocol) String() string {
return fmt.Sprintf("%d.%d", p.Major, p.Minor)
}
// LT returns whether a is less than b.
func (a Protocol) LT(b Protocol) bool {
return a.Major < b.Major ||
(a.Major == b.Major && a.Minor < b.Minor)
}
// GE returns whether a is greater than or equal to b.
func (a Protocol) GE(b Protocol) bool {
return a.Major > b.Major ||
(a.Major == b.Major && a.Minor >= b.Minor)
}
func (a Protocol) is79() bool {
return a.GE(Protocol{7, 9})
}
// HasAttrBlockSize returns whether Attr.BlockSize is respected by the
// kernel.
func (a Protocol) HasAttrBlockSize() bool {
return a.is79()
}
// HasReadWriteFlags returns whether ReadRequest/WriteRequest
// fields Flags and FileFlags are valid.
func (a Protocol) HasReadWriteFlags() bool {
return a.is79()
}
// HasGetattrFlags returns whether GetattrRequest field Flags is
// valid.
func (a Protocol) HasGetattrFlags() bool {
return a.is79()
}
func (a Protocol) is710() bool {
return a.GE(Protocol{7, 10})
}
// HasOpenNonSeekable returns whether OpenResponse field Flags flag
// OpenNonSeekable is supported.
func (a Protocol) HasOpenNonSeekable() bool {
return a.is710()
}
func (a Protocol) is712() bool {
return a.GE(Protocol{7, 12})
}
// HasUmask returns whether CreateRequest/MkdirRequest/MknodRequest
// field Umask is valid.
func (a Protocol) HasUmask() bool {
return a.is712()
}
// HasInvalidate returns whether InvalidateNode/InvalidateEntry are
// supported.
func (a Protocol) HasInvalidate() bool {
return a.is712()
}
package fuseshim
import (
"unsafe"
"github.com/jacobsa/fuse/internal/fusekernel"
)
// buffer provides a mechanism for constructing a message from
// multiple segments.
type buffer []byte
// alloc allocates size bytes and returns a pointer to the new
// segment.
func (w *buffer) alloc(size uintptr) unsafe.Pointer {
s := int(size)
if len(*w)+s > cap(*w) {
old := *w
*w = make([]byte, len(*w), 2*cap(*w)+s)
copy(*w, old)
}
l := len(*w)
*w = (*w)[:l+s]
return unsafe.Pointer(&(*w)[l])
}
// reset clears out the contents of the buffer.
func (w *buffer) reset() {
for i := range (*w)[:cap(*w)] {
(*w)[i] = 0
}
*w = (*w)[:0]
}
func newBuffer(extra uintptr) buffer {
const hdrSize = unsafe.Sizeof(fusekernel.OutHeader{})
buf := make(buffer, hdrSize, hdrSize+extra)
return buf
}
This diff is collapsed.
package fuseshim
import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"syscall"
)
// OS X appears to cap the size of writes to 1 MiB. This constant is also used
// for sizing receive buffers, so make it as small as it can be without
// limiting write sizes.
const maxWrite = 1 << 20
var errNoAvail = errors.New("no available fuse devices")
var errNotLoaded = errors.New("osxfusefs is not loaded")
func loadOSXFUSE() error {
cmd := exec.Command("/Library/Filesystems/osxfusefs.fs/Support/load_osxfusefs")
cmd.Dir = "/"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
return err
}
func openOSXFUSEDev() (*os.File, error) {
var f *os.File
var err error
for i := uint64(0); ; i++ {
path := "/dev/osxfuse" + strconv.FormatUint(i, 10)
f, err = os.OpenFile(path, os.O_RDWR, 0000)
if os.IsNotExist(err) {
if i == 0 {
// not even the first device was found -> fuse is not loaded
return nil, errNotLoaded
}
// we've run out of kernel-provided devices
return nil, errNoAvail
}
if err2, ok := err.(*os.PathError); ok && err2.Err == syscall.EBUSY {
// try the next one
continue
}
if err != nil {
return nil, err
}
return f, nil
}
}
func callMount(dir string, conf *mountConfig, f *os.File, ready chan<- struct{}, errp *error) error {
bin := "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs"
for k, v := range conf.options {
if strings.Contains(k, ",") || strings.Contains(v, ",") {
// Silly limitation but the mount helper does not
// understand any escaping. See TestMountOptionCommaError.
return fmt.Errorf("mount options cannot contain commas on darwin: %q=%q", k, v)
}
}
cmd := exec.Command(
bin,
"-o", conf.getOptions(),
// Tell osxfuse-kext how large our buffer is. It must split
// writes larger than this into multiple writes.
//
// OSXFUSE seems to ignore InitResponse.MaxWrite, and uses
// this instead.
"-o", "iosize="+strconv.FormatUint(maxWrite, 10),
// refers to fd passed in cmd.ExtraFiles
"3",
dir,
)
cmd.ExtraFiles = []*os.File{f}
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "MOUNT_FUSEFS_CALL_BY_LIB=")
// TODO this is used for fs typenames etc, let app influence it
cmd.Env = append(cmd.Env, "MOUNT_FUSEFS_DAEMON_PATH="+bin)
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Stderr = &buf
err := cmd.Start()
if err != nil {
return err
}
go func() {
err := cmd.Wait()
if err != nil {
if buf.Len() > 0 {
output := buf.Bytes()
output = bytes.TrimRight(output, "\n")
msg := err.Error() + ": " + string(output)
err = errors.New(msg)
}
}
*errp = err
close(ready)
}()
return err
}
func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (*os.File, error) {
f, err := openOSXFUSEDev()
if err == errNotLoaded {
err = loadOSXFUSE()
if err != nil {
return nil, err
}
// try again
f, err = openOSXFUSEDev()
}
if err != nil {
return nil, err
}
err = callMount(dir, conf, f, ready, errp)
if err != nil {
f.Close()
return nil, err
}
return f, nil
}
package fuseshim
import (
"fmt"
"os"
"os/exec"
"strings"
)
// Maximum file write size we are prepared to receive from the kernel.
const maxWrite = 128 * 1024
func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (*os.File, error) {
for k, v := range conf.options {
if strings.Contains(k, ",") || strings.Contains(v, ",") {
// Silly limitation but the mount helper does not
// understand any escaping. See TestMountOptionCommaError.
return nil, fmt.Errorf("mount options cannot contain commas on FreeBSD: %q=%q", k, v)
}
}
f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0000)
if err != nil {
*errp = err
return nil, err
}
cmd := exec.Command(
"/sbin/mount_fusefs",
"--safe",
"-o", conf.getOptions(),
"3",
dir,
)
cmd.ExtraFiles = []*os.File{f}
out, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("mount_fusefs: %q, %v", out, err)
}
close(ready)
return f, nil
}
package fuseshim
import (
"bufio"
"fmt"
"io"
"log"
"net"
"os"
"os/exec"
"sync"
"syscall"
)
// Maximum file write size we are prepared to receive from the kernel. Linux
// appears to limit writes to 128 KiB.
const maxWrite = 128 * 1024
func lineLogger(wg *sync.WaitGroup, prefix string, r io.ReadCloser) {
defer wg.Done()
scanner := bufio.NewScanner(r)
for scanner.Scan() {
switch line := scanner.Text(); line {
case `fusermount: failed to open /etc/fuse.conf: Permission denied`:
// Silence this particular message, it occurs way too
// commonly and isn't very relevant to whether the mount
// succeeds or not.
continue
default:
log.Printf("%s: %s", prefix, line)
}
}
if err := scanner.Err(); err != nil {
log.Printf("%s, error reading: %v", prefix, err)
}
}
func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) {
// linux mount is never delayed
close(ready)
fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0)
if err != nil {
return nil, fmt.Errorf("socketpair error: %v", err)
}
writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes")
defer writeFile.Close()
readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
defer readFile.Close()
cmd := exec.Command(
"fusermount",
"-o", conf.getOptions(),
"--",
dir,
)
cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3")
cmd.ExtraFiles = []*os.File{writeFile}
var wg sync.WaitGroup
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("setting up fusermount stderr: %v", err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, fmt.Errorf("setting up fusermount stderr: %v", err)
}
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("fusermount: %v", err)
}
wg.Add(2)
go lineLogger(&wg, "mount helper output", stdout)
go lineLogger(&wg, "mount helper error", stderr)
wg.Wait()
if err := cmd.Wait(); err != nil {
return nil, fmt.Errorf("fusermount: %v", err)
}
c, err := net.FileConn(readFile)
if err != nil {
return nil, fmt.Errorf("FileConn from fusermount socket: %v", err)
}
defer c.Close()
uc, ok := c.(*net.UnixConn)
if !ok {
return nil, fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c)
}
buf := make([]byte, 32) // expect 1 byte
oob := make([]byte, 32) // expect 24 bytes
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
if err != nil {
return nil, fmt.Errorf("ParseSocketControlMessage: %v", err)
}
if len(scms) != 1 {
return nil, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms)
}
scm := scms[0]
gotFds, err := syscall.ParseUnixRights(&scm)
if err != nil {
return nil, fmt.Errorf("syscall.ParseUnixRights: %v", err)
}
if len(gotFds) != 1 {
return nil, fmt.Errorf("wanted 1 fd; got %#v", gotFds)
}
f := os.NewFile(uintptr(gotFds[0]), "/dev/fuse")
return f, nil
}
package fuseshim
import (
"errors"
"strings"
"github.com/jacobsa/fuse/internal/fusekernel"
)
func dummyOption(conf *mountConfig) error {
return nil
}
// mountConfig holds the configuration for a mount operation.
// Use it by passing MountOption values to Mount.
type mountConfig struct {
options map[string]string
maxReadahead uint32
initFlags fusekernel.InitFlags
}
func escapeComma(s string) string {
s = strings.Replace(s, `\`, `\\`, -1)
s = strings.Replace(s, `,`, `\,`, -1)
return s
}
// getOptions makes a string of options suitable for passing to FUSE
// mount flag `-o`. Returns an empty string if no options were set.
// Any platform specific adjustments should happen before the call.
func (m *mountConfig) getOptions() string {
var opts []string
for k, v := range m.options {
k = escapeComma(k)
if v != "" {
k += "=" + escapeComma(v)
}
opts = append(opts, k)
}
return strings.Join(opts, ",")
}
type mountOption func(*mountConfig) error
// MountOption is passed to Mount to change the behavior of the mount.
type MountOption mountOption
// FSName sets the file system name (also called source) that is
// visible in the list of mounted file systems.
//
// FreeBSD ignores this option.
func FSName(name string) MountOption {
return func(conf *mountConfig) error {
conf.options["fsname"] = name
return nil
}
}
// Subtype sets the subtype of the mount. The main type is always
// `fuse`. The type in a list of mounted file systems will look like
// `fuse.foo`.
//
// OS X ignores this option.
// FreeBSD ignores this option.
func Subtype(fstype string) MountOption {
return func(conf *mountConfig) error {
conf.options["subtype"] = fstype
return nil
}
}
// LocalVolume sets the volume to be local (instead of network),
// changing the behavior of Finder, Spotlight, and such.
//
// OS X only. Others ignore this option.
func LocalVolume() MountOption {
return localVolume
}
// VolumeName sets the volume name shown in Finder.
//
// OS X only. Others ignore this option.
func VolumeName(name string) MountOption {
return volumeName(name)
}
var ErrCannotCombineAllowOtherAndAllowRoot = errors.New("cannot combine AllowOther and AllowRoot")
// AllowOther allows other users to access the file system.
//
// Only one of AllowOther or AllowRoot can be used.
func AllowOther() MountOption {
return func(conf *mountConfig) error {
if _, ok := conf.options["allow_root"]; ok {
return ErrCannotCombineAllowOtherAndAllowRoot
}
conf.options["allow_other"] = ""
return nil
}
}
// AllowRoot allows other users to access the file system.
//
// Only one of AllowOther or AllowRoot can be used.
//
// FreeBSD ignores this option.
func AllowRoot() MountOption {
return func(conf *mountConfig) error {
if _, ok := conf.options["allow_other"]; ok {
return ErrCannotCombineAllowOtherAndAllowRoot
}
conf.options["allow_root"] = ""
return nil
}
}
// DefaultPermissions makes the kernel enforce access control based on
// the file mode (as in chmod).
//
// Without this option, the Node itself decides what is and is not
// allowed. This is normally ok because FUSE file systems cannot be
// accessed by other users without AllowOther/AllowRoot.
//
// FreeBSD ignores this option.
func DefaultPermissions() MountOption {
return func(conf *mountConfig) error {
conf.options["default_permissions"] = ""
return nil
}
}
// Set the supplied arbitrary (key, value) pair in the "-o" argument to the
// fuse mount binary, overriding any previous setting for the key. If value is
// empty, the '=' will be omitted from the argument.
func SetOption(key, value string) MountOption {
return func(conf *mountConfig) error {
conf.options[key] = value
return nil
}
}
// ReadOnly makes the mount read-only.
func ReadOnly() MountOption {
return func(conf *mountConfig) error {
conf.options["ro"] = ""
return nil
}
}
// MaxReadahead sets the number of bytes that can be prefetched for
// sequential reads. The kernel can enforce a maximum value lower than
// this.
//
// This setting makes the kernel perform speculative reads that do not
// originate from any client process. This usually tremendously
// improves read performance.
func MaxReadahead(n uint32) MountOption {
return func(conf *mountConfig) error {
conf.maxReadahead = n
return nil
}
}
// AsyncRead enables multiple outstanding read requests for the same
// handle. Without this, there is at most one request in flight at a
// time.
func AsyncRead() MountOption {
return func(conf *mountConfig) error {
conf.initFlags |= fusekernel.InitAsyncRead
return nil
}
}
// WritebackCache enables the kernel to buffer writes before sending
// them to the FUSE server. Without this, writethrough caching is
// used.
func WritebackCache() MountOption {
return func(conf *mountConfig) error {
conf.initFlags |= fusekernel.InitWritebackCache
return nil
}
}
package fuseshim
func localVolume(conf *mountConfig) error {
conf.options["local"] = ""
return nil
}
func volumeName(name string) MountOption {
return func(conf *mountConfig) error {
conf.options["volname"] = name
return nil
}
}
package fuseshim
func localVolume(conf *mountConfig) error {
return nil
}
func volumeName(name string) MountOption {
return dummyOption
}
package fuseshim
// for TestMountOptionCommaError
func ForTestSetMountOption(k, v string) MountOption {
fn := func(conf *mountConfig) error {
conf.options[k] = v
return nil
}
return fn
}
package fuseshim
func localVolume(conf *mountConfig) error {
return nil
}
func volumeName(name string) MountOption {
return dummyOption
}
// This file contains tests for platforms that have no escape
// mechanism for including commas in mount options.
//
// +build darwin
package fuseshim_test
import (
"runtime"
"testing"
fuse "github.com/jacobsa/bazilfuse"
"github.com/jacobsa/bazilfuse/fs/fstestutil"
)
func TestMountOptionCommaError(t *testing.T) {
t.Parallel()
// this test is not tied to any specific option, it just needs
// some string content
var evil = "FuseTest,Marker"
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil,
fuse.ForTestSetMountOption("fusetest", evil),
)
if err == nil {
mnt.Close()
t.Fatal("expected an error about commas")
}
if g, e := err.Error(), `mount options cannot contain commas on `+runtime.GOOS+`: "fusetest"="FuseTest,Marker"`; g != e {
t.Fatalf("wrong error: %q != %q", g, e)
}
}
package fuseshim_test
import (
"os"
"runtime"
"syscall"
"testing"
fuse "github.com/jacobsa/bazilfuse"
"github.com/jacobsa/bazilfuse/fs"
"github.com/jacobsa/bazilfuse/fs/fstestutil"
"golang.org/x/net/context"
)
func init() {
fstestutil.DebugByDefault()
}
func TestMountOptionFSName(t *testing.T) {
if runtime.GOOS == "freebsd" {
t.Skip("FreeBSD does not support FSName")
}
t.Parallel()
const name = "FuseTestMarker"
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil,
fuse.FSName(name),
)
if err != nil {
t.Fatal(err)
}
defer mnt.Close()
info, err := fstestutil.GetMountInfo(mnt.Dir)
if err != nil {
t.Fatal(err)
}
if g, e := info.FSName, name; g != e {
t.Errorf("wrong FSName: %q != %q", g, e)
}
}
func testMountOptionFSNameEvil(t *testing.T, evil string) {
if runtime.GOOS == "freebsd" {
t.Skip("FreeBSD does not support FSName")
}
t.Parallel()
var name = "FuseTest" + evil + "Marker"
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil,
fuse.FSName(name),
)
if err != nil {
t.Fatal(err)
}
defer mnt.Close()
info, err := fstestutil.GetMountInfo(mnt.Dir)
if err != nil {
t.Fatal(err)
}
if g, e := info.FSName, name; g != e {
t.Errorf("wrong FSName: %q != %q", g, e)
}
}
func TestMountOptionFSNameEvilComma(t *testing.T) {
if runtime.GOOS == "darwin" {
// see TestMountOptionCommaError for a test that enforces we
// at least give a nice error, instead of corrupting the mount
// options
t.Skip("TODO: OS X gets this wrong, commas in mount options cannot be escaped at all")
}
testMountOptionFSNameEvil(t, ",")
}
func TestMountOptionFSNameEvilSpace(t *testing.T) {
testMountOptionFSNameEvil(t, " ")
}
func TestMountOptionFSNameEvilTab(t *testing.T) {
testMountOptionFSNameEvil(t, "\t")
}
func TestMountOptionFSNameEvilNewline(t *testing.T) {
testMountOptionFSNameEvil(t, "\n")
}
func TestMountOptionFSNameEvilBackslash(t *testing.T) {
testMountOptionFSNameEvil(t, `\`)
}
func TestMountOptionFSNameEvilBackslashDouble(t *testing.T) {
// catch double-unescaping, if it were to happen
testMountOptionFSNameEvil(t, `\\`)
}
func TestMountOptionSubtype(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("OS X does not support Subtype")
}
if runtime.GOOS == "freebsd" {
t.Skip("FreeBSD does not support Subtype")
}
t.Parallel()
const name = "FuseTestMarker"
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil,
fuse.Subtype(name),
)
if err != nil {
t.Fatal(err)
}
defer mnt.Close()
info, err := fstestutil.GetMountInfo(mnt.Dir)
if err != nil {
t.Fatal(err)
}
if g, e := info.Type, "fuse."+name; g != e {
t.Errorf("wrong Subtype: %q != %q", g, e)
}
}
// TODO test LocalVolume
// TODO test AllowOther; hard because needs system-level authorization
func TestMountOptionAllowOtherThenAllowRoot(t *testing.T) {
t.Parallel()
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil,
fuse.AllowOther(),
fuse.AllowRoot(),
)
if err == nil {
mnt.Close()
}
if g, e := err, fuse.ErrCannotCombineAllowOtherAndAllowRoot; g != e {
t.Fatalf("wrong error: %v != %v", g, e)
}
}
// TODO test AllowRoot; hard because needs system-level authorization
func TestMountOptionAllowRootThenAllowOther(t *testing.T) {
t.Parallel()
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}}, nil,
fuse.AllowRoot(),
fuse.AllowOther(),
)
if err == nil {
mnt.Close()
}
if g, e := err, fuse.ErrCannotCombineAllowOtherAndAllowRoot; g != e {
t.Fatalf("wrong error: %v != %v", g, e)
}
}
type unwritableFile struct{}
func (f unwritableFile) Attr(ctx context.Context, a *fuse.Attr) error {
a.Mode = 0000
return nil
}
func TestMountOptionDefaultPermissions(t *testing.T) {
if runtime.GOOS == "freebsd" {
t.Skip("FreeBSD does not support DefaultPermissions")
}
t.Parallel()
mnt, err := fstestutil.MountedT(t,
fstestutil.SimpleFS{
&fstestutil.ChildMap{"child": unwritableFile{}},
},
nil,
fuse.DefaultPermissions(),
)
if err != nil {
t.Fatal(err)
}
defer mnt.Close()
// This will be prevented by kernel-level access checking when
// DefaultPermissions is used.
f, err := os.OpenFile(mnt.Dir+"/child", os.O_WRONLY, 0000)
if err == nil {
f.Close()
t.Fatal("expected an error")
}
if !os.IsPermission(err) {
t.Fatalf("expected a permission error, got %T: %v", err, err)
}
}
type createrDir struct {
fstestutil.Dir
}
var _ fs.NodeCreater = createrDir{}
func (createrDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
// pick a really distinct error, to identify it later
return nil, nil, fuse.Errno(syscall.ENAMETOOLONG)
}
func TestMountOptionReadOnly(t *testing.T) {
t.Parallel()
mnt, err := fstestutil.MountedT(t,
fstestutil.SimpleFS{createrDir{}},
nil,
fuse.ReadOnly(),
)
if err != nil {
t.Fatal(err)
}
defer mnt.Close()
// This will be prevented by kernel-level access checking when
// ReadOnly is used.
f, err := os.Create(mnt.Dir + "/child")
if err == nil {
f.Close()
t.Fatal("expected an error")
}
perr, ok := err.(*os.PathError)
if !ok {
t.Fatalf("expected PathError, got %T: %v", err, err)
}
if perr.Err != syscall.EROFS {
t.Fatalf("expected EROFS, got %T: %v", err, err)
}
}
package fuseshim
// Unmount tries to unmount the filesystem mounted at dir.
func Unmount(dir string) error {
return unmount(dir)
}
package bazilfuse
import (
"bytes"
"errors"
"os/exec"
)
func unmount(dir string) error {
cmd := exec.Command("fusermount", "-u", dir)
output, err := cmd.CombinedOutput()
if err != nil {
if len(output) > 0 {
output = bytes.TrimRight(output, "\n")
msg := err.Error() + ": " + string(output)
err = errors.New(msg)
}
return err
}
return nil
}
// +build !linux
package fuseshim
import (
"os"
"syscall"
)
func unmount(dir string) error {
err := syscall.Unmount(dir, 0)
if err != nil {
err = &os.PathError{Op: "unmount", Path: dir, Err: err}
return err
}
return nil
}
...@@ -19,7 +19,8 @@ import ( ...@@ -19,7 +19,8 @@ import (
"log" "log"
"runtime" "runtime"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/fuse/internal/fuseshim"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
...@@ -111,13 +112,13 @@ type MountConfig struct { ...@@ -111,13 +112,13 @@ type MountConfig struct {
Options map[string]string Options map[string]string
} }
// Convert to mount options to be passed to package bazilfuse. // Convert to mount options to be passed to package fuseshim.
func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) { func (c *MountConfig) bazilfuseOptions() (opts []fuseshim.MountOption) {
isDarwin := runtime.GOOS == "darwin" isDarwin := runtime.GOOS == "darwin"
// Enable permissions checking in the kernel. See the comments on // Enable permissions checking in the kernel. See the comments on
// InodeAttributes.Mode. // InodeAttributes.Mode.
opts = append(opts, bazilfuse.SetOption("default_permissions", "")) opts = append(opts, fuseshim.SetOption("default_permissions", ""))
// HACK(jacobsa): Work around what appears to be a bug in systemd v219, as // HACK(jacobsa): Work around what appears to be a bug in systemd v219, as
// shipped in Ubuntu 15.04, where it automatically unmounts any file system // shipped in Ubuntu 15.04, where it automatically unmounts any file system
...@@ -135,17 +136,17 @@ func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) { ...@@ -135,17 +136,17 @@ func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) {
// Special file system name? // Special file system name?
if fsname != "" { if fsname != "" {
opts = append(opts, bazilfuse.FSName(fsname)) opts = append(opts, fuseshim.FSName(fsname))
} }
// Read only? // Read only?
if c.ReadOnly { if c.ReadOnly {
opts = append(opts, bazilfuse.ReadOnly()) opts = append(opts, fuseshim.ReadOnly())
} }
// OS X: set novncache when appropriate. // OS X: set novncache when appropriate.
if isDarwin && !c.EnableVnodeCaching { if isDarwin && !c.EnableVnodeCaching {
opts = append(opts, bazilfuse.SetOption("novncache", "")) opts = append(opts, fuseshim.SetOption("novncache", ""))
} }
// OS X: disable the use of "Apple Double" (._foo and .DS_Store) files, which // OS X: disable the use of "Apple Double" (._foo and .DS_Store) files, which
...@@ -154,7 +155,7 @@ func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) { ...@@ -154,7 +155,7 @@ func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) {
// //
// Cf. https://github.com/osxfuse/osxfuse/wiki/Mount-options // Cf. https://github.com/osxfuse/osxfuse/wiki/Mount-options
if isDarwin { if isDarwin {
opts = append(opts, bazilfuse.SetOption("noappledouble", "")) opts = append(opts, fuseshim.SetOption("noappledouble", ""))
} }
// Ask the Linux kernel for larger read requests. // Ask the Linux kernel for larger read requests.
...@@ -175,11 +176,11 @@ func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) { ...@@ -175,11 +176,11 @@ func (c *MountConfig) bazilfuseOptions() (opts []bazilfuse.MountOption) {
// //
// Reading a page at a time is a drag. Ask for a larger size. // Reading a page at a time is a drag. Ask for a larger size.
const maxReadahead = 1 << 20 const maxReadahead = 1 << 20
opts = append(opts, bazilfuse.MaxReadahead(maxReadahead)) opts = append(opts, fuseshim.MaxReadahead(maxReadahead))
// Last but not least: other user-supplied options. // Last but not least: other user-supplied options.
for k, v := range c.Options { for k, v := range c.Options {
opts = append(opts, bazilfuse.SetOption(k, v)) opts = append(opts, fuseshim.SetOption(k, v))
} }
return return
...@@ -198,10 +199,10 @@ func Mount( ...@@ -198,10 +199,10 @@ func Mount(
joinStatusAvailable: make(chan struct{}), joinStatusAvailable: make(chan struct{}),
} }
// Open a bazilfuse connection. // Open a fuseshim connection.
bfConn, err := bazilfuse.Mount(mfs.dir, config.bazilfuseOptions()...) bfConn, err := fuseshim.Mount(mfs.dir, config.bazilfuseOptions()...)
if err != nil { if err != nil {
err = fmt.Errorf("bazilfuse.Mount: %v", err) err = fmt.Errorf("fuseshim.Mount: %v", err)
return return
} }
......
...@@ -30,9 +30,9 @@ import ( ...@@ -30,9 +30,9 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"github.com/jacobsa/bazilfuse"
"github.com/jacobsa/fuse/fsutil" "github.com/jacobsa/fuse/fsutil"
"github.com/jacobsa/fuse/fusetesting" "github.com/jacobsa/fuse/fusetesting"
"github.com/jacobsa/fuse/internal/fuseshim"
"github.com/jacobsa/fuse/samples" "github.com/jacobsa/fuse/samples"
. "github.com/jacobsa/oglematchers" . "github.com/jacobsa/oglematchers"
. "github.com/jacobsa/ogletest" . "github.com/jacobsa/ogletest"
...@@ -58,8 +58,8 @@ type flushFSTest struct { ...@@ -58,8 +58,8 @@ type flushFSTest struct {
func (t *flushFSTest) setUp( func (t *flushFSTest) setUp(
ti *TestInfo, ti *TestInfo,
flushErr bazilfuse.Errno, flushErr fuseshim.Errno,
fsyncErr bazilfuse.Errno, fsyncErr fuseshim.Errno,
readOnly bool) { readOnly bool) {
var err error var err error
...@@ -810,7 +810,7 @@ func init() { RegisterTestSuite(&FlushErrorTest{}) } ...@@ -810,7 +810,7 @@ func init() { RegisterTestSuite(&FlushErrorTest{}) }
func (t *FlushErrorTest) SetUp(ti *TestInfo) { func (t *FlushErrorTest) SetUp(ti *TestInfo) {
const noErr = 0 const noErr = 0
t.flushFSTest.setUp(ti, bazilfuse.ENOENT, noErr, false) t.flushFSTest.setUp(ti, fuseshim.ENOENT, noErr, false)
} }
func (t *FlushErrorTest) Close() { func (t *FlushErrorTest) Close() {
...@@ -890,7 +890,7 @@ func init() { RegisterTestSuite(&FsyncErrorTest{}) } ...@@ -890,7 +890,7 @@ func init() { RegisterTestSuite(&FsyncErrorTest{}) }
func (t *FsyncErrorTest) SetUp(ti *TestInfo) { func (t *FsyncErrorTest) SetUp(ti *TestInfo) {
const noErr = 0 const noErr = 0
t.flushFSTest.setUp(ti, noErr, bazilfuse.ENOENT, false) t.flushFSTest.setUp(ti, noErr, fuseshim.ENOENT, false)
} }
func (t *FsyncErrorTest) Fsync() { func (t *FsyncErrorTest) Fsync() {
......
This diff is collapsed.
This diff is collapsed.
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