Commit c22e8d7b authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fuse: wire cancellation channel through RawFileSystem API

This should be tagged with a version bump because it changes the
RawFileSystem API.

Changes to nodefs and paths will be transparent: a Cancel channel was
added to the fuse.Context struct. In addition fuse.Context now
implements the Go context package. This also increases the minimum Go
version to 1.7.
parent 55f8d0c5
......@@ -168,6 +168,19 @@ type MountOptions struct {
// each method in separate goroutine.
//
// A null implementation is provided by NewDefaultRawFileSystem.
//
// After a successful FUSE API call returns, you may not read input or
// write output data: for performance reasons, memory is reused for
// following requests, and reading/writing the request data will lead
// to race conditions. If you spawn a background routine from a FUSE
// API call, any incoming request data it wants to reference should be
// copied over.
//
// If a FUSE API call is canceled (which is signaled by closing the
// `cancel` channel), the API call should return EINTR. In this case,
// the outstanding request data is not reused, so the API call may
// return EINTR without ensuring that child contexts have successfully
// completed.
type RawFileSystem interface {
String() string
......@@ -178,7 +191,7 @@ type RawFileSystem interface {
// about a file inside a directory. Many lookup calls can
// occur in parallel, but only one call happens for each (dir,
// name) pair.
Lookup(header *InHeader, name string, out *EntryOut) (status Status)
Lookup(cancel <-chan struct{}, header *InHeader, name string, out *EntryOut) (status Status)
// Forget is called when the kernel discards entries from its
// dentry cache. This happens on unmount, and when the kernel
......@@ -189,53 +202,52 @@ type RawFileSystem interface {
Forget(nodeid, nlookup uint64)
// Attributes.
GetAttr(input *GetAttrIn, out *AttrOut) (code Status)
SetAttr(input *SetAttrIn, out *AttrOut) (code Status)
GetAttr(cancel <-chan struct{}, input *GetAttrIn, out *AttrOut) (code Status)
SetAttr(cancel <-chan struct{}, input *SetAttrIn, out *AttrOut) (code Status)
// Modifying structure.
Mknod(input *MknodIn, name string, out *EntryOut) (code Status)
Mkdir(input *MkdirIn, name string, out *EntryOut) (code Status)
Unlink(header *InHeader, name string) (code Status)
Rmdir(header *InHeader, name string) (code Status)
Rename(input *RenameIn, oldName string, newName string) (code Status)
Link(input *LinkIn, filename string, out *EntryOut) (code Status)
Mknod(cancel <-chan struct{}, input *MknodIn, name string, out *EntryOut) (code Status)
Mkdir(cancel <-chan struct{}, input *MkdirIn, name string, out *EntryOut) (code Status)
Unlink(cancel <-chan struct{}, header *InHeader, name string) (code Status)
Rmdir(cancel <-chan struct{}, header *InHeader, name string) (code Status)
Rename(cancel <-chan struct{}, input *RenameIn, oldName string, newName string) (code Status)
Link(cancel <-chan struct{}, input *LinkIn, filename string, out *EntryOut) (code Status)
Symlink(header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status)
Readlink(header *InHeader) (out []byte, code Status)
Access(input *AccessIn) (code Status)
Symlink(cancel <-chan struct{}, header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status)
Readlink(cancel <-chan struct{}, header *InHeader) (out []byte, code Status)
Access(cancel <-chan struct{}, input *AccessIn) (code Status)
// Extended attributes.
GetXAttrSize(header *InHeader, attr string) (sz int, code Status)
GetXAttrData(header *InHeader, attr string) (data []byte, code Status)
ListXAttr(header *InHeader) (attributes []byte, code Status)
SetXAttr(input *SetXAttrIn, attr string, data []byte) Status
RemoveXAttr(header *InHeader, attr string) (code Status)
GetXAttrSize(cancel <-chan struct{}, header *InHeader, attr string) (sz int, code Status)
GetXAttrData(cancel <-chan struct{}, header *InHeader, attr string) (data []byte, code Status)
ListXAttr(cancel <-chan struct{}, header *InHeader) (attributes []byte, code Status)
SetXAttr(cancel <-chan struct{}, input *SetXAttrIn, attr string, data []byte) Status
RemoveXAttr(cancel <-chan struct{}, header *InHeader, attr string) (code Status)
// File handling.
Create(input *CreateIn, name string, out *CreateOut) (code Status)
Open(input *OpenIn, out *OpenOut) (status Status)
Read(input *ReadIn, buf []byte) (ReadResult, Status)
Create(cancel <-chan struct{}, input *CreateIn, name string, out *CreateOut) (code Status)
Open(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status)
Read(cancel <-chan struct{}, input *ReadIn, buf []byte) (ReadResult, Status)
// File locking
GetLk(input *LkIn, out *LkOut) (code Status)
SetLk(input *LkIn) (code Status)
SetLkw(input *LkIn) (code Status)
GetLk(cancel <-chan struct{}, input *LkIn, out *LkOut) (code Status)
SetLk(cancel <-chan struct{}, input *LkIn) (code Status)
SetLkw(cancel <-chan struct{}, input *LkIn) (code Status)
Release(input *ReleaseIn)
Write(input *WriteIn, data []byte) (written uint32, code Status)
Flush(input *FlushIn) Status
Fsync(input *FsyncIn) (code Status)
Fallocate(input *FallocateIn) (code Status)
Write(cancel <-chan struct{}, input *WriteIn, data []byte) (written uint32, code Status)
Flush(cancel <-chan struct{}, input *FlushIn) Status
Fsync(cancel <-chan struct{}, input *FsyncIn) (code Status)
Fallocate(cancel <-chan struct{}, input *FallocateIn) (code Status)
// Directory handling
OpenDir(input *OpenIn, out *OpenOut) (status Status)
ReadDir(input *ReadIn, out *DirEntryList) Status
ReadDirPlus(input *ReadIn, out *DirEntryList) Status
OpenDir(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status)
ReadDir(cancel <-chan struct{}, input *ReadIn, out *DirEntryList) Status
ReadDirPlus(cancel <-chan struct{}, input *ReadIn, out *DirEntryList) Status
ReleaseDir(input *ReleaseIn)
FsyncDir(input *FsyncIn) (code Status)
FsyncDir(cancel <-chan struct{}, input *FsyncIn) (code Status)
//
StatFs(input *InHeader, out *StatfsOut) (code Status)
StatFs(cancel <-chan struct{}, input *InHeader, out *StatfsOut) (code Status)
// This is called on processing the first request. The
// filesystem implementation can use the server argument to
......
// Copyright 2016 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package fuse
import (
"context"
"time"
)
// Context passes along cancelation signal and request data (PID, GID,
// UID). The name of this class predates the standard "context"
// package from Go, but it does implement the context.Context
// interface.
//
// When a FUSE request is canceled, the API routine should respond by
// returning the EINTR status code.
type Context struct {
Caller
Cancel <-chan struct{}
}
func (c *Context) Deadline() (time.Time, bool) {
return time.Time{}, false
}
func (c *Context) Done() <-chan struct{} {
return c.Cancel
}
func (c *Context) Err() error {
select {
case <-c.Cancel:
return context.Canceled
default:
return nil
}
}
type callerKeyType struct{}
var callerKey callerKeyType
func FromContext(ctx context.Context) (*Caller, bool) {
v, ok := ctx.Value(callerKey).(*Caller)
return v, ok
}
func NewContext(ctx context.Context, caller *Caller) context.Context {
return context.WithValue(ctx, callerKey, caller)
}
func (c *Context) Value(key interface{}) interface{} {
if key == callerKey {
return &c.Caller
}
return nil
}
var _ = context.Context((*Context)(nil))
......@@ -26,139 +26,139 @@ func (fs *defaultRawFileSystem) String() string {
func (fs *defaultRawFileSystem) SetDebug(dbg bool) {
}
func (fs *defaultRawFileSystem) StatFs(header *InHeader, out *StatfsOut) Status {
func (fs *defaultRawFileSystem) StatFs(cancel <-chan struct{}, header *InHeader, out *StatfsOut) Status {
return ENOSYS
}
func (fs *defaultRawFileSystem) Lookup(header *InHeader, name string, out *EntryOut) (code Status) {
func (fs *defaultRawFileSystem) Lookup(cancel <-chan struct{}, header *InHeader, name string, out *EntryOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Forget(nodeID, nlookup uint64) {
}
func (fs *defaultRawFileSystem) GetAttr(input *GetAttrIn, out *AttrOut) (code Status) {
func (fs *defaultRawFileSystem) GetAttr(cancel <-chan struct{}, input *GetAttrIn, out *AttrOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Open(input *OpenIn, out *OpenOut) (status Status) {
func (fs *defaultRawFileSystem) Open(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status) {
return OK
}
func (fs *defaultRawFileSystem) SetAttr(input *SetAttrIn, out *AttrOut) (code Status) {
func (fs *defaultRawFileSystem) SetAttr(cancel <-chan struct{}, input *SetAttrIn, out *AttrOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Readlink(header *InHeader) (out []byte, code Status) {
func (fs *defaultRawFileSystem) Readlink(cancel <-chan struct{}, header *InHeader) (out []byte, code Status) {
return nil, ENOSYS
}
func (fs *defaultRawFileSystem) Mknod(input *MknodIn, name string, out *EntryOut) (code Status) {
func (fs *defaultRawFileSystem) Mknod(cancel <-chan struct{}, input *MknodIn, name string, out *EntryOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Mkdir(input *MkdirIn, name string, out *EntryOut) (code Status) {
func (fs *defaultRawFileSystem) Mkdir(cancel <-chan struct{}, input *MkdirIn, name string, out *EntryOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Unlink(header *InHeader, name string) (code Status) {
func (fs *defaultRawFileSystem) Unlink(cancel <-chan struct{}, header *InHeader, name string) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Rmdir(header *InHeader, name string) (code Status) {
func (fs *defaultRawFileSystem) Rmdir(cancel <-chan struct{}, header *InHeader, name string) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Symlink(header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status) {
func (fs *defaultRawFileSystem) Symlink(cancel <-chan struct{}, header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Rename(input *RenameIn, oldName string, newName string) (code Status) {
func (fs *defaultRawFileSystem) Rename(cancel <-chan struct{}, input *RenameIn, oldName string, newName string) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Link(input *LinkIn, name string, out *EntryOut) (code Status) {
func (fs *defaultRawFileSystem) Link(cancel <-chan struct{}, input *LinkIn, name string, out *EntryOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) GetXAttrSize(header *InHeader, attr string) (size int, code Status) {
func (fs *defaultRawFileSystem) GetXAttrSize(cancel <-chan struct{}, header *InHeader, attr string) (size int, code Status) {
return 0, ENOSYS
}
func (fs *defaultRawFileSystem) GetXAttrData(header *InHeader, attr string) (data []byte, code Status) {
func (fs *defaultRawFileSystem) GetXAttrData(cancel <-chan struct{}, header *InHeader, attr string) (data []byte, code Status) {
return nil, ENOATTR
}
func (fs *defaultRawFileSystem) SetXAttr(input *SetXAttrIn, attr string, data []byte) Status {
func (fs *defaultRawFileSystem) SetXAttr(cancel <-chan struct{}, input *SetXAttrIn, attr string, data []byte) Status {
return ENOSYS
}
func (fs *defaultRawFileSystem) ListXAttr(header *InHeader) (data []byte, code Status) {
func (fs *defaultRawFileSystem) ListXAttr(cancel <-chan struct{}, header *InHeader) (data []byte, code Status) {
return nil, ENOSYS
}
func (fs *defaultRawFileSystem) RemoveXAttr(header *InHeader, attr string) Status {
func (fs *defaultRawFileSystem) RemoveXAttr(cancel <-chan struct{}, header *InHeader, attr string) Status {
return ENOSYS
}
func (fs *defaultRawFileSystem) Access(input *AccessIn) (code Status) {
func (fs *defaultRawFileSystem) Access(cancel <-chan struct{}, input *AccessIn) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Create(input *CreateIn, name string, out *CreateOut) (code Status) {
func (fs *defaultRawFileSystem) Create(cancel <-chan struct{}, input *CreateIn, name string, out *CreateOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) OpenDir(input *OpenIn, out *OpenOut) (status Status) {
func (fs *defaultRawFileSystem) OpenDir(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Read(input *ReadIn, buf []byte) (ReadResult, Status) {
func (fs *defaultRawFileSystem) Read(cancel <-chan struct{}, input *ReadIn, buf []byte) (ReadResult, Status) {
return nil, ENOSYS
}
func (fs *defaultRawFileSystem) GetLk(in *LkIn, out *LkOut) (code Status) {
func (fs *defaultRawFileSystem) GetLk(cancel <-chan struct{}, in *LkIn, out *LkOut) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) SetLk(in *LkIn) (code Status) {
func (fs *defaultRawFileSystem) SetLk(cancel <-chan struct{}, in *LkIn) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) SetLkw(in *LkIn) (code Status) {
func (fs *defaultRawFileSystem) SetLkw(cancel <-chan struct{}, in *LkIn) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Release(input *ReleaseIn) {
}
func (fs *defaultRawFileSystem) Write(input *WriteIn, data []byte) (written uint32, code Status) {
func (fs *defaultRawFileSystem) Write(cancel <-chan struct{}, input *WriteIn, data []byte) (written uint32, code Status) {
return 0, ENOSYS
}
func (fs *defaultRawFileSystem) Flush(input *FlushIn) Status {
func (fs *defaultRawFileSystem) Flush(cancel <-chan struct{}, input *FlushIn) Status {
return OK
}
func (fs *defaultRawFileSystem) Fsync(input *FsyncIn) (code Status) {
func (fs *defaultRawFileSystem) Fsync(cancel <-chan struct{}, input *FsyncIn) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) ReadDir(input *ReadIn, l *DirEntryList) Status {
func (fs *defaultRawFileSystem) ReadDir(cancel <-chan struct{}, input *ReadIn, l *DirEntryList) Status {
return ENOSYS
}
func (fs *defaultRawFileSystem) ReadDirPlus(input *ReadIn, l *DirEntryList) Status {
func (fs *defaultRawFileSystem) ReadDirPlus(cancel <-chan struct{}, input *ReadIn, l *DirEntryList) Status {
return ENOSYS
}
func (fs *defaultRawFileSystem) ReleaseDir(input *ReleaseIn) {
}
func (fs *defaultRawFileSystem) FsyncDir(input *FsyncIn) (code Status) {
func (fs *defaultRawFileSystem) FsyncDir(cancel <-chan struct{}, input *FsyncIn) (code Status) {
return ENOSYS
}
func (fs *defaultRawFileSystem) Fallocate(in *FallocateIn) (code Status) {
func (fs *defaultRawFileSystem) Fallocate(cancel <-chan struct{}, in *FallocateIn) (code Status) {
return ENOSYS
}
......@@ -33,9 +33,9 @@ func (fs *lockingRawFileSystem) locked() func() {
return func() { fs.lock.Unlock() }
}
func (fs *lockingRawFileSystem) Lookup(header *InHeader, name string, out *EntryOut) (code Status) {
func (fs *lockingRawFileSystem) Lookup(cancel <-chan struct{}, header *InHeader, name string, out *EntryOut) (code Status) {
defer fs.locked()()
return fs.RawFS.Lookup(header, name, out)
return fs.RawFS.Lookup(cancel, header, name, out)
}
func (fs *lockingRawFileSystem) SetDebug(dbg bool) {
......@@ -48,100 +48,100 @@ func (fs *lockingRawFileSystem) Forget(nodeID uint64, nlookup uint64) {
fs.RawFS.Forget(nodeID, nlookup)
}
func (fs *lockingRawFileSystem) GetAttr(input *GetAttrIn, out *AttrOut) (code Status) {
func (fs *lockingRawFileSystem) GetAttr(cancel <-chan struct{}, input *GetAttrIn, out *AttrOut) (code Status) {
defer fs.locked()()
return fs.RawFS.GetAttr(input, out)
return fs.RawFS.GetAttr(cancel, input, out)
}
func (fs *lockingRawFileSystem) Open(input *OpenIn, out *OpenOut) (status Status) {
func (fs *lockingRawFileSystem) Open(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status) {
defer fs.locked()()
return fs.RawFS.Open(input, out)
return fs.RawFS.Open(cancel, input, out)
}
func (fs *lockingRawFileSystem) SetAttr(input *SetAttrIn, out *AttrOut) (code Status) {
func (fs *lockingRawFileSystem) SetAttr(cancel <-chan struct{}, input *SetAttrIn, out *AttrOut) (code Status) {
defer fs.locked()()
return fs.RawFS.SetAttr(input, out)
return fs.RawFS.SetAttr(cancel, input, out)
}
func (fs *lockingRawFileSystem) Readlink(header *InHeader) (out []byte, code Status) {
func (fs *lockingRawFileSystem) Readlink(cancel <-chan struct{}, header *InHeader) (out []byte, code Status) {
defer fs.locked()()
return fs.RawFS.Readlink(header)
return fs.RawFS.Readlink(cancel, header)
}
func (fs *lockingRawFileSystem) Mknod(input *MknodIn, name string, out *EntryOut) (code Status) {
func (fs *lockingRawFileSystem) Mknod(cancel <-chan struct{}, input *MknodIn, name string, out *EntryOut) (code Status) {
defer fs.locked()()
return fs.RawFS.Mknod(input, name, out)
return fs.RawFS.Mknod(cancel, input, name, out)
}
func (fs *lockingRawFileSystem) Mkdir(input *MkdirIn, name string, out *EntryOut) (code Status) {
func (fs *lockingRawFileSystem) Mkdir(cancel <-chan struct{}, input *MkdirIn, name string, out *EntryOut) (code Status) {
defer fs.locked()()
return fs.RawFS.Mkdir(input, name, out)
return fs.RawFS.Mkdir(cancel, input, name, out)
}
func (fs *lockingRawFileSystem) Unlink(header *InHeader, name string) (code Status) {
func (fs *lockingRawFileSystem) Unlink(cancel <-chan struct{}, header *InHeader, name string) (code Status) {
defer fs.locked()()
return fs.RawFS.Unlink(header, name)
return fs.RawFS.Unlink(cancel, header, name)
}
func (fs *lockingRawFileSystem) Rmdir(header *InHeader, name string) (code Status) {
func (fs *lockingRawFileSystem) Rmdir(cancel <-chan struct{}, header *InHeader, name string) (code Status) {
defer fs.locked()()
return fs.RawFS.Rmdir(header, name)
return fs.RawFS.Rmdir(cancel, header, name)
}
func (fs *lockingRawFileSystem) Symlink(header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status) {
func (fs *lockingRawFileSystem) Symlink(cancel <-chan struct{}, header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status) {
defer fs.locked()()
return fs.RawFS.Symlink(header, pointedTo, linkName, out)
return fs.RawFS.Symlink(cancel, header, pointedTo, linkName, out)
}
func (fs *lockingRawFileSystem) Rename(input *RenameIn, oldName string, newName string) (code Status) {
func (fs *lockingRawFileSystem) Rename(cancel <-chan struct{}, input *RenameIn, oldName string, newName string) (code Status) {
defer fs.locked()()
return fs.RawFS.Rename(input, oldName, newName)
return fs.RawFS.Rename(cancel, input, oldName, newName)
}
func (fs *lockingRawFileSystem) Link(input *LinkIn, name string, out *EntryOut) (code Status) {
func (fs *lockingRawFileSystem) Link(cancel <-chan struct{}, input *LinkIn, name string, out *EntryOut) (code Status) {
defer fs.locked()()
return fs.RawFS.Link(input, name, out)
return fs.RawFS.Link(cancel, input, name, out)
}
func (fs *lockingRawFileSystem) SetXAttr(input *SetXAttrIn, attr string, data []byte) Status {
func (fs *lockingRawFileSystem) SetXAttr(cancel <-chan struct{}, input *SetXAttrIn, attr string, data []byte) Status {
defer fs.locked()()
return fs.RawFS.SetXAttr(input, attr, data)
return fs.RawFS.SetXAttr(cancel, input, attr, data)
}
func (fs *lockingRawFileSystem) GetXAttrData(header *InHeader, attr string) (data []byte, code Status) {
func (fs *lockingRawFileSystem) GetXAttrData(cancel <-chan struct{}, header *InHeader, attr string) (data []byte, code Status) {
defer fs.locked()()
return fs.RawFS.GetXAttrData(header, attr)
return fs.RawFS.GetXAttrData(cancel, header, attr)
}
func (fs *lockingRawFileSystem) GetXAttrSize(header *InHeader, attr string) (sz int, code Status) {
func (fs *lockingRawFileSystem) GetXAttrSize(cancel <-chan struct{}, header *InHeader, attr string) (sz int, code Status) {
defer fs.locked()()
return fs.RawFS.GetXAttrSize(header, attr)
return fs.RawFS.GetXAttrSize(cancel, header, attr)
}
func (fs *lockingRawFileSystem) ListXAttr(header *InHeader) (data []byte, code Status) {
func (fs *lockingRawFileSystem) ListXAttr(cancel <-chan struct{}, header *InHeader) (data []byte, code Status) {
defer fs.locked()()
return fs.RawFS.ListXAttr(header)
return fs.RawFS.ListXAttr(cancel, header)
}
func (fs *lockingRawFileSystem) RemoveXAttr(header *InHeader, attr string) Status {
func (fs *lockingRawFileSystem) RemoveXAttr(cancel <-chan struct{}, header *InHeader, attr string) Status {
defer fs.locked()()
return fs.RawFS.RemoveXAttr(header, attr)
return fs.RawFS.RemoveXAttr(cancel, header, attr)
}
func (fs *lockingRawFileSystem) Access(input *AccessIn) (code Status) {
func (fs *lockingRawFileSystem) Access(cancel <-chan struct{}, input *AccessIn) (code Status) {
defer fs.locked()()
return fs.RawFS.Access(input)
return fs.RawFS.Access(cancel, input)
}
func (fs *lockingRawFileSystem) Create(input *CreateIn, name string, out *CreateOut) (code Status) {
func (fs *lockingRawFileSystem) Create(cancel <-chan struct{}, input *CreateIn, name string, out *CreateOut) (code Status) {
defer fs.locked()()
return fs.RawFS.Create(input, name, out)
return fs.RawFS.Create(cancel, input, name, out)
}
func (fs *lockingRawFileSystem) OpenDir(input *OpenIn, out *OpenOut) (status Status) {
func (fs *lockingRawFileSystem) OpenDir(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status) {
defer fs.locked()()
return fs.RawFS.OpenDir(input, out)
return fs.RawFS.OpenDir(cancel, input, out)
}
func (fs *lockingRawFileSystem) Release(input *ReleaseIn) {
......@@ -154,54 +154,54 @@ func (fs *lockingRawFileSystem) ReleaseDir(input *ReleaseIn) {
fs.RawFS.ReleaseDir(input)
}
func (fs *lockingRawFileSystem) Read(input *ReadIn, buf []byte) (ReadResult, Status) {
func (fs *lockingRawFileSystem) Read(cancel <-chan struct{}, input *ReadIn, buf []byte) (ReadResult, Status) {
defer fs.locked()()
return fs.RawFS.Read(input, buf)
return fs.RawFS.Read(cancel, input, buf)
}
func (fs *lockingRawFileSystem) GetLk(in *LkIn, out *LkOut) (code Status) {
func (fs *lockingRawFileSystem) GetLk(cancel <-chan struct{}, in *LkIn, out *LkOut) (code Status) {
defer fs.locked()()
return fs.RawFS.GetLk(in, out)
return fs.RawFS.GetLk(cancel, in, out)
}
func (fs *lockingRawFileSystem) SetLk(in *LkIn) (code Status) {
func (fs *lockingRawFileSystem) SetLk(cancel <-chan struct{}, in *LkIn) (code Status) {
defer fs.locked()()
return fs.RawFS.SetLk(in)
return fs.RawFS.SetLk(cancel, in)
}
func (fs *lockingRawFileSystem) SetLkw(in *LkIn) (code Status) {
func (fs *lockingRawFileSystem) SetLkw(cancel <-chan struct{}, in *LkIn) (code Status) {
defer fs.locked()()
return fs.RawFS.SetLkw(in)
return fs.RawFS.SetLkw(cancel, in)
}
func (fs *lockingRawFileSystem) Write(input *WriteIn, data []byte) (written uint32, code Status) {
func (fs *lockingRawFileSystem) Write(cancel <-chan struct{}, input *WriteIn, data []byte) (written uint32, code Status) {
defer fs.locked()()
return fs.RawFS.Write(input, data)
return fs.RawFS.Write(cancel, input, data)
}
func (fs *lockingRawFileSystem) Flush(input *FlushIn) Status {
func (fs *lockingRawFileSystem) Flush(cancel <-chan struct{}, input *FlushIn) Status {
defer fs.locked()()
return fs.RawFS.Flush(input)
return fs.RawFS.Flush(cancel, input)
}
func (fs *lockingRawFileSystem) Fsync(input *FsyncIn) (code Status) {
func (fs *lockingRawFileSystem) Fsync(cancel <-chan struct{}, input *FsyncIn) (code Status) {
defer fs.locked()()
return fs.RawFS.Fsync(input)
return fs.RawFS.Fsync(cancel, input)
}
func (fs *lockingRawFileSystem) ReadDir(input *ReadIn, out *DirEntryList) Status {
func (fs *lockingRawFileSystem) ReadDir(cancel <-chan struct{}, input *ReadIn, out *DirEntryList) Status {
defer fs.locked()()
return fs.RawFS.ReadDir(input, out)
return fs.RawFS.ReadDir(cancel, input, out)
}
func (fs *lockingRawFileSystem) ReadDirPlus(input *ReadIn, out *DirEntryList) Status {
func (fs *lockingRawFileSystem) ReadDirPlus(cancel <-chan struct{}, input *ReadIn, out *DirEntryList) Status {
defer fs.locked()()
return fs.RawFS.ReadDirPlus(input, out)
return fs.RawFS.ReadDirPlus(cancel, input, out)
}
func (fs *lockingRawFileSystem) FsyncDir(input *FsyncIn) (code Status) {
func (fs *lockingRawFileSystem) FsyncDir(cancel <-chan struct{}, input *FsyncIn) (code Status) {
defer fs.locked()()
return fs.RawFS.FsyncDir(input)
return fs.RawFS.FsyncDir(cancel, input)
}
func (fs *lockingRawFileSystem) Init(s *Server) {
......@@ -209,14 +209,14 @@ func (fs *lockingRawFileSystem) Init(s *Server) {
fs.RawFS.Init(s)
}
func (fs *lockingRawFileSystem) StatFs(header *InHeader, out *StatfsOut) (code Status) {
func (fs *lockingRawFileSystem) StatFs(cancel <-chan struct{}, header *InHeader, out *StatfsOut) (code Status) {
defer fs.locked()()
return fs.RawFS.StatFs(header, out)
return fs.RawFS.StatFs(cancel, header, out)
}
func (fs *lockingRawFileSystem) Fallocate(in *FallocateIn) (code Status) {
func (fs *lockingRawFileSystem) Fallocate(cancel <-chan struct{}, in *FallocateIn) (code Status) {
defer fs.locked()()
return fs.RawFS.Fallocate(in)
return fs.RawFS.Fallocate(cancel, in)
}
func (fs *lockingRawFileSystem) String() string {
......
......@@ -22,14 +22,14 @@ type connectorDir struct {
stream []fuse.DirEntry
}
func (d *connectorDir) ReadDir(input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
func (d *connectorDir) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
d.mu.Lock()
defer d.mu.Unlock()
// rewinddir() should be as if reopening directory.
// TODO - test this.
if d.stream == nil || input.Offset == 0 {
d.stream, code = d.node.OpenDir(&input.Context)
d.stream, code = d.node.OpenDir(&fuse.Context{Caller: input.Caller, Cancel: cancel})
if !code.Ok() {
return code
}
......@@ -58,13 +58,13 @@ func (d *connectorDir) ReadDir(input *fuse.ReadIn, out *fuse.DirEntryList) (code
return fuse.OK
}
func (d *connectorDir) ReadDirPlus(input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
func (d *connectorDir) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
d.mu.Lock()
defer d.mu.Unlock()
// rewinddir() should be as if reopening directory.
if d.stream == nil || input.Offset == 0 {
d.stream, code = d.node.OpenDir(&input.Context)
d.stream, code = d.node.OpenDir(&fuse.Context{Caller: input.Caller, Cancel: cancel})
if !code.Ok() {
return code
}
......@@ -98,7 +98,7 @@ func (d *connectorDir) ReadDirPlus(input *fuse.ReadIn, out *fuse.DirEntryList) (
continue
}
d.rawFS.Lookup(&input.InHeader, e.Name, entryDest)
d.rawFS.Lookup(cancel, &input.InHeader, e.Name, entryDest)
}
return fuse.OK
}
......
......@@ -230,7 +230,7 @@ func (c *FileSystemConnector) LookupNode(parent *Inode, path string) *Inode {
// This will not affect inode ID lookup counts, which
// are only update in response to kernel requests.
var dummy fuse.InHeader
child, _ := c.internalLookup(&a, parent, r, &dummy)
child, _ := c.internalLookup(nil, &a, parent, r, &dummy)
if child == nil {
return nil
}
......
......@@ -24,7 +24,7 @@ func (c *FileSystemConnector) RawFS() fuse.RawFileSystem {
type rawBridge FileSystemConnector
func (c *rawBridge) Fsync(input *fuse.FsyncIn) fuse.Status {
func (c *rawBridge) Fsync(cancel <-chan struct{}, input *fuse.FsyncIn) fuse.Status {
node := c.toInode(input.NodeId)
opened := node.mount.getOpenedFile(input.Fh)
......@@ -39,7 +39,7 @@ func (c *rawBridge) SetDebug(debug bool) {
c.fsConn().SetDebug(debug)
}
func (c *rawBridge) FsyncDir(input *fuse.FsyncIn) fuse.Status {
func (c *rawBridge) FsyncDir(cancel <-chan struct{}, input *fuse.FsyncIn) fuse.Status {
return fuse.ENOSYS
}
......@@ -74,7 +74,7 @@ func (c *FileSystemConnector) lookupMountUpdate(out *fuse.Attr, mount *fileSyste
}
// internalLookup executes a lookup without affecting NodeId reference counts.
func (c *FileSystemConnector) internalLookup(out *fuse.Attr, parent *Inode, name string, header *fuse.InHeader) (node *Inode, code fuse.Status) {
func (c *FileSystemConnector) internalLookup(cancel <-chan struct{}, out *fuse.Attr, parent *Inode, name string, header *fuse.InHeader) (node *Inode, code fuse.Status) {
// We may already know the child because it was created using Create or Mkdir,
// from an earlier lookup, or because the nodes were created in advance
......@@ -86,15 +86,15 @@ func (c *FileSystemConnector) internalLookup(out *fuse.Attr, parent *Inode, name
}
if child != nil && !parent.mount.options.LookupKnownChildren {
code = child.fsInode.GetAttr(out, nil, &header.Context)
code = child.fsInode.GetAttr(out, nil, &fuse.Context{Caller: header.Caller, Cancel: cancel})
} else {
child, code = parent.fsInode.Lookup(out, name, &header.Context)
child, code = parent.fsInode.Lookup(out, name, &fuse.Context{Caller: header.Caller, Cancel: cancel})
}
return child, code
}
func (c *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOut) (code fuse.Status) {
func (c *rawBridge) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name string, out *fuse.EntryOut) (code fuse.Status) {
// Prevent Lookup() and Forget() from running concurrently.
c.lookupLock.Lock()
defer c.lookupLock.Unlock()
......@@ -105,7 +105,7 @@ func (c *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOu
return fuse.ENOTDIR
}
child, code := c.fsConn().internalLookup(&out.Attr, parent, name, header)
child, code := c.fsConn().internalLookup(cancel, &out.Attr, parent, name, header)
if code == fuse.ENOENT && parent.mount.negativeEntry(out) {
return fuse.OK
}
......@@ -133,7 +133,7 @@ func (c *rawBridge) Forget(nodeID, nlookup uint64) {
c.fsConn().forgetUpdate(nodeID, int(nlookup))
}
func (c *rawBridge) GetAttr(input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
func (c *rawBridge) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
node := c.toInode(input.NodeId)
var f File
......@@ -144,7 +144,7 @@ func (c *rawBridge) GetAttr(input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse
}
dest := &out.Attr
code = node.fsInode.GetAttr(dest, f, &input.Context)
code = node.fsInode.GetAttr(dest, f, &fuse.Context{Caller: input.Caller, Cancel: cancel})
if !code.Ok() {
return code
}
......@@ -159,7 +159,7 @@ func (c *rawBridge) GetAttr(input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse
return fuse.OK
}
func (c *rawBridge) OpenDir(input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) {
func (c *rawBridge) OpenDir(cancel <-chan struct{}, input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) {
node := c.toInode(input.NodeId)
de := &connectorDir{
inode: node,
......@@ -172,21 +172,21 @@ func (c *rawBridge) OpenDir(input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.St
return fuse.OK
}
func (c *rawBridge) ReadDir(input *fuse.ReadIn, out *fuse.DirEntryList) fuse.Status {
func (c *rawBridge) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) fuse.Status {
node := c.toInode(input.NodeId)
opened := node.mount.getOpenedFile(input.Fh)
return opened.dir.ReadDir(input, out)
return opened.dir.ReadDir(cancel, input, out)
}
func (c *rawBridge) ReadDirPlus(input *fuse.ReadIn, out *fuse.DirEntryList) fuse.Status {
func (c *rawBridge) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) fuse.Status {
node := c.toInode(input.NodeId)
opened := node.mount.getOpenedFile(input.Fh)
return opened.dir.ReadDirPlus(input, out)
return opened.dir.ReadDirPlus(cancel, input, out)
}
func (c *rawBridge) Open(input *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) {
func (c *rawBridge) Open(cancel <-chan struct{}, input *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) {
node := c.toInode(input.NodeId)
f, code := node.fsInode.Open(input.Flags, &input.Context)
f, code := node.fsInode.Open(input.Flags, &fuse.Context{Caller: input.Caller, Cancel: cancel})
if !code.Ok() {
return code
}
......@@ -196,7 +196,7 @@ func (c *rawBridge) Open(input *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Sta
return fuse.OK
}
func (c *rawBridge) SetAttr(input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
func (c *rawBridge) SetAttr(cancel <-chan struct{}, input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse.Status) {
node := c.toInode(input.NodeId)
var f File
......@@ -207,17 +207,17 @@ func (c *rawBridge) SetAttr(input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse
}
if permissions, ok := input.GetMode(); ok {
code = node.fsInode.Chmod(f, permissions, &input.Context)
code = node.fsInode.Chmod(f, permissions, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
uid, uok := input.GetUID()
gid, gok := input.GetGID()
if code.Ok() && (uok || gok) {
code = node.fsInode.Chown(f, uid, gid, &input.Context)
code = node.fsInode.Chown(f, uid, gid, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
if sz, ok := input.GetSize(); code.Ok() && ok {
code = node.fsInode.Truncate(f, sz, &input.Context)
code = node.fsInode.Truncate(f, sz, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
atime, aok := input.GetATime()
......@@ -232,7 +232,7 @@ func (c *rawBridge) SetAttr(input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse
m = &mtime
}
code = node.fsInode.Utimens(f, a, m, &input.Context)
code = node.fsInode.Utimens(f, a, m, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
if !code.Ok() {
......@@ -242,69 +242,69 @@ func (c *rawBridge) SetAttr(input *fuse.SetAttrIn, out *fuse.AttrOut) (code fuse
// Must call GetAttr(); the filesystem may override some of
// the changes we effect here.
attr := &out.Attr
code = node.fsInode.GetAttr(attr, nil, &input.Context)
code = node.fsInode.GetAttr(attr, nil, &fuse.Context{Caller: input.Caller, Cancel: cancel})
if code.Ok() {
node.mount.fillAttr(out, input.NodeId)
}
return code
}
func (c *rawBridge) Fallocate(input *fuse.FallocateIn) (code fuse.Status) {
func (c *rawBridge) Fallocate(cancel <-chan struct{}, input *fuse.FallocateIn) (code fuse.Status) {
n := c.toInode(input.NodeId)
opened := n.mount.getOpenedFile(input.Fh)
return n.fsInode.Fallocate(opened, input.Offset, input.Length, input.Mode, &input.Context)
return n.fsInode.Fallocate(opened, input.Offset, input.Length, input.Mode, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) Readlink(header *fuse.InHeader) (out []byte, code fuse.Status) {
func (c *rawBridge) Readlink(cancel <-chan struct{}, header *fuse.InHeader) (out []byte, code fuse.Status) {
n := c.toInode(header.NodeId)
return n.fsInode.Readlink(&header.Context)
return n.fsInode.Readlink(&fuse.Context{Caller: header.Caller, Cancel: cancel})
}
func (c *rawBridge) Mknod(input *fuse.MknodIn, name string, out *fuse.EntryOut) (code fuse.Status) {
func (c *rawBridge) Mknod(cancel <-chan struct{}, input *fuse.MknodIn, name string, out *fuse.EntryOut) (code fuse.Status) {
parent := c.toInode(input.NodeId)
child, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), &input.Context)
child, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), &fuse.Context{Caller: input.Caller, Cancel: cancel})
if code.Ok() {
c.childLookup(out, child, &input.Context)
code = child.fsInode.GetAttr(&out.Attr, nil, &input.Context)
c.childLookup(out, child, &fuse.Context{Caller: input.Caller, Cancel: cancel})
code = child.fsInode.GetAttr(&out.Attr, nil, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
return code
}
func (c *rawBridge) Mkdir(input *fuse.MkdirIn, name string, out *fuse.EntryOut) (code fuse.Status) {
func (c *rawBridge) Mkdir(cancel <-chan struct{}, input *fuse.MkdirIn, name string, out *fuse.EntryOut) (code fuse.Status) {
parent := c.toInode(input.NodeId)
child, code := parent.fsInode.Mkdir(name, input.Mode, &input.Context)
child, code := parent.fsInode.Mkdir(name, input.Mode, &fuse.Context{Caller: input.Caller, Cancel: cancel})
if code.Ok() {
c.childLookup(out, child, &input.Context)
code = child.fsInode.GetAttr(&out.Attr, nil, &input.Context)
c.childLookup(out, child, &fuse.Context{Caller: input.Caller, Cancel: cancel})
code = child.fsInode.GetAttr(&out.Attr, nil, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
return code
}
func (c *rawBridge) Unlink(header *fuse.InHeader, name string) (code fuse.Status) {
func (c *rawBridge) Unlink(cancel <-chan struct{}, header *fuse.InHeader, name string) (code fuse.Status) {
parent := c.toInode(header.NodeId)
return parent.fsInode.Unlink(name, &header.Context)
return parent.fsInode.Unlink(name, &fuse.Context{Caller: header.Caller, Cancel: cancel})
}
func (c *rawBridge) Rmdir(header *fuse.InHeader, name string) (code fuse.Status) {
func (c *rawBridge) Rmdir(cancel <-chan struct{}, header *fuse.InHeader, name string) (code fuse.Status) {
parent := c.toInode(header.NodeId)
return parent.fsInode.Rmdir(name, &header.Context)
return parent.fsInode.Rmdir(name, &fuse.Context{Caller: header.Caller, Cancel: cancel})
}
func (c *rawBridge) Symlink(header *fuse.InHeader, pointedTo string, linkName string, out *fuse.EntryOut) (code fuse.Status) {
func (c *rawBridge) Symlink(cancel <-chan struct{}, header *fuse.InHeader, pointedTo string, linkName string, out *fuse.EntryOut) (code fuse.Status) {
parent := c.toInode(header.NodeId)
child, code := parent.fsInode.Symlink(linkName, pointedTo, &header.Context)
child, code := parent.fsInode.Symlink(linkName, pointedTo, &fuse.Context{Caller: header.Caller, Cancel: cancel})
if code.Ok() {
c.childLookup(out, child, &header.Context)
code = child.fsInode.GetAttr(&out.Attr, nil, &header.Context)
c.childLookup(out, child, &fuse.Context{Caller: header.Caller, Cancel: cancel})
code = child.fsInode.GetAttr(&out.Attr, nil, &fuse.Context{Caller: header.Caller, Cancel: cancel})
}
return code
}
func (c *rawBridge) Rename(input *fuse.RenameIn, oldName string, newName string) (code fuse.Status) {
func (c *rawBridge) Rename(cancel <-chan struct{}, input *fuse.RenameIn, oldName string, newName string) (code fuse.Status) {
if input.Flags != 0 {
return fuse.ENOSYS
}
......@@ -323,10 +323,10 @@ func (c *rawBridge) Rename(input *fuse.RenameIn, oldName string, newName string)
return fuse.EXDEV
}
return oldParent.fsInode.Rename(oldName, newParent.fsInode, newName, &input.Context)
return oldParent.fsInode.Rename(oldName, newParent.fsInode, newName, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) Link(input *fuse.LinkIn, name string, out *fuse.EntryOut) (code fuse.Status) {
func (c *rawBridge) Link(cancel <-chan struct{}, input *fuse.LinkIn, name string, out *fuse.EntryOut) (code fuse.Status) {
existing := c.toInode(input.Oldnodeid)
parent := c.toInode(input.NodeId)
......@@ -334,28 +334,28 @@ func (c *rawBridge) Link(input *fuse.LinkIn, name string, out *fuse.EntryOut) (c
return fuse.EXDEV
}
child, code := parent.fsInode.Link(name, existing.fsInode, &input.Context)
child, code := parent.fsInode.Link(name, existing.fsInode, &fuse.Context{Caller: input.Caller, Cancel: cancel})
if code.Ok() {
c.childLookup(out, child, &input.Context)
code = child.fsInode.GetAttr(&out.Attr, nil, &input.Context)
c.childLookup(out, child, &fuse.Context{Caller: input.Caller, Cancel: cancel})
code = child.fsInode.GetAttr(&out.Attr, nil, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
return code
}
func (c *rawBridge) Access(input *fuse.AccessIn) (code fuse.Status) {
func (c *rawBridge) Access(cancel <-chan struct{}, input *fuse.AccessIn) (code fuse.Status) {
n := c.toInode(input.NodeId)
return n.fsInode.Access(input.Mask, &input.Context)
return n.fsInode.Access(input.Mask, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) Create(input *fuse.CreateIn, name string, out *fuse.CreateOut) (code fuse.Status) {
func (c *rawBridge) Create(cancel <-chan struct{}, input *fuse.CreateIn, name string, out *fuse.CreateOut) (code fuse.Status) {
parent := c.toInode(input.NodeId)
f, child, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, &input.Context)
f, child, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, &fuse.Context{Caller: input.Caller, Cancel: cancel})
if !code.Ok() {
return code
}
c.childLookup(&out.EntryOut, child, &input.Context)
c.childLookup(&out.EntryOut, child, &fuse.Context{Caller: input.Caller, Cancel: cancel})
handle, opened := parent.mount.registerFileHandle(child, nil, f, input.Flags)
out.OpenOut.OpenFlags = opened.FuseFlags
......@@ -378,30 +378,30 @@ func (c *rawBridge) ReleaseDir(input *fuse.ReleaseIn) {
}
}
func (c *rawBridge) GetXAttrSize(header *fuse.InHeader, attribute string) (sz int, code fuse.Status) {
func (c *rawBridge) GetXAttrSize(cancel <-chan struct{}, header *fuse.InHeader, attribute string) (sz int, code fuse.Status) {
node := c.toInode(header.NodeId)
data, errno := node.fsInode.GetXAttr(attribute, &header.Context)
data, errno := node.fsInode.GetXAttr(attribute, &fuse.Context{Caller: header.Caller, Cancel: cancel})
return len(data), errno
}
func (c *rawBridge) GetXAttrData(header *fuse.InHeader, attribute string) (data []byte, code fuse.Status) {
func (c *rawBridge) GetXAttrData(cancel <-chan struct{}, header *fuse.InHeader, attribute string) (data []byte, code fuse.Status) {
node := c.toInode(header.NodeId)
return node.fsInode.GetXAttr(attribute, &header.Context)
return node.fsInode.GetXAttr(attribute, &fuse.Context{Caller: header.Caller, Cancel: cancel})
}
func (c *rawBridge) RemoveXAttr(header *fuse.InHeader, attr string) fuse.Status {
func (c *rawBridge) RemoveXAttr(cancel <-chan struct{}, header *fuse.InHeader, attr string) fuse.Status {
node := c.toInode(header.NodeId)
return node.fsInode.RemoveXAttr(attr, &header.Context)
return node.fsInode.RemoveXAttr(attr, &fuse.Context{Caller: header.Caller, Cancel: cancel})
}
func (c *rawBridge) SetXAttr(input *fuse.SetXAttrIn, attr string, data []byte) fuse.Status {
func (c *rawBridge) SetXAttr(cancel <-chan struct{}, input *fuse.SetXAttrIn, attr string, data []byte) fuse.Status {
node := c.toInode(input.NodeId)
return node.fsInode.SetXAttr(attr, data, int(input.Flags), &input.Context)
return node.fsInode.SetXAttr(attr, data, int(input.Flags), &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) ListXAttr(header *fuse.InHeader) (data []byte, code fuse.Status) {
func (c *rawBridge) ListXAttr(cancel <-chan struct{}, header *fuse.InHeader) (data []byte, code fuse.Status) {
node := c.toInode(header.NodeId)
attrs, code := node.fsInode.ListXAttr(&header.Context)
attrs, code := node.fsInode.ListXAttr(&fuse.Context{Caller: header.Caller, Cancel: cancel})
if code != fuse.OK {
return nil, code
}
......@@ -418,7 +418,7 @@ func (c *rawBridge) ListXAttr(header *fuse.InHeader) (data []byte, code fuse.Sta
////////////////
// files.
func (c *rawBridge) Write(input *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
func (c *rawBridge) Write(cancel <-chan struct{}, input *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
node := c.toInode(input.NodeId)
opened := node.mount.getOpenedFile(input.Fh)
......@@ -427,10 +427,10 @@ func (c *rawBridge) Write(input *fuse.WriteIn, data []byte) (written uint32, cod
f = opened.WithFlags.File
}
return node.Node().Write(f, data, int64(input.Offset), &input.Context)
return node.Node().Write(f, data, int64(input.Offset), &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) Read(input *fuse.ReadIn, buf []byte) (fuse.ReadResult, fuse.Status) {
func (c *rawBridge) Read(cancel <-chan struct{}, input *fuse.ReadIn, buf []byte) (fuse.ReadResult, fuse.Status) {
node := c.toInode(input.NodeId)
opened := node.mount.getOpenedFile(input.Fh)
......@@ -439,31 +439,31 @@ func (c *rawBridge) Read(input *fuse.ReadIn, buf []byte) (fuse.ReadResult, fuse.
f = opened.WithFlags.File
}
return node.Node().Read(f, buf, int64(input.Offset), &input.Context)
return node.Node().Read(f, buf, int64(input.Offset), &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) GetLk(input *fuse.LkIn, out *fuse.LkOut) (code fuse.Status) {
func (c *rawBridge) GetLk(cancel <-chan struct{}, input *fuse.LkIn, out *fuse.LkOut) (code fuse.Status) {
n := c.toInode(input.NodeId)
opened := n.mount.getOpenedFile(input.Fh)
return n.fsInode.GetLk(opened, input.Owner, &input.Lk, input.LkFlags, &out.Lk, &input.Context)
return n.fsInode.GetLk(opened, input.Owner, &input.Lk, input.LkFlags, &out.Lk, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) SetLk(input *fuse.LkIn) (code fuse.Status) {
func (c *rawBridge) SetLk(cancel <-chan struct{}, input *fuse.LkIn) (code fuse.Status) {
n := c.toInode(input.NodeId)
opened := n.mount.getOpenedFile(input.Fh)
return n.fsInode.SetLk(opened, input.Owner, &input.Lk, input.LkFlags, &input.Context)
return n.fsInode.SetLk(opened, input.Owner, &input.Lk, input.LkFlags, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) SetLkw(input *fuse.LkIn) (code fuse.Status) {
func (c *rawBridge) SetLkw(cancel <-chan struct{}, input *fuse.LkIn) (code fuse.Status) {
n := c.toInode(input.NodeId)
opened := n.mount.getOpenedFile(input.Fh)
return n.fsInode.SetLkw(opened, input.Owner, &input.Lk, input.LkFlags, &input.Context)
return n.fsInode.SetLkw(opened, input.Owner, &input.Lk, input.LkFlags, &fuse.Context{Caller: input.Caller, Cancel: cancel})
}
func (c *rawBridge) StatFs(header *fuse.InHeader, out *fuse.StatfsOut) fuse.Status {
func (c *rawBridge) StatFs(cancel <-chan struct{}, header *fuse.InHeader, out *fuse.StatfsOut) fuse.Status {
node := c.toInode(header.NodeId)
s := node.Node().StatFs()
if s == nil {
......@@ -473,7 +473,7 @@ func (c *rawBridge) StatFs(header *fuse.InHeader, out *fuse.StatfsOut) fuse.Stat
return fuse.OK
}
func (c *rawBridge) Flush(input *fuse.FlushIn) fuse.Status {
func (c *rawBridge) Flush(cancel <-chan struct{}, input *fuse.FlushIn) fuse.Status {
node := c.toInode(input.NodeId)
opened := node.mount.getOpenedFile(input.Fh)
......
......@@ -129,7 +129,7 @@ func doInit(server *Server, req *request) {
func doOpen(server *Server, req *request) {
out := (*OpenOut)(req.outData())
status := server.fileSystem.Open((*OpenIn)(req.inData), out)
status := server.fileSystem.Open(req.cancel, (*OpenIn)(req.inData), out)
req.status = status
if status != OK {
return
......@@ -138,7 +138,7 @@ func doOpen(server *Server, req *request) {
func doCreate(server *Server, req *request) {
out := (*CreateOut)(req.outData())
status := server.fileSystem.Create((*CreateIn)(req.inData), req.filenames[0], out)
status := server.fileSystem.Create(req.cancel, (*CreateIn)(req.inData), req.filenames[0], out)
req.status = status
}
......@@ -147,7 +147,7 @@ func doReadDir(server *Server, req *request) {
buf := server.allocOut(req, in.Size)
out := NewDirEntryList(buf, uint64(in.Offset))
code := server.fileSystem.ReadDir(in, out)
code := server.fileSystem.ReadDir(req.cancel, in, out)
req.flatData = out.bytes()
req.status = code
}
......@@ -157,24 +157,24 @@ func doReadDirPlus(server *Server, req *request) {
buf := server.allocOut(req, in.Size)
out := NewDirEntryList(buf, uint64(in.Offset))
code := server.fileSystem.ReadDirPlus(in, out)
code := server.fileSystem.ReadDirPlus(req.cancel, in, out)
req.flatData = out.bytes()
req.status = code
}
func doOpenDir(server *Server, req *request) {
out := (*OpenOut)(req.outData())
status := server.fileSystem.OpenDir((*OpenIn)(req.inData), out)
status := server.fileSystem.OpenDir(req.cancel, (*OpenIn)(req.inData), out)
req.status = status
}
func doSetattr(server *Server, req *request) {
out := (*AttrOut)(req.outData())
req.status = server.fileSystem.SetAttr((*SetAttrIn)(req.inData), out)
req.status = server.fileSystem.SetAttr(req.cancel, (*SetAttrIn)(req.inData), out)
}
func doWrite(server *Server, req *request) {
n, status := server.fileSystem.Write((*WriteIn)(req.inData), req.arg)
n, status := server.fileSystem.Write(req.cancel, (*WriteIn)(req.inData), req.arg)
o := (*WriteOut)(req.outData())
o.Size = n
req.status = status
......@@ -246,14 +246,14 @@ func doGetXAttr(server *Server, req *request) {
// TODO(hanwen): double check this. For getxattr, input.Size
// field refers to the size of the attribute, so it usually
// is not 0.
sz, code := server.fileSystem.GetXAttrSize(req.inHeader, req.filenames[0])
sz, code := server.fileSystem.GetXAttrSize(req.cancel, req.inHeader, req.filenames[0])
if code.Ok() {
out.Size = uint32(sz)
}
req.status = code
return
case _OP_LISTXATTR:
data, code := server.fileSystem.ListXAttr(req.inHeader)
data, code := server.fileSystem.ListXAttr(req.cancel, req.inHeader)
if code.Ok() {
out.Size = uint32(len(data))
}
......@@ -264,9 +264,9 @@ func doGetXAttr(server *Server, req *request) {
var data []byte
switch req.inHeader.Opcode {
case _OP_GETXATTR:
data, req.status = server.fileSystem.GetXAttrData(req.inHeader, req.filenames[0])
data, req.status = server.fileSystem.GetXAttrData(req.cancel, req.inHeader, req.filenames[0])
case _OP_LISTXATTR:
data, req.status = server.fileSystem.ListXAttr(req.inHeader)
data, req.status = server.fileSystem.ListXAttr(req.cancel, req.inHeader)
default:
log.Panicf("xattr opcode %v", req.inHeader.Opcode)
req.status = ENOSYS
......@@ -285,7 +285,7 @@ func doGetXAttr(server *Server, req *request) {
func doGetAttr(server *Server, req *request) {
out := (*AttrOut)(req.outData())
s := server.fileSystem.GetAttr((*GetAttrIn)(req.inData), out)
s := server.fileSystem.GetAttr(req.cancel, (*GetAttrIn)(req.inData), out)
req.status = s
}
......@@ -326,44 +326,44 @@ func doBatchForget(server *Server, req *request) {
}
func doReadlink(server *Server, req *request) {
req.flatData, req.status = server.fileSystem.Readlink(req.inHeader)
req.flatData, req.status = server.fileSystem.Readlink(req.cancel, req.inHeader)
}
func doLookup(server *Server, req *request) {
out := (*EntryOut)(req.outData())
s := server.fileSystem.Lookup(req.inHeader, req.filenames[0], out)
s := server.fileSystem.Lookup(req.cancel, req.inHeader, req.filenames[0], out)
req.status = s
}
func doMknod(server *Server, req *request) {
out := (*EntryOut)(req.outData())
req.status = server.fileSystem.Mknod((*MknodIn)(req.inData), req.filenames[0], out)
req.status = server.fileSystem.Mknod(req.cancel, (*MknodIn)(req.inData), req.filenames[0], out)
}
func doMkdir(server *Server, req *request) {
out := (*EntryOut)(req.outData())
req.status = server.fileSystem.Mkdir((*MkdirIn)(req.inData), req.filenames[0], out)
req.status = server.fileSystem.Mkdir(req.cancel, (*MkdirIn)(req.inData), req.filenames[0], out)
}
func doUnlink(server *Server, req *request) {
req.status = server.fileSystem.Unlink(req.inHeader, req.filenames[0])
req.status = server.fileSystem.Unlink(req.cancel, req.inHeader, req.filenames[0])
}
func doRmdir(server *Server, req *request) {
req.status = server.fileSystem.Rmdir(req.inHeader, req.filenames[0])
req.status = server.fileSystem.Rmdir(req.cancel, req.inHeader, req.filenames[0])
}
func doLink(server *Server, req *request) {
out := (*EntryOut)(req.outData())
req.status = server.fileSystem.Link((*LinkIn)(req.inData), req.filenames[0], out)
req.status = server.fileSystem.Link(req.cancel, (*LinkIn)(req.inData), req.filenames[0], out)
}
func doRead(server *Server, req *request) {
in := (*ReadIn)(req.inData)
buf := server.allocOut(req, in.Size)
req.readResult, req.status = server.fileSystem.Read(in, buf)
req.readResult, req.status = server.fileSystem.Read(req.cancel, in, buf)
if fd, ok := req.readResult.(*readResultFd); ok {
req.fdData = fd
req.flatData = nil
......@@ -373,7 +373,7 @@ func doRead(server *Server, req *request) {
}
func doFlush(server *Server, req *request) {
req.status = server.fileSystem.Flush((*FlushIn)(req.inData))
req.status = server.fileSystem.Flush(req.cancel, (*FlushIn)(req.inData))
}
func doRelease(server *Server, req *request) {
......@@ -381,7 +381,7 @@ func doRelease(server *Server, req *request) {
}
func doFsync(server *Server, req *request) {
req.status = server.fileSystem.Fsync((*FsyncIn)(req.inData))
req.status = server.fileSystem.Fsync(req.cancel, (*FsyncIn)(req.inData))
}
func doReleaseDir(server *Server, req *request) {
......@@ -389,25 +389,25 @@ func doReleaseDir(server *Server, req *request) {
}
func doFsyncDir(server *Server, req *request) {
req.status = server.fileSystem.FsyncDir((*FsyncIn)(req.inData))
req.status = server.fileSystem.FsyncDir(req.cancel, (*FsyncIn)(req.inData))
}
func doSetXAttr(server *Server, req *request) {
splits := bytes.SplitN(req.arg, []byte{0}, 2)
req.status = server.fileSystem.SetXAttr((*SetXAttrIn)(req.inData), string(splits[0]), splits[1])
req.status = server.fileSystem.SetXAttr(req.cancel, (*SetXAttrIn)(req.inData), string(splits[0]), splits[1])
}
func doRemoveXAttr(server *Server, req *request) {
req.status = server.fileSystem.RemoveXAttr(req.inHeader, req.filenames[0])
req.status = server.fileSystem.RemoveXAttr(req.cancel, req.inHeader, req.filenames[0])
}
func doAccess(server *Server, req *request) {
req.status = server.fileSystem.Access((*AccessIn)(req.inData))
req.status = server.fileSystem.Access(req.cancel, (*AccessIn)(req.inData))
}
func doSymlink(server *Server, req *request) {
out := (*EntryOut)(req.outData())
req.status = server.fileSystem.Symlink(req.inHeader, req.filenames[1], req.filenames[0], out)
req.status = server.fileSystem.Symlink(req.cancel, req.inHeader, req.filenames[1], req.filenames[0], out)
}
func doRename(server *Server, req *request) {
......@@ -416,16 +416,16 @@ func doRename(server *Server, req *request) {
InHeader: in1.InHeader,
Newdir: in1.Newdir,
}
req.status = server.fileSystem.Rename(&in, req.filenames[0], req.filenames[1])
req.status = server.fileSystem.Rename(req.cancel, &in, req.filenames[0], req.filenames[1])
}
func doRename2(server *Server, req *request) {
req.status = server.fileSystem.Rename((*RenameIn)(req.inData), req.filenames[0], req.filenames[1])
req.status = server.fileSystem.Rename(req.cancel, (*RenameIn)(req.inData), req.filenames[0], req.filenames[1])
}
func doStatFs(server *Server, req *request) {
out := (*StatfsOut)(req.outData())
req.status = server.fileSystem.StatFs(req.inHeader, out)
req.status = server.fileSystem.StatFs(req.cancel, req.inHeader, out)
if req.status == ENOSYS && runtime.GOOS == "darwin" {
// OSX FUSE requires Statfs to be implemented for the
// mount to succeed.
......@@ -443,19 +443,19 @@ func doDestroy(server *Server, req *request) {
}
func doFallocate(server *Server, req *request) {
req.status = server.fileSystem.Fallocate((*FallocateIn)(req.inData))
req.status = server.fileSystem.Fallocate(req.cancel, (*FallocateIn)(req.inData))
}
func doGetLk(server *Server, req *request) {
req.status = server.fileSystem.GetLk((*LkIn)(req.inData), (*LkOut)(req.outData()))
req.status = server.fileSystem.GetLk(req.cancel, (*LkIn)(req.inData), (*LkOut)(req.outData()))
}
func doSetLk(server *Server, req *request) {
req.status = server.fileSystem.SetLk((*LkIn)(req.inData))
req.status = server.fileSystem.SetLk(req.cancel, (*LkIn)(req.inData))
}
func doSetLkw(server *Server, req *request) {
req.status = server.fileSystem.SetLkw((*LkIn)(req.inData))
req.status = server.fileSystem.SetLkw(req.cancel, (*LkIn)(req.inData))
}
func doInterrupt(server *Server, req *request) {
......
......@@ -29,6 +29,9 @@ const (
// EAGAIN Resource temporarily unavailable
EAGAIN = Status(syscall.EAGAIN)
// EINTR Call was interrupted
EINTR = Status(syscall.EINTR)
// EINVAL Invalid argument
EINVAL = Status(syscall.EINVAL)
......@@ -541,7 +544,7 @@ type CreateOut struct {
OpenOut
}
type Context struct {
type Caller struct {
Owner
Pid uint32
}
......@@ -551,7 +554,7 @@ type InHeader struct {
Opcode int32
Unique uint64
NodeId uint64
Context
Caller
Padding uint32
}
......
......@@ -38,21 +38,31 @@ func (fs *wrappingFS) SetDebug(dbg bool) {
}
}
func (fs *wrappingFS) StatFs(header *InHeader, out *StatfsOut) Status {
func (fs *wrappingFS) StatFs(cancel <-chan struct{}, header *InHeader, out *StatfsOut) Status {
if s, ok := fs.fs.(interface {
StatFs(header *InHeader, out *StatfsOut) Status
}); ok {
return s.StatFs(header, out)
}
if s, ok := fs.fs.(interface {
StatFs(cancel <-chan struct{}, header *InHeader, out *StatfsOut) Status
}); ok {
return s.StatFs(cancel, header, out)
}
return ENOSYS
}
func (fs *wrappingFS) Lookup(header *InHeader, name string, out *EntryOut) (code Status) {
func (fs *wrappingFS) Lookup(cancel <-chan struct{}, header *InHeader, name string, out *EntryOut) (code Status) {
if s, ok := fs.fs.(interface {
Lookup(header *InHeader, name string, out *EntryOut) (code Status)
}); ok {
return s.Lookup(header, name, out)
}
if s, ok := fs.fs.(interface {
Lookup(cancel <-chan struct{}, header *InHeader, name string, out *EntryOut) (code Status)
}); ok {
return s.Lookup(cancel, header, name, out)
}
return ENOSYS
}
......@@ -64,210 +74,325 @@ func (fs *wrappingFS) Forget(nodeID, nlookup uint64) {
}
}
func (fs *wrappingFS) GetAttr(input *GetAttrIn, out *AttrOut) (code Status) {
func (fs *wrappingFS) GetAttr(cancel <-chan struct{}, input *GetAttrIn, out *AttrOut) (code Status) {
if s, ok := fs.fs.(interface {
GetAttr(input *GetAttrIn, out *AttrOut) (code Status)
}); ok {
return s.GetAttr(input, out)
}
if s, ok := fs.fs.(interface {
GetAttr(cancel <-chan struct{}, input *GetAttrIn, out *AttrOut) (code Status)
}); ok {
return s.GetAttr(cancel, input, out)
}
return ENOSYS
}
func (fs *wrappingFS) Open(input *OpenIn, out *OpenOut) (status Status) {
func (fs *wrappingFS) Open(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status) {
if s, ok := fs.fs.(interface {
Open(input *OpenIn, out *OpenOut) (status Status)
}); ok {
return s.Open(input, out)
}
if s, ok := fs.fs.(interface {
Open(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status)
}); ok {
return s.Open(cancel, input, out)
}
return ENOSYS
}
func (fs *wrappingFS) SetAttr(input *SetAttrIn, out *AttrOut) (code Status) {
func (fs *wrappingFS) SetAttr(cancel <-chan struct{}, input *SetAttrIn, out *AttrOut) (code Status) {
if s, ok := fs.fs.(interface {
SetAttr(input *SetAttrIn, out *AttrOut) (code Status)
}); ok {
return s.SetAttr(input, out)
}
if s, ok := fs.fs.(interface {
SetAttr(cancel <-chan struct{}, input *SetAttrIn, out *AttrOut) (code Status)
}); ok {
return s.SetAttr(cancel, input, out)
}
return ENOSYS
}
func (fs *wrappingFS) Readlink(header *InHeader) (out []byte, code Status) {
func (fs *wrappingFS) Readlink(cancel <-chan struct{}, header *InHeader) (out []byte, code Status) {
if s, ok := fs.fs.(interface {
Readlink(header *InHeader) (out []byte, code Status)
}); ok {
return s.Readlink(header)
}
if s, ok := fs.fs.(interface {
Readlink(cancel <-chan struct{}, header *InHeader) (out []byte, code Status)
}); ok {
return s.Readlink(cancel, header)
}
return nil, ENOSYS
}
func (fs *wrappingFS) Mknod(input *MknodIn, name string, out *EntryOut) (code Status) {
func (fs *wrappingFS) Mknod(cancel <-chan struct{}, input *MknodIn, name string, out *EntryOut) (code Status) {
if s, ok := fs.fs.(interface {
Mknod(input *MknodIn, name string, out *EntryOut) (code Status)
}); ok {
return s.Mknod(input, name, out)
}
if s, ok := fs.fs.(interface {
Mknod(cancel <-chan struct{}, input *MknodIn, name string, out *EntryOut) (code Status)
}); ok {
return s.Mknod(cancel, input, name, out)
}
return ENOSYS
}
func (fs *wrappingFS) Mkdir(input *MkdirIn, name string, out *EntryOut) (code Status) {
func (fs *wrappingFS) Mkdir(cancel <-chan struct{}, input *MkdirIn, name string, out *EntryOut) (code Status) {
if s, ok := fs.fs.(interface {
Mkdir(input *MkdirIn, name string, out *EntryOut) (code Status)
}); ok {
return s.Mkdir(input, name, out)
}
if s, ok := fs.fs.(interface {
Mkdir(cancel <-chan struct{}, input *MkdirIn, name string, out *EntryOut) (code Status)
}); ok {
return s.Mkdir(cancel, input, name, out)
}
return ENOSYS
}
func (fs *wrappingFS) Unlink(header *InHeader, name string) (code Status) {
func (fs *wrappingFS) Unlink(cancel <-chan struct{}, header *InHeader, name string) (code Status) {
if s, ok := fs.fs.(interface {
Unlink(header *InHeader, name string) (code Status)
}); ok {
return s.Unlink(header, name)
}
if s, ok := fs.fs.(interface {
Unlink(cancel <-chan struct{}, header *InHeader, name string) (code Status)
}); ok {
return s.Unlink(cancel, header, name)
}
return ENOSYS
}
func (fs *wrappingFS) Rmdir(header *InHeader, name string) (code Status) {
func (fs *wrappingFS) Rmdir(cancel <-chan struct{}, header *InHeader, name string) (code Status) {
if s, ok := fs.fs.(interface {
Rmdir(header *InHeader, name string) (code Status)
}); ok {
return s.Rmdir(header, name)
}
if s, ok := fs.fs.(interface {
Rmdir(cancel <-chan struct{}, header *InHeader, name string) (code Status)
}); ok {
return s.Rmdir(cancel, header, name)
}
return ENOSYS
}
func (fs *wrappingFS) Symlink(header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status) {
func (fs *wrappingFS) Symlink(cancel <-chan struct{}, header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status) {
if s, ok := fs.fs.(interface {
Symlink(header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status)
}); ok {
return s.Symlink(header, pointedTo, linkName, out)
}
if s, ok := fs.fs.(interface {
Symlink(cancel <-chan struct{}, header *InHeader, pointedTo string, linkName string, out *EntryOut) (code Status)
}); ok {
return s.Symlink(cancel, header, pointedTo, linkName, out)
}
return ENOSYS
}
func (fs *wrappingFS) Rename(input *RenameIn, oldName string, newName string) (code Status) {
func (fs *wrappingFS) Rename(cancel <-chan struct{}, input *RenameIn, oldName string, newName string) (code Status) {
if s, ok := fs.fs.(interface {
Rename(input *RenameIn, oldName string, newName string) (code Status)
}); ok {
return s.Rename(input, oldName, newName)
}
if s, ok := fs.fs.(interface {
Rename(cancel <-chan struct{}, input *RenameIn, oldName string, newName string) (code Status)
}); ok {
return s.Rename(cancel, input, oldName, newName)
}
return ENOSYS
}
func (fs *wrappingFS) Link(input *LinkIn, name string, out *EntryOut) (code Status) {
func (fs *wrappingFS) Link(cancel <-chan struct{}, input *LinkIn, name string, out *EntryOut) (code Status) {
if s, ok := fs.fs.(interface {
Link(input *LinkIn, name string, out *EntryOut) (code Status)
}); ok {
return s.Link(input, name, out)
}
if s, ok := fs.fs.(interface {
Link(cancel <-chan struct{}, input *LinkIn, name string, out *EntryOut) (code Status)
}); ok {
return s.Link(cancel, input, name, out)
}
return ENOSYS
}
func (fs *wrappingFS) GetXAttrSize(header *InHeader, attr string) (size int, code Status) {
func (fs *wrappingFS) GetXAttrSize(cancel <-chan struct{}, header *InHeader, attr string) (size int, code Status) {
if s, ok := fs.fs.(interface {
GetXAttrSize(header *InHeader, attr string) (size int, code Status)
}); ok {
return s.GetXAttrSize(header, attr)
}
if s, ok := fs.fs.(interface {
GetXAttrSize(cancel <-chan struct{}, header *InHeader, attr string) (size int, code Status)
}); ok {
return s.GetXAttrSize(cancel, header, attr)
}
return 0, ENOSYS
}
func (fs *wrappingFS) GetXAttrData(header *InHeader, attr string) (data []byte, code Status) {
func (fs *wrappingFS) GetXAttrData(cancel <-chan struct{}, header *InHeader, attr string) (data []byte, code Status) {
if s, ok := fs.fs.(interface {
GetXAttrData(header *InHeader, attr string) (data []byte, code Status)
}); ok {
return s.GetXAttrData(header, attr)
}
if s, ok := fs.fs.(interface {
GetXAttrData(cancel <-chan struct{}, header *InHeader, attr string) (data []byte, code Status)
}); ok {
return s.GetXAttrData(cancel, header, attr)
}
return nil, ENOSYS
}
func (fs *wrappingFS) SetXAttr(input *SetXAttrIn, attr string, data []byte) Status {
func (fs *wrappingFS) SetXAttr(cancel <-chan struct{}, input *SetXAttrIn, attr string, data []byte) Status {
if s, ok := fs.fs.(interface {
SetXAttr(input *SetXAttrIn, attr string, data []byte) Status
}); ok {
return s.SetXAttr(input, attr, data)
}
if s, ok := fs.fs.(interface {
SetXAttr(cancel <-chan struct{}, input *SetXAttrIn, attr string, data []byte) Status
}); ok {
return s.SetXAttr(cancel, input, attr, data)
}
return ENOSYS
}
func (fs *wrappingFS) ListXAttr(header *InHeader) (data []byte, code Status) {
func (fs *wrappingFS) ListXAttr(cancel <-chan struct{}, header *InHeader) (data []byte, code Status) {
if s, ok := fs.fs.(interface {
ListXAttr(header *InHeader) (data []byte, code Status)
}); ok {
return s.ListXAttr(header)
}
if s, ok := fs.fs.(interface {
ListXAttr(cancel <-chan struct{}, header *InHeader) (data []byte, code Status)
}); ok {
return s.ListXAttr(cancel, header)
}
return nil, ENOSYS
}
func (fs *wrappingFS) RemoveXAttr(header *InHeader, attr string) Status {
func (fs *wrappingFS) RemoveXAttr(cancel <-chan struct{}, header *InHeader, attr string) Status {
if s, ok := fs.fs.(interface {
RemoveXAttr(header *InHeader, attr string) Status
}); ok {
return s.RemoveXAttr(header, attr)
}
if s, ok := fs.fs.(interface {
RemoveXAttr(cancel <-chan struct{}, header *InHeader, attr string) Status
}); ok {
return s.RemoveXAttr(cancel, header, attr)
}
return ENOSYS
}
func (fs *wrappingFS) Access(input *AccessIn) (code Status) {
func (fs *wrappingFS) Access(cancel <-chan struct{}, input *AccessIn) (code Status) {
if s, ok := fs.fs.(interface {
Access(input *AccessIn) (code Status)
}); ok {
return s.Access(input)
}
if s, ok := fs.fs.(interface {
Access(cancel <-chan struct{}, input *AccessIn) (code Status)
}); ok {
return s.Access(cancel, input)
}
return ENOSYS
}
func (fs *wrappingFS) Create(input *CreateIn, name string, out *CreateOut) (code Status) {
func (fs *wrappingFS) Create(cancel <-chan struct{}, input *CreateIn, name string, out *CreateOut) (code Status) {
if s, ok := fs.fs.(interface {
Create(input *CreateIn, name string, out *CreateOut) (code Status)
}); ok {
return s.Create(input, name, out)
}
if s, ok := fs.fs.(interface {
Create(cancel <-chan struct{}, input *CreateIn, name string, out *CreateOut) (code Status)
}); ok {
return s.Create(cancel, input, name, out)
}
return ENOSYS
}
func (fs *wrappingFS) OpenDir(input *OpenIn, out *OpenOut) (status Status) {
func (fs *wrappingFS) OpenDir(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status) {
if s, ok := fs.fs.(interface {
OpenDir(input *OpenIn, out *OpenOut) (status Status)
}); ok {
return s.OpenDir(input, out)
}
if s, ok := fs.fs.(interface {
OpenDir(cancel <-chan struct{}, input *OpenIn, out *OpenOut) (status Status)
}); ok {
return s.OpenDir(cancel, input, out)
}
return ENOSYS
}
func (fs *wrappingFS) Read(input *ReadIn, buf []byte) (ReadResult, Status) {
func (fs *wrappingFS) Read(cancel <-chan struct{}, input *ReadIn, buf []byte) (ReadResult, Status) {
if s, ok := fs.fs.(interface {
Read(input *ReadIn, buf []byte) (ReadResult, Status)
}); ok {
return s.Read(input, buf)
}
if s, ok := fs.fs.(interface {
Read(cancel <-chan struct{}, input *ReadIn, buf []byte) (ReadResult, Status)
}); ok {
return s.Read(cancel, input, buf)
}
return nil, ENOSYS
}
func (fs *wrappingFS) GetLk(in *LkIn, out *LkOut) (code Status) {
func (fs *wrappingFS) GetLk(cancel <-chan struct{}, in *LkIn, out *LkOut) (code Status) {
if s, ok := fs.fs.(interface {
GetLk(in *LkIn, out *LkOut) (code Status)
}); ok {
return s.GetLk(in, out)
}
if s, ok := fs.fs.(interface {
GetLk(cancel <-chan struct{}, in *LkIn, out *LkOut) (code Status)
}); ok {
return s.GetLk(cancel, in, out)
}
return ENOSYS
}
func (fs *wrappingFS) SetLk(in *LkIn) (code Status) {
func (fs *wrappingFS) SetLk(cancel <-chan struct{}, in *LkIn) (code Status) {
if s, ok := fs.fs.(interface {
SetLk(in *LkIn) (code Status)
}); ok {
return s.SetLk(in)
}
if s, ok := fs.fs.(interface {
SetLk(cancel <-chan struct{}, in *LkIn) (code Status)
}); ok {
return s.SetLk(cancel, in)
}
return ENOSYS
}
func (fs *wrappingFS) SetLkw(in *LkIn) (code Status) {
func (fs *wrappingFS) SetLkw(cancel <-chan struct{}, in *LkIn) (code Status) {
if s, ok := fs.fs.(interface {
SetLkw(in *LkIn) (code Status)
}); ok {
return s.SetLkw(in)
}
if s, ok := fs.fs.(interface {
SetLkw(cancel <-chan struct{}, in *LkIn) (code Status)
}); ok {
return s.SetLkw(cancel, in)
}
return ENOSYS
}
......@@ -279,48 +404,73 @@ func (fs *wrappingFS) Release(input *ReleaseIn) {
}
}
func (fs *wrappingFS) Write(input *WriteIn, data []byte) (written uint32, code Status) {
func (fs *wrappingFS) Write(cancel <-chan struct{}, input *WriteIn, data []byte) (written uint32, code Status) {
if s, ok := fs.fs.(interface {
Write(input *WriteIn, data []byte) (written uint32, code Status)
}); ok {
return s.Write(input, data)
}
if s, ok := fs.fs.(interface {
Write(cancel <-chan struct{}, input *WriteIn, data []byte) (written uint32, code Status)
}); ok {
return s.Write(cancel, input, data)
}
return 0, ENOSYS
}
func (fs *wrappingFS) Flush(input *FlushIn) Status {
func (fs *wrappingFS) Flush(cancel <-chan struct{}, input *FlushIn) Status {
if s, ok := fs.fs.(interface {
Flush(input *FlushIn) Status
}); ok {
return s.Flush(input)
}
if s, ok := fs.fs.(interface {
Flush(cancel <-chan struct{}, input *FlushIn) Status
}); ok {
return s.Flush(cancel, input)
}
return OK
}
func (fs *wrappingFS) Fsync(input *FsyncIn) (code Status) {
func (fs *wrappingFS) Fsync(cancel <-chan struct{}, input *FsyncIn) (code Status) {
if s, ok := fs.fs.(interface {
Fsync(input *FsyncIn) (code Status)
}); ok {
return s.Fsync(input)
}
if s, ok := fs.fs.(interface {
Fsync(cancel <-chan struct{}, input *FsyncIn) (code Status)
}); ok {
return s.Fsync(cancel, input)
}
return ENOSYS
}
func (fs *wrappingFS) ReadDir(input *ReadIn, l *DirEntryList) Status {
func (fs *wrappingFS) ReadDir(cancel <-chan struct{}, input *ReadIn, l *DirEntryList) Status {
if s, ok := fs.fs.(interface {
ReadDir(input *ReadIn, l *DirEntryList) Status
}); ok {
return s.ReadDir(input, l)
}
if s, ok := fs.fs.(interface {
ReadDir(cancel <-chan struct{}, input *ReadIn, l *DirEntryList) Status
}); ok {
return s.ReadDir(cancel, input, l)
}
return ENOSYS
}
func (fs *wrappingFS) ReadDirPlus(input *ReadIn, l *DirEntryList) Status {
func (fs *wrappingFS) ReadDirPlus(cancel <-chan struct{}, input *ReadIn, l *DirEntryList) Status {
if s, ok := fs.fs.(interface {
ReadDirPlus(input *ReadIn, l *DirEntryList) Status
}); ok {
return s.ReadDirPlus(input, l)
}
if s, ok := fs.fs.(interface {
ReadDirPlus(cancel <-chan struct{}, input *ReadIn, l *DirEntryList) Status
}); ok {
return s.ReadDirPlus(cancel, input, l)
}
return ENOSYS
}
......@@ -332,20 +482,30 @@ func (fs *wrappingFS) ReleaseDir(input *ReleaseIn) {
}
}
func (fs *wrappingFS) FsyncDir(input *FsyncIn) (code Status) {
func (fs *wrappingFS) FsyncDir(cancel <-chan struct{}, input *FsyncIn) (code Status) {
if s, ok := fs.fs.(interface {
FsyncDir(input *FsyncIn) (code Status)
}); ok {
return s.FsyncDir(input)
}
if s, ok := fs.fs.(interface {
FsyncDir(cancel <-chan struct{}, input *FsyncIn) (code Status)
}); ok {
return s.FsyncDir(cancel, input)
}
return ENOSYS
}
func (fs *wrappingFS) Fallocate(in *FallocateIn) (code Status) {
func (fs *wrappingFS) Fallocate(cancel <-chan struct{}, in *FallocateIn) (code Status) {
if s, ok := fs.fs.(interface {
Fallocate(in *FallocateIn) (code Status)
}); ok {
return s.Fallocate(in)
}
if s, ok := fs.fs.(interface {
Fallocate(cancel <-chan struct{}, in *FallocateIn) (code Status)
}); ok {
return s.Fallocate(cancel, in)
}
return ENOSYS
}
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