diff options
author | Christopher Speller <crspeller@gmail.com> | 2018-04-16 05:37:14 -0700 |
---|---|---|
committer | Joram Wilander <jwawilander@gmail.com> | 2018-04-16 08:37:14 -0400 |
commit | 6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch) | |
tree | 3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/github.com/mattermost/rsc/fuse | |
parent | bf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff) | |
download | chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2 chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip |
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/github.com/mattermost/rsc/fuse')
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/debug.go | 20 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/fuse.go | 1650 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/fuse_kernel.go | 539 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/fuse_kernel_darwin.go | 58 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/fuse_kernel_linux.go | 50 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/fuse_kernel_std.go | 1 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/fuse_test.go | 594 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/hellofs/hello.go | 62 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/mount_darwin.go | 122 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/mount_linux.go | 67 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/serve.go | 1022 | ||||
-rw-r--r-- | vendor/github.com/mattermost/rsc/fuse/tree.go | 93 |
12 files changed, 0 insertions, 4278 deletions
diff --git a/vendor/github.com/mattermost/rsc/fuse/debug.go b/vendor/github.com/mattermost/rsc/fuse/debug.go deleted file mode 100644 index 2dc5d4312..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/debug.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// FUSE service loop, for servers that wish to use it. - -package fuse - -import ( - "runtime" -) - -func stack() string { - buf := make([]byte, 1024) - return string(buf[:runtime.Stack(buf, false)]) -} - -var Debugf = nop - -func nop(string, ...interface{}) {} diff --git a/vendor/github.com/mattermost/rsc/fuse/fuse.go b/vendor/github.com/mattermost/rsc/fuse/fuse.go deleted file mode 100644 index 2ad10c93e..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/fuse.go +++ /dev/null @@ -1,1650 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c, -// which carries this notice: -// -// The files in this directory are subject to the following license. -// -// The author of this software is Russ Cox. -// -// Copyright (c) 2006 Russ Cox -// -// Permission to use, copy, modify, and distribute this software for any -// purpose without fee is hereby granted, provided that this entire notice -// is included in all copies of any software which is or includes a copy -// or modification of this software and in all copies of the supporting -// documentation for such software. -// -// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED -// WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY -// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS -// FITNESS FOR ANY PARTICULAR PURPOSE. - -// Package fuse enables writing FUSE file systems on FreeBSD, Linux, and OS X. -// -// On OS X, it requires OSXFUSE (http://osxfuse.github.com/). -// -// There are two approaches to writing a FUSE file system. The first is to speak -// the low-level message protocol, reading from a Conn using ReadRequest and -// writing using the various Respond methods. This approach is closest to -// the actual interaction with the kernel and can be the simplest one in contexts -// such as protocol translators. -// -// Servers of synthesized file systems tend to share common bookkeeping -// abstracted away by the second approach, which is to call the Conn's -// Serve method to serve the FUSE protocol using -// an implementation of the service methods in the interfaces -// FS (file system), Node (file or directory), and Handle (opened file or directory). -// There are a daunting number of such methods that can be written, -// but few are required. -// The specific methods are described in the documentation for those interfaces. -// -// The hellofs subdirectory contains a simple illustration of the ServeFS approach. -// -// Service Methods -// -// The required and optional methods for the FS, Node, and Handle interfaces -// have the general form -// -// Op(req *OpRequest, resp *OpResponse, intr Intr) Error -// -// where Op is the name of a FUSE operation. Op reads request parameters -// from req and writes results to resp. An operation whose only result is -// the error result omits the resp parameter. Multiple goroutines may call -// service methods simultaneously; the methods being called are responsible -// for appropriate synchronization. -// -// Interrupted Operations -// -// In some file systems, some operations -// may take an undetermined amount of time. For example, a Read waiting for -// a network message or a matching Write might wait indefinitely. If the request -// is cancelled and no longer needed, the package will close intr, a chan struct{}. -// Blocking operations should select on a receive from intr and attempt to -// abort the operation early if the receive succeeds (meaning the channel is closed). -// To indicate that the operation failed because it was aborted, return fuse.EINTR. -// -// If an operation does not block for an indefinite amount of time, the intr parameter -// can be ignored. -// -// Authentication -// -// All requests types embed a Header, meaning that the method can inspect -// req.Pid, req.Uid, and req.Gid as necessary to implement permission checking. -// Alternately, XXX. -// -// Mount Options -// -// XXX -// -package fuse - -// BUG(rsc): The mount code for FreeBSD has not been written yet. - -import ( - "bytes" - "errors" - "fmt" - "io" - "log" - "os" - "runtime" - "sync" - "syscall" - "time" - "unsafe" -) - -// A Conn represents a connection to a mounted FUSE file system. -type Conn struct { - fd int - buf []byte - wio sync.Mutex - - serveConn -} - -// Mount mounts a new FUSE connection on the named directory -// and returns a connection for reading and writing FUSE messages. -func Mount(dir string) (*Conn, error) { - // TODO(rsc): mount options (...string?) - fd, errstr := mount(dir) - if errstr != "" { - return nil, errors.New(errstr) - } - - return &Conn{fd: fd}, nil -} - -// A Request represents a single FUSE request received from the kernel. -// Use a type switch to determine the specific kind. -// A request of unrecognized type will have concrete type *Header. -type Request interface { - // Hdr returns the Header associated with this request. - Hdr() *Header - - // RespondError responds to the request with the given error. - RespondError(Error) - - String() string - - // handle returns the HandleID for the request, or 0. - handle() HandleID -} - -// A RequestID identifies an active FUSE request. -type RequestID uint64 - -// A NodeID is a number identifying a directory or file. -// It must be unique among IDs returned in LookupResponses -// that have not yet been forgotten by ForgetRequests. -type NodeID uint64 - -// A HandleID is a number identifying an open directory or file. -// It only needs to be unique while the directory or file is open. -type HandleID uint64 - -// The RootID identifies the root directory of a FUSE file system. -const RootID NodeID = rootID - -// A Header describes the basic information sent in every request. -type Header struct { - Conn *Conn // connection this request was received on - ID RequestID // unique ID for request - Node NodeID // file or directory the request is about - Uid uint32 // user ID of process making request - Gid uint32 // group ID of process making request - Pid uint32 // process ID of process making request -} - -func (h *Header) String() string { - return fmt.Sprintf("ID=%#x Node=%#x Uid=%d Gid=%d Pid=%d", h.ID, h.Node, h.Uid, h.Gid, h.Pid) -} - -func (h *Header) Hdr() *Header { - return h -} - -func (h *Header) handle() HandleID { - return 0 -} - -// An Error is a FUSE error. -type Error interface { - errno() int32 -} - -const ( - // ENOSYS indicates that the call is not supported. - ENOSYS = Errno(syscall.ENOSYS) - - // ESTALE is used by Serve to respond to violations of the FUSE protocol. - ESTALE = Errno(syscall.ESTALE) - - ENOENT = Errno(syscall.ENOENT) - EIO = Errno(syscall.EIO) - EPERM = Errno(syscall.EPERM) -) - -type errno int - -func (e errno) errno() int32 { - return int32(e) -} - -// Errno implements Error using a syscall.Errno. -type Errno syscall.Errno - -func (e Errno) errno() int32 { - return int32(e) -} - -func (e Errno) String() string { - return syscall.Errno(e).Error() -} - -func (h *Header) RespondError(err Error) { - // FUSE uses negative errors! - // TODO: File bug report against OSXFUSE: positive error causes kernel panic. - out := &outHeader{Error: -err.errno(), Unique: uint64(h.ID)} - h.Conn.respond(out, unsafe.Sizeof(*out)) -} - -var maxWrite = syscall.Getpagesize() -var bufSize = 4096 + maxWrite - -// a message represents the bytes of a single FUSE message -type message struct { - conn *Conn - buf []byte // all bytes - hdr *inHeader // header - off int // offset for reading additional fields -} - -func newMessage(c *Conn) *message { - m := &message{conn: c, buf: make([]byte, bufSize)} - m.hdr = (*inHeader)(unsafe.Pointer(&m.buf[0])) - return m -} - -func (m *message) len() uintptr { - return uintptr(len(m.buf) - m.off) -} - -func (m *message) data() unsafe.Pointer { - var p unsafe.Pointer - if m.off < len(m.buf) { - p = unsafe.Pointer(&m.buf[m.off]) - } - return p -} - -func (m *message) bytes() []byte { - return m.buf[m.off:] -} - -func (m *message) Header() Header { - h := m.hdr - return Header{Conn: m.conn, ID: RequestID(h.Unique), Node: NodeID(h.Nodeid), Uid: h.Uid, Gid: h.Gid, Pid: h.Pid} -} - -// fileMode returns a Go os.FileMode from a Unix mode. -func fileMode(unixMode uint32) os.FileMode { - mode := os.FileMode(unixMode & 0777) - switch unixMode & syscall.S_IFMT { - case syscall.S_IFREG: - // nothing - case syscall.S_IFDIR: - mode |= os.ModeDir - case syscall.S_IFCHR: - mode |= os.ModeCharDevice | os.ModeDevice - case syscall.S_IFBLK: - mode |= os.ModeDevice - case syscall.S_IFIFO: - mode |= os.ModeNamedPipe - case syscall.S_IFLNK: - mode |= os.ModeSymlink - case syscall.S_IFSOCK: - mode |= os.ModeSocket - default: - // no idea - mode |= os.ModeDevice - } - if unixMode&syscall.S_ISUID != 0 { - mode |= os.ModeSetuid - } - if unixMode&syscall.S_ISGID != 0 { - mode |= os.ModeSetgid - } - return mode -} - -func (c *Conn) ReadRequest() (Request, error) { - // TODO: Some kind of buffer reuse. - m := newMessage(c) - n, err := syscall.Read(c.fd, m.buf) - if err != nil && err != syscall.ENODEV { - return nil, err - } - if n <= 0 { - return nil, io.EOF - } - m.buf = m.buf[:n] - - if n < inHeaderSize { - return nil, errors.New("fuse: message too short") - } - - // FreeBSD FUSE sends a short length in the header - // for FUSE_INIT even though the actual read length is correct. - if n == inHeaderSize+initInSize && m.hdr.Opcode == opInit && m.hdr.Len < uint32(n) { - m.hdr.Len = uint32(n) - } - - // OSXFUSE sometimes sends the wrong m.hdr.Len in a FUSE_WRITE message. - if m.hdr.Len < uint32(n) && m.hdr.Len >= uint32(unsafe.Sizeof(writeIn{})) && m.hdr.Opcode == opWrite { - m.hdr.Len = uint32(n) - } - - if m.hdr.Len != uint32(n) { - return nil, fmt.Errorf("fuse: read %d opcode %d but expected %d", n, m.hdr.Opcode, m.hdr.Len) - } - - m.off = inHeaderSize - - // Convert to data structures. - // Do not trust kernel to hand us well-formed data. - var req Request - switch m.hdr.Opcode { - default: - println("No opcode", m.hdr.Opcode) - goto unrecognized - - case opLookup: - buf := m.bytes() - n := len(buf) - if n == 0 || buf[n-1] != '\x00' { - goto corrupt - } - req = &LookupRequest{ - Header: m.Header(), - Name: string(buf[:n-1]), - } - - case opForget: - in := (*forgetIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &ForgetRequest{ - Header: m.Header(), - N: in.Nlookup, - } - - case opGetattr: - req = &GetattrRequest{ - Header: m.Header(), - } - - case opSetattr: - in := (*setattrIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &SetattrRequest{ - Header: m.Header(), - Valid: SetattrValid(in.Valid), - Handle: HandleID(in.Fh), - Size: in.Size, - Atime: time.Unix(int64(in.Atime), int64(in.AtimeNsec)), - Mtime: time.Unix(int64(in.Mtime), int64(in.MtimeNsec)), - Mode: fileMode(in.Mode), - Uid: in.Uid, - Gid: in.Gid, - Bkuptime: in.BkupTime(), - Chgtime: in.Chgtime(), - Flags: in.Flags(), - } - - case opReadlink: - if len(m.bytes()) > 0 { - goto corrupt - } - req = &ReadlinkRequest{ - Header: m.Header(), - } - - case opSymlink: - // m.bytes() is "newName\0target\0" - names := m.bytes() - if len(names) == 0 || names[len(names)-1] != 0 { - goto corrupt - } - i := bytes.IndexByte(names, '\x00') - if i < 0 { - goto corrupt - } - newName, target := names[0:i], names[i+1:len(names)-1] - req = &SymlinkRequest{ - Header: m.Header(), - NewName: string(newName), - Target: string(target), - } - - case opLink: - in := (*linkIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - newName := m.bytes()[unsafe.Sizeof(*in):] - if len(newName) < 2 || newName[len(newName)-1] != 0 { - goto corrupt - } - newName = newName[:len(newName)-1] - req = &LinkRequest{ - Header: m.Header(), - OldNode: NodeID(in.Oldnodeid), - NewName: string(newName), - } - - case opMknod: - in := (*mknodIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - name := m.bytes()[unsafe.Sizeof(*in):] - if len(name) < 2 || name[len(name)-1] != '\x00' { - goto corrupt - } - name = name[:len(name)-1] - req = &MknodRequest{ - Header: m.Header(), - Mode: fileMode(in.Mode), - Rdev: in.Rdev, - Name: string(name), - } - - case opMkdir: - in := (*mkdirIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - name := m.bytes()[unsafe.Sizeof(*in):] - i := bytes.IndexByte(name, '\x00') - if i < 0 { - goto corrupt - } - req = &MkdirRequest{ - Header: m.Header(), - Name: string(name[:i]), - Mode: fileMode(in.Mode) | os.ModeDir, - } - - case opUnlink, opRmdir: - buf := m.bytes() - n := len(buf) - if n == 0 || buf[n-1] != '\x00' { - goto corrupt - } - req = &RemoveRequest{ - Header: m.Header(), - Name: string(buf[:n-1]), - Dir: m.hdr.Opcode == opRmdir, - } - - case opRename: - in := (*renameIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - newDirNodeID := NodeID(in.Newdir) - oldNew := m.bytes()[unsafe.Sizeof(*in):] - // oldNew should be "old\x00new\x00" - if len(oldNew) < 4 { - goto corrupt - } - if oldNew[len(oldNew)-1] != '\x00' { - goto corrupt - } - i := bytes.IndexByte(oldNew, '\x00') - if i < 0 { - goto corrupt - } - oldName, newName := string(oldNew[:i]), string(oldNew[i+1:len(oldNew)-1]) - // log.Printf("RENAME: newDirNode = %d; old = %q, new = %q", newDirNodeID, oldName, newName) - req = &RenameRequest{ - Header: m.Header(), - NewDir: newDirNodeID, - OldName: oldName, - NewName: newName, - } - - case opOpendir, opOpen: - in := (*openIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &OpenRequest{ - Header: m.Header(), - Dir: m.hdr.Opcode == opOpendir, - Flags: in.Flags, - Mode: fileMode(in.Mode), - } - - case opRead, opReaddir: - in := (*readIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &ReadRequest{ - Header: m.Header(), - Dir: m.hdr.Opcode == opReaddir, - Handle: HandleID(in.Fh), - Offset: int64(in.Offset), - Size: int(in.Size), - } - - case opWrite: - in := (*writeIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - r := &WriteRequest{ - Header: m.Header(), - Handle: HandleID(in.Fh), - Offset: int64(in.Offset), - Flags: WriteFlags(in.WriteFlags), - } - buf := m.bytes()[unsafe.Sizeof(*in):] - if uint32(len(buf)) < in.Size { - goto corrupt - } - r.Data = buf - req = r - - case opStatfs: - req = &StatfsRequest{ - Header: m.Header(), - } - - case opRelease, opReleasedir: - in := (*releaseIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &ReleaseRequest{ - Header: m.Header(), - Dir: m.hdr.Opcode == opReleasedir, - Handle: HandleID(in.Fh), - Flags: in.Flags, - ReleaseFlags: ReleaseFlags(in.ReleaseFlags), - LockOwner: in.LockOwner, - } - - case opFsync: - in := (*fsyncIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &FsyncRequest{ - Header: m.Header(), - Handle: HandleID(in.Fh), - Flags: in.FsyncFlags, - } - - case opSetxattr: - var size uint32 - var r *SetxattrRequest - if runtime.GOOS == "darwin" { - in := (*setxattrInOSX)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - r = &SetxattrRequest{ - Flags: in.Flags, - Position: in.Position, - } - size = in.Size - m.off += int(unsafe.Sizeof(*in)) - } else { - in := (*setxattrIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - r = &SetxattrRequest{} - size = in.Size - m.off += int(unsafe.Sizeof(*in)) - } - r.Header = m.Header() - name := m.bytes() - i := bytes.IndexByte(name, '\x00') - if i < 0 { - goto corrupt - } - r.Name = string(name[:i]) - r.Xattr = name[i+1:] - if uint32(len(r.Xattr)) < size { - goto corrupt - } - r.Xattr = r.Xattr[:size] - req = r - - case opGetxattr: - if runtime.GOOS == "darwin" { - in := (*getxattrInOSX)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &GetxattrRequest{ - Header: m.Header(), - Size: in.Size, - Position: in.Position, - } - } else { - in := (*getxattrIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &GetxattrRequest{ - Header: m.Header(), - Size: in.Size, - } - } - - case opListxattr: - if runtime.GOOS == "darwin" { - in := (*getxattrInOSX)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &ListxattrRequest{ - Header: m.Header(), - Size: in.Size, - Position: in.Position, - } - } else { - in := (*getxattrIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &ListxattrRequest{ - Header: m.Header(), - Size: in.Size, - } - } - - case opRemovexattr: - buf := m.bytes() - n := len(buf) - if n == 0 || buf[n-1] != '\x00' { - goto corrupt - } - req = &RemovexattrRequest{ - Header: m.Header(), - Name: string(buf[:n-1]), - } - - case opFlush: - in := (*flushIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &FlushRequest{ - Header: m.Header(), - Handle: HandleID(in.Fh), - Flags: in.FlushFlags, - LockOwner: in.LockOwner, - } - - case opInit: - in := (*initIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &InitRequest{ - Header: m.Header(), - Major: in.Major, - Minor: in.Minor, - MaxReadahead: in.MaxReadahead, - Flags: InitFlags(in.Flags), - } - - case opFsyncdir: - panic("opFsyncdir") - case opGetlk: - panic("opGetlk") - case opSetlk: - panic("opSetlk") - case opSetlkw: - panic("opSetlkw") - - case opAccess: - in := (*accessIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - req = &AccessRequest{ - Header: m.Header(), - Mask: in.Mask, - } - - case opCreate: - in := (*openIn)(m.data()) - if m.len() < unsafe.Sizeof(*in) { - goto corrupt - } - name := m.bytes()[unsafe.Sizeof(*in):] - i := bytes.IndexByte(name, '\x00') - if i < 0 { - goto corrupt - } - req = &CreateRequest{ - Header: m.Header(), - Flags: in.Flags, - Mode: fileMode(in.Mode), - Name: string(name[:i]), - } - - case opInterrupt: - panic("opInterrupt") - case opBmap: - panic("opBmap") - - case opDestroy: - req = &DestroyRequest{ - Header: m.Header(), - } - - // OS X - case opSetvolname: - panic("opSetvolname") - case opGetxtimes: - panic("opGetxtimes") - case opExchange: - panic("opExchange") - } - - return req, nil - -corrupt: - println("malformed message") - return nil, fmt.Errorf("fuse: malformed message") - -unrecognized: - // Unrecognized message. - // Assume higher-level code will send a "no idea what you mean" error. - h := m.Header() - return &h, nil -} - -func (c *Conn) respond(out *outHeader, n uintptr) { - c.wio.Lock() - defer c.wio.Unlock() - out.Len = uint32(n) - msg := (*[1 << 30]byte)(unsafe.Pointer(out))[:n] - nn, err := syscall.Write(c.fd, msg) - if nn != len(msg) || err != nil { - log.Printf("RESPOND WRITE: %d %v", nn, err) - log.Printf("with stack: %s", stack()) - } -} - -func (c *Conn) respondData(out *outHeader, n uintptr, data []byte) { - c.wio.Lock() - defer c.wio.Unlock() - // TODO: use writev - out.Len = uint32(n + uintptr(len(data))) - msg := make([]byte, out.Len) - copy(msg, (*[1 << 30]byte)(unsafe.Pointer(out))[:n]) - copy(msg[n:], data) - syscall.Write(c.fd, msg) -} - -// An InitRequest is the first request sent on a FUSE file system. -type InitRequest struct { - Header - Major uint32 - Minor uint32 - MaxReadahead uint32 - Flags InitFlags -} - -func (r *InitRequest) String() string { - return fmt.Sprintf("Init [%s] %d.%d ra=%d fl=%v", &r.Header, r.Major, r.Minor, r.MaxReadahead, r.Flags) -} - -// An InitResponse is the response to an InitRequest. -type InitResponse struct { - MaxReadahead uint32 - Flags InitFlags - MaxWrite uint32 -} - -func (r *InitResponse) String() string { - return fmt.Sprintf("Init %+v", *r) -} - -// Respond replies to the request with the given response. -func (r *InitRequest) Respond(resp *InitResponse) { - out := &initOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Major: kernelVersion, - Minor: kernelMinorVersion, - MaxReadahead: resp.MaxReadahead, - Flags: uint32(resp.Flags), - MaxWrite: resp.MaxWrite, - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A StatfsRequest requests information about the mounted file system. -type StatfsRequest struct { - Header -} - -func (r *StatfsRequest) String() string { - return fmt.Sprintf("Statfs [%s]\n", &r.Header) -} - -// Respond replies to the request with the given response. -func (r *StatfsRequest) Respond(resp *StatfsResponse) { - out := &statfsOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - St: kstatfs{ - Blocks: resp.Blocks, - Bfree: resp.Bfree, - Bavail: resp.Bavail, - Files: resp.Files, - Bsize: resp.Bsize, - Namelen: resp.Namelen, - Frsize: resp.Frsize, - }, - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A StatfsResponse is the response to a StatfsRequest. -type StatfsResponse struct { - Blocks uint64 // Total data blocks in file system. - Bfree uint64 // Free blocks in file system. - Bavail uint64 // Free blocks in file system if you're not root. - Files uint64 // Total files in file system. - Ffree uint64 // Free files in file system. - Bsize uint32 // Block size - Namelen uint32 // Maximum file name length? - Frsize uint32 // ? -} - -func (r *StatfsResponse) String() string { - return fmt.Sprintf("Statfs %+v", *r) -} - -// An AccessRequest asks whether the file can be accessed -// for the purpose specified by the mask. -type AccessRequest struct { - Header - Mask uint32 -} - -func (r *AccessRequest) String() string { - return fmt.Sprintf("Access [%s] mask=%#x", &r.Header, r.Mask) -} - -// Respond replies to the request indicating that access is allowed. -// To deny access, use RespondError. -func (r *AccessRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// An Attr is the metadata for a single file or directory. -type Attr struct { - Inode uint64 // inode number - Size uint64 // size in bytes - Blocks uint64 // size in blocks - Atime time.Time // time of last access - Mtime time.Time // time of last modification - Ctime time.Time // time of last inode change - Crtime time.Time // time of creation (OS X only) - Mode os.FileMode // file mode - Nlink uint32 // number of links - Uid uint32 // owner uid - Gid uint32 // group gid - Rdev uint32 // device numbers - Flags uint32 // chflags(2) flags (OS X only) -} - -func unix(t time.Time) (sec uint64, nsec uint32) { - nano := t.UnixNano() - sec = uint64(nano / 1e9) - nsec = uint32(nano % 1e9) - return -} - -func (a *Attr) attr() (out attr) { - out.Ino = a.Inode - out.Size = a.Size - out.Blocks = a.Blocks - out.Atime, out.AtimeNsec = unix(a.Atime) - out.Mtime, out.MtimeNsec = unix(a.Mtime) - out.Ctime, out.CtimeNsec = unix(a.Ctime) - out.SetCrtime(unix(a.Crtime)) - out.Mode = uint32(a.Mode) & 0777 - switch { - default: - out.Mode |= syscall.S_IFREG - case a.Mode&os.ModeDir != 0: - out.Mode |= syscall.S_IFDIR - case a.Mode&os.ModeDevice != 0: - if a.Mode&os.ModeCharDevice != 0 { - out.Mode |= syscall.S_IFCHR - } else { - out.Mode |= syscall.S_IFBLK - } - case a.Mode&os.ModeNamedPipe != 0: - out.Mode |= syscall.S_IFIFO - case a.Mode&os.ModeSymlink != 0: - out.Mode |= syscall.S_IFLNK - case a.Mode&os.ModeSocket != 0: - out.Mode |= syscall.S_IFSOCK - } - if a.Mode&os.ModeSetuid != 0 { - out.Mode |= syscall.S_ISUID - } - if a.Mode&os.ModeSetgid != 0 { - out.Mode |= syscall.S_ISGID - } - out.Nlink = a.Nlink - if out.Nlink < 1 { - out.Nlink = 1 - } - out.Uid = a.Uid - out.Gid = a.Gid - out.Rdev = a.Rdev - out.SetFlags(a.Flags) - - return -} - -// A GetattrRequest asks for the metadata for the file denoted by r.Node. -type GetattrRequest struct { - Header -} - -func (r *GetattrRequest) String() string { - return fmt.Sprintf("Getattr [%s]", &r.Header) -} - -// Respond replies to the request with the given response. -func (r *GetattrRequest) Respond(resp *GetattrResponse) { - out := &attrOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A GetattrResponse is the response to a GetattrRequest. -type GetattrResponse struct { - AttrValid time.Duration // how long Attr can be cached - Attr Attr // file attributes -} - -func (r *GetattrResponse) String() string { - return fmt.Sprintf("Getattr %+v", *r) -} - -// A GetxattrRequest asks for the extended attributes associated with r.Node. -type GetxattrRequest struct { - Header - Size uint32 // maximum size to return - Position uint32 // offset within extended attributes -} - -func (r *GetxattrRequest) String() string { - return fmt.Sprintf("Getxattr [%s] %d @%d", &r.Header, r.Size, r.Position) -} - -// Respond replies to the request with the given response. -func (r *GetxattrRequest) Respond(resp *GetxattrResponse) { - out := &getxattrOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Size: uint32(len(resp.Xattr)), - } - r.Conn.respondData(&out.outHeader, unsafe.Sizeof(*out), resp.Xattr) -} - -// A GetxattrResponse is the response to a GetxattrRequest. -type GetxattrResponse struct { - Xattr []byte -} - -func (r *GetxattrResponse) String() string { - return fmt.Sprintf("Getxattr %x", r.Xattr) -} - -// A ListxattrRequest asks to list the extended attributes associated with r.Node. -type ListxattrRequest struct { - Header - Size uint32 // maximum size to return - Position uint32 // offset within attribute list -} - -func (r *ListxattrRequest) String() string { - return fmt.Sprintf("Listxattr [%s] %d @%d", &r.Header, r.Size, r.Position) -} - -// Respond replies to the request with the given response. -func (r *ListxattrRequest) Respond(resp *ListxattrResponse) { - out := &getxattrOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Size: uint32(len(resp.Xattr)), - } - r.Conn.respondData(&out.outHeader, unsafe.Sizeof(*out), resp.Xattr) -} - -// A ListxattrResponse is the response to a ListxattrRequest. -type ListxattrResponse struct { - Xattr []byte -} - -func (r *ListxattrResponse) String() string { - return fmt.Sprintf("Listxattr %x", r.Xattr) -} - -// A RemovexattrRequest asks to remove an extended attribute associated with r.Node. -type RemovexattrRequest struct { - Header - Name string // name of extended attribute -} - -func (r *RemovexattrRequest) String() string { - return fmt.Sprintf("Removexattr [%s] %q", &r.Header, r.Name) -} - -// Respond replies to the request, indicating that the attribute was removed. -func (r *RemovexattrRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// A SetxattrRequest asks to set an extended attribute associated with a file. -type SetxattrRequest struct { - Header - Flags uint32 - Position uint32 // OS X only - Name string - Xattr []byte -} - -func (r *SetxattrRequest) String() string { - return fmt.Sprintf("Setxattr [%s] %q %x fl=%v @%#x", &r.Header, r.Name, r.Xattr, r.Flags, r.Position) -} - -// Respond replies to the request, indicating that the extended attribute was set. -func (r *SetxattrRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// A LookupRequest asks to look up the given name in the directory named by r.Node. -type LookupRequest struct { - Header - Name string -} - -func (r *LookupRequest) String() string { - return fmt.Sprintf("Lookup [%s] %q", &r.Header, r.Name) -} - -// Respond replies to the request with the given response. -func (r *LookupRequest) Respond(resp *LookupResponse) { - out := &entryOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Nodeid: uint64(resp.Node), - Generation: resp.Generation, - EntryValid: uint64(resp.EntryValid / time.Second), - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond), - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A LookupResponse is the response to a LookupRequest. -type LookupResponse struct { - Node NodeID - Generation uint64 - EntryValid time.Duration - AttrValid time.Duration - Attr Attr -} - -func (r *LookupResponse) String() string { - return fmt.Sprintf("Lookup %+v", *r) -} - -// An OpenRequest asks to open a file or directory -type OpenRequest struct { - Header - Dir bool // is this Opendir? - Flags uint32 - Mode os.FileMode -} - -func (r *OpenRequest) String() string { - return fmt.Sprintf("Open [%s] dir=%v fl=%v mode=%v", &r.Header, r.Dir, r.Flags, r.Mode) -} - -// Respond replies to the request with the given response. -func (r *OpenRequest) Respond(resp *OpenResponse) { - out := &openOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Fh: uint64(resp.Handle), - OpenFlags: uint32(resp.Flags), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A OpenResponse is the response to a OpenRequest. -type OpenResponse struct { - Handle HandleID - Flags OpenFlags -} - -func (r *OpenResponse) String() string { - return fmt.Sprintf("Open %+v", *r) -} - -// A CreateRequest asks to create and open a file (not a directory). -type CreateRequest struct { - Header - Name string - Flags uint32 - Mode os.FileMode -} - -func (r *CreateRequest) String() string { - return fmt.Sprintf("Create [%s] %q fl=%v mode=%v", &r.Header, r.Name, r.Flags, r.Mode) -} - -// Respond replies to the request with the given response. -func (r *CreateRequest) Respond(resp *CreateResponse) { - out := &createOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - - Nodeid: uint64(resp.Node), - Generation: resp.Generation, - EntryValid: uint64(resp.EntryValid / time.Second), - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond), - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - - Fh: uint64(resp.Handle), - OpenFlags: uint32(resp.Flags), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A CreateResponse is the response to a CreateRequest. -// It describes the created node and opened handle. -type CreateResponse struct { - LookupResponse - OpenResponse -} - -func (r *CreateResponse) String() string { - return fmt.Sprintf("Create %+v", *r) -} - -// A MkdirRequest asks to create (but not open) a directory. -type MkdirRequest struct { - Header - Name string - Mode os.FileMode -} - -func (r *MkdirRequest) String() string { - return fmt.Sprintf("Mkdir [%s] %q mode=%v", &r.Header, r.Name, r.Mode) -} - -// Respond replies to the request with the given response. -func (r *MkdirRequest) Respond(resp *MkdirResponse) { - out := &entryOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Nodeid: uint64(resp.Node), - Generation: resp.Generation, - EntryValid: uint64(resp.EntryValid / time.Second), - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond), - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A MkdirResponse is the response to a MkdirRequest. -type MkdirResponse struct { - LookupResponse -} - -func (r *MkdirResponse) String() string { - return fmt.Sprintf("Mkdir %+v", *r) -} - -// A ReadRequest asks to read from an open file. -type ReadRequest struct { - Header - Dir bool // is this Readdir? - Handle HandleID - Offset int64 - Size int -} - -func (r *ReadRequest) handle() HandleID { - return r.Handle -} - -func (r *ReadRequest) String() string { - return fmt.Sprintf("Read [%s] %#x %d @%#x dir=%v", &r.Header, r.Handle, r.Size, r.Offset, r.Dir) -} - -// Respond replies to the request with the given response. -func (r *ReadRequest) Respond(resp *ReadResponse) { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respondData(out, unsafe.Sizeof(*out), resp.Data) -} - -// A ReadResponse is the response to a ReadRequest. -type ReadResponse struct { - Data []byte -} - -func (r *ReadResponse) String() string { - return fmt.Sprintf("Read %x", r.Data) -} - -// A ReleaseRequest asks to release (close) an open file handle. -type ReleaseRequest struct { - Header - Dir bool // is this Releasedir? - Handle HandleID - Flags uint32 // flags from OpenRequest - ReleaseFlags ReleaseFlags - LockOwner uint32 -} - -func (r *ReleaseRequest) handle() HandleID { - return r.Handle -} - -func (r *ReleaseRequest) String() string { - return fmt.Sprintf("Release [%s] %#x fl=%v rfl=%v owner=%#x", &r.Header, r.Handle, r.Flags, r.ReleaseFlags, r.LockOwner) -} - -// Respond replies to the request, indicating that the handle has been released. -func (r *ReleaseRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// A DestroyRequest is sent by the kernel when unmounting the file system. -// No more requests will be received after this one, but it should still be -// responded to. -type DestroyRequest struct { - Header -} - -func (r *DestroyRequest) String() string { - return fmt.Sprintf("Destroy [%s]", &r.Header) -} - -// Respond replies to the request. -func (r *DestroyRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// A ForgetRequest is sent by the kernel when forgetting about r.Node -// as returned by r.N lookup requests. -type ForgetRequest struct { - Header - N uint64 -} - -func (r *ForgetRequest) String() string { - return fmt.Sprintf("Forget [%s] %d", &r.Header, r.N) -} - -// Respond replies to the request, indicating that the forgetfulness has been recorded. -func (r *ForgetRequest) Respond() { - // Don't reply to forget messages. -} - -// A Dirent represents a single directory entry. -type Dirent struct { - Inode uint64 // inode this entry names - Type uint32 // ? - Name string // name of entry -} - -// AppendDirent appends the encoded form of a directory entry to data -// and returns the resulting slice. -func AppendDirent(data []byte, dir Dirent) []byte { - de := dirent{ - Ino: dir.Inode, - Namelen: uint32(len(dir.Name)), - Type: dir.Type, - } - de.Off = uint64(len(data) + direntSize + (len(dir.Name)+7)&^7) - data = append(data, (*[direntSize]byte)(unsafe.Pointer(&de))[:]...) - data = append(data, dir.Name...) - n := direntSize + uintptr(len(dir.Name)) - if n%8 != 0 { - var pad [8]byte - data = append(data, pad[:8-n%8]...) - } - return data -} - -// A WriteRequest asks to write to an open file. -type WriteRequest struct { - Header - Handle HandleID - Offset int64 - Data []byte - Flags WriteFlags -} - -func (r *WriteRequest) String() string { - return fmt.Sprintf("Write [%s] %#x %d @%d fl=%v", &r.Header, r.Handle, len(r.Data), r.Offset, r.Flags) -} - -// Respond replies to the request with the given response. -func (r *WriteRequest) Respond(resp *WriteResponse) { - out := &writeOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Size: uint32(resp.Size), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -func (r *WriteRequest) handle() HandleID { - return r.Handle -} - -// A WriteResponse replies to a write indicating how many bytes were written. -type WriteResponse struct { - Size int -} - -func (r *WriteResponse) String() string { - return fmt.Sprintf("Write %+v", *r) -} - -// A SetattrRequest asks to change one or more attributes associated with a file, -// as indicated by Valid. -type SetattrRequest struct { - Header - Valid SetattrValid - Handle HandleID - Size uint64 - Atime time.Time - Mtime time.Time - Mode os.FileMode - Uid uint32 - Gid uint32 - - // OS X only - Bkuptime time.Time - Chgtime time.Time - Crtime time.Time - Flags uint32 // see chflags(2) -} - -func (r *SetattrRequest) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "Setattr [%s]", &r.Header) - if r.Valid.Mode() { - fmt.Fprintf(&buf, " mode=%v", r.Mode) - } - if r.Valid.Uid() { - fmt.Fprintf(&buf, " uid=%d", r.Uid) - } - if r.Valid.Gid() { - fmt.Fprintf(&buf, " gid=%d", r.Gid) - } - if r.Valid.Size() { - fmt.Fprintf(&buf, " size=%d", r.Size) - } - if r.Valid.Atime() { - fmt.Fprintf(&buf, " atime=%v", r.Atime) - } - if r.Valid.Mtime() { - fmt.Fprintf(&buf, " mtime=%v", r.Mtime) - } - if r.Valid.Handle() { - fmt.Fprintf(&buf, " handle=%#x", r.Handle) - } else { - fmt.Fprintf(&buf, " handle=INVALID-%#x", r.Handle) - } - if r.Valid.Crtime() { - fmt.Fprintf(&buf, " crtime=%v", r.Crtime) - } - if r.Valid.Chgtime() { - fmt.Fprintf(&buf, " chgtime=%v", r.Chgtime) - } - if r.Valid.Bkuptime() { - fmt.Fprintf(&buf, " bkuptime=%v", r.Bkuptime) - } - if r.Valid.Flags() { - fmt.Fprintf(&buf, " flags=%#x", r.Flags) - } - return buf.String() -} - -func (r *SetattrRequest) handle() HandleID { - if r.Valid.Handle() { - return r.Handle - } - return 0 -} - -// Respond replies to the request with the given response, -// giving the updated attributes. -func (r *SetattrRequest) Respond(resp *SetattrResponse) { - out := &attrOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A SetattrResponse is the response to a SetattrRequest. -type SetattrResponse struct { - AttrValid time.Duration // how long Attr can be cached - Attr Attr // file attributes -} - -func (r *SetattrResponse) String() string { - return fmt.Sprintf("Setattr %+v", *r) -} - -// A FlushRequest asks for the current state of an open file to be flushed -// to storage, as when a file descriptor is being closed. A single opened Handle -// may receive multiple FlushRequests over its lifetime. -type FlushRequest struct { - Header - Handle HandleID - Flags uint32 - LockOwner uint64 -} - -func (r *FlushRequest) String() string { - return fmt.Sprintf("Flush [%s] %#x fl=%#x lk=%#x", &r.Header, r.Handle, r.Flags, r.LockOwner) -} - -func (r *FlushRequest) handle() HandleID { - return r.Handle -} - -// Respond replies to the request, indicating that the flush succeeded. -func (r *FlushRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// A RemoveRequest asks to remove a file or directory. -type RemoveRequest struct { - Header - Name string // name of extended attribute - Dir bool // is this rmdir? -} - -func (r *RemoveRequest) String() string { - return fmt.Sprintf("Remove [%s] %q dir=%v", &r.Header, r.Name, r.Dir) -} - -// Respond replies to the request, indicating that the file was removed. -func (r *RemoveRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -// A SymlinkRequest is a request to create a symlink making NewName point to Target. -type SymlinkRequest struct { - Header - NewName, Target string -} - -func (r *SymlinkRequest) String() string { - return fmt.Sprintf("Symlink [%s] from %q to target %q", &r.Header, r.NewName, r.Target) -} - -func (r *SymlinkRequest) handle() HandleID { - return 0 -} - -// Respond replies to the request, indicating that the symlink was created. -func (r *SymlinkRequest) Respond(resp *SymlinkResponse) { - out := &entryOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Nodeid: uint64(resp.Node), - Generation: resp.Generation, - EntryValid: uint64(resp.EntryValid / time.Second), - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond), - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A SymlinkResponse is the response to a SymlinkRequest. -type SymlinkResponse struct { - LookupResponse -} - -// A ReadlinkRequest is a request to read a symlink's target. -type ReadlinkRequest struct { - Header -} - -func (r *ReadlinkRequest) String() string { - return fmt.Sprintf("Readlink [%s]", &r.Header) -} - -func (r *ReadlinkRequest) handle() HandleID { - return 0 -} - -func (r *ReadlinkRequest) Respond(target string) { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respondData(out, unsafe.Sizeof(*out), []byte(target)) -} - -// A LinkRequest is a request to create a hard link. -type LinkRequest struct { - Header - OldNode NodeID - NewName string -} - -func (r *LinkRequest) Respond(resp *LookupResponse) { - out := &entryOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Nodeid: uint64(resp.Node), - Generation: resp.Generation, - EntryValid: uint64(resp.EntryValid / time.Second), - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond), - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A RenameRequest is a request to rename a file. -type RenameRequest struct { - Header - NewDir NodeID - OldName, NewName string -} - -func (r *RenameRequest) handle() HandleID { - return 0 -} - -func (r *RenameRequest) String() string { - return fmt.Sprintf("Rename [%s] from %q to dirnode %d %q", &r.Header, r.OldName, r.NewDir, r.NewName) -} - -func (r *RenameRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -type MknodRequest struct { - Header - Name string - Mode os.FileMode - Rdev uint32 -} - -func (r *MknodRequest) String() string { - return fmt.Sprintf("Mknod [%s] Name %q mode %v rdev %d", &r.Header, r.Name, r.Mode, r.Rdev) -} - -func (r *MknodRequest) Respond(resp *LookupResponse) { - out := &entryOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - Nodeid: uint64(resp.Node), - Generation: resp.Generation, - EntryValid: uint64(resp.EntryValid / time.Second), - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond), - AttrValid: uint64(resp.AttrValid / time.Second), - AttrValidNsec: uint32(resp.AttrValid % time.Second / time.Nanosecond), - Attr: resp.Attr.attr(), - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -type FsyncRequest struct { - Header - Handle HandleID - Flags uint32 -} - -func (r *FsyncRequest) String() string { - return fmt.Sprintf("Fsync [%s] Handle %v Flags %v", &r.Header, r.Handle, r.Flags) -} - -func (r *FsyncRequest) Respond() { - out := &outHeader{Unique: uint64(r.ID)} - r.Conn.respond(out, unsafe.Sizeof(*out)) -} - -/*{ - -// A XXXRequest xxx. -type XXXRequest struct { - Header - xxx -} - -func (r *XXXRequest) String() string { - return fmt.Sprintf("XXX [%s] xxx", &r.Header) -} - -func (r *XXXRequest) handle() HandleID { - return r.Handle -} - -// Respond replies to the request with the given response. -func (r *XXXRequest) Respond(resp *XXXResponse) { - out := &xxxOut{ - outHeader: outHeader{Unique: uint64(r.ID)}, - xxx, - } - r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out)) -} - -// A XXXResponse is the response to a XXXRequest. -type XXXResponse struct { - xxx -} - -func (r *XXXResponse) String() string { - return fmt.Sprintf("XXX %+v", *r) -} - - } -*/ diff --git a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel.go b/vendor/github.com/mattermost/rsc/fuse/fuse_kernel.go deleted file mode 100644 index a57360e63..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel.go +++ /dev/null @@ -1,539 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Derived from FUSE's fuse_kernel.h -/* - This file defines the kernel interface of FUSE - Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> - - - This -- and only this -- header file may also be distributed under - the terms of the BSD Licence as follows: - - Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. -*/ - -package fuse - -import ( - "fmt" - "unsafe" -) - -// Version is the FUSE version implemented by the package. -const Version = "7.8" - -const ( - kernelVersion = 7 - kernelMinorVersion = 8 - rootID = 1 -) - -type kstatfs struct { - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Bsize uint32 - Namelen uint32 - Frsize uint32 - Padding uint32 - Spare [6]uint32 -} - -type fileLock struct { - Start uint64 - End uint64 - Type uint32 - Pid uint32 -} - -// The SetattrValid are bit flags describing which fields in the SetattrRequest -// are included in the change. -type SetattrValid uint32 - -const ( - SetattrMode SetattrValid = 1 << 0 - SetattrUid SetattrValid = 1 << 1 - SetattrGid SetattrValid = 1 << 2 - SetattrSize SetattrValid = 1 << 3 - SetattrAtime SetattrValid = 1 << 4 - SetattrMtime SetattrValid = 1 << 5 - SetattrHandle SetattrValid = 1 << 6 // TODO: What does this mean? - - // Linux only(?) - SetattrAtimeNow SetattrValid = 1 << 7 - SetattrMtimeNow SetattrValid = 1 << 8 - SetattrLockOwner SetattrValid = 1 << 9 // http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg27852.html - - // OS X only - SetattrCrtime SetattrValid = 1 << 28 - SetattrChgtime SetattrValid = 1 << 29 - SetattrBkuptime SetattrValid = 1 << 30 - SetattrFlags SetattrValid = 1 << 31 -) - -func (fl SetattrValid) Mode() bool { return fl&SetattrMode != 0 } -func (fl SetattrValid) Uid() bool { return fl&SetattrUid != 0 } -func (fl SetattrValid) Gid() bool { return fl&SetattrGid != 0 } -func (fl SetattrValid) Size() bool { return fl&SetattrSize != 0 } -func (fl SetattrValid) Atime() bool { return fl&SetattrAtime != 0 } -func (fl SetattrValid) Mtime() bool { return fl&SetattrMtime != 0 } -func (fl SetattrValid) Handle() bool { return fl&SetattrHandle != 0 } -func (fl SetattrValid) Crtime() bool { return fl&SetattrCrtime != 0 } -func (fl SetattrValid) Chgtime() bool { return fl&SetattrChgtime != 0 } -func (fl SetattrValid) Bkuptime() bool { return fl&SetattrBkuptime != 0 } -func (fl SetattrValid) Flags() bool { return fl&SetattrFlags != 0 } - -func (fl SetattrValid) String() string { - return flagString(uint32(fl), setattrValidNames) -} - -var setattrValidNames = []flagName{ - {uint32(SetattrMode), "SetattrMode"}, - {uint32(SetattrUid), "SetattrUid"}, - {uint32(SetattrGid), "SetattrGid"}, - {uint32(SetattrSize), "SetattrSize"}, - {uint32(SetattrAtime), "SetattrAtime"}, - {uint32(SetattrMtime), "SetattrMtime"}, - {uint32(SetattrHandle), "SetattrHandle"}, - {uint32(SetattrCrtime), "SetattrCrtime"}, - {uint32(SetattrChgtime), "SetattrChgtime"}, - {uint32(SetattrBkuptime), "SetattrBkuptime"}, - {uint32(SetattrFlags), "SetattrFlags"}, -} - -// The OpenFlags are returned in the OpenResponse. -type OpenFlags uint32 - -const ( - OpenDirectIO OpenFlags = 1 << 0 // bypass page cache for this open file - OpenKeepCache OpenFlags = 1 << 1 // don't invalidate the data cache on open - OpenNonSeekable OpenFlags = 1 << 2 // (Linux?) - - OpenPurgeAttr OpenFlags = 1 << 30 // OS X - OpenPurgeUBC OpenFlags = 1 << 31 // OS X -) - -func (fl OpenFlags) String() string { - return flagString(uint32(fl), openFlagNames) -} - -var openFlagNames = []flagName{ - {uint32(OpenDirectIO), "OpenDirectIO"}, - {uint32(OpenKeepCache), "OpenKeepCache"}, - {uint32(OpenPurgeAttr), "OpenPurgeAttr"}, - {uint32(OpenPurgeUBC), "OpenPurgeUBC"}, -} - -// The InitFlags are used in the Init exchange. -type InitFlags uint32 - -const ( - InitAsyncRead InitFlags = 1 << 0 - InitPosixLocks InitFlags = 1 << 1 - - InitCaseSensitive InitFlags = 1 << 29 // OS X only - InitVolRename InitFlags = 1 << 30 // OS X only - InitXtimes InitFlags = 1 << 31 // OS X only -) - -type flagName struct { - bit uint32 - name string -} - -var initFlagNames = []flagName{ - {uint32(InitAsyncRead), "InitAsyncRead"}, - {uint32(InitPosixLocks), "InitPosixLocks"}, - {uint32(InitCaseSensitive), "InitCaseSensitive"}, - {uint32(InitVolRename), "InitVolRename"}, - {uint32(InitXtimes), "InitXtimes"}, -} - -func (fl InitFlags) String() string { - return flagString(uint32(fl), initFlagNames) -} - -func flagString(f uint32, names []flagName) string { - var s string - - if f == 0 { - return "0" - } - - for _, n := range names { - if f&n.bit != 0 { - s += "+" + n.name - f &^= n.bit - } - } - if f != 0 { - s += fmt.Sprintf("%+#x", f) - } - return s[1:] -} - -// The ReleaseFlags are used in the Release exchange. -type ReleaseFlags uint32 - -const ( - ReleaseFlush ReleaseFlags = 1 << 0 -) - -func (fl ReleaseFlags) String() string { - return flagString(uint32(fl), releaseFlagNames) -} - -var releaseFlagNames = []flagName{ - {uint32(ReleaseFlush), "ReleaseFlush"}, -} - -// Opcodes -const ( - opLookup = 1 - opForget = 2 // no reply - opGetattr = 3 - opSetattr = 4 - opReadlink = 5 - opSymlink = 6 - opMknod = 8 - opMkdir = 9 - opUnlink = 10 - opRmdir = 11 - opRename = 12 - opLink = 13 - opOpen = 14 - opRead = 15 - opWrite = 16 - opStatfs = 17 - opRelease = 18 - opFsync = 20 - opSetxattr = 21 - opGetxattr = 22 - opListxattr = 23 - opRemovexattr = 24 - opFlush = 25 - opInit = 26 - opOpendir = 27 - opReaddir = 28 - opReleasedir = 29 - opFsyncdir = 30 - opGetlk = 31 - opSetlk = 32 - opSetlkw = 33 - opAccess = 34 - opCreate = 35 - opInterrupt = 36 - opBmap = 37 - opDestroy = 38 - opIoctl = 39 // Linux? - opPoll = 40 // Linux? - - // OS X - opSetvolname = 61 - opGetxtimes = 62 - opExchange = 63 -) - -// The read buffer is required to be at least 8k but may be much larger -const minReadBuffer = 8192 - -type entryOut struct { - outHeader - Nodeid uint64 // Inode ID - Generation uint64 // Inode generation - EntryValid uint64 // Cache timeout for the name - AttrValid uint64 // Cache timeout for the attributes - EntryValidNsec uint32 - AttrValidNsec uint32 - Attr attr -} - -type forgetIn struct { - Nlookup uint64 -} - -type attrOut struct { - outHeader - AttrValid uint64 // Cache timeout for the attributes - AttrValidNsec uint32 - Dummy uint32 - Attr attr -} - -// OS X -type getxtimesOut struct { - outHeader - Bkuptime uint64 - Crtime uint64 - BkuptimeNsec uint32 - CrtimeNsec uint32 -} - -type mknodIn struct { - Mode uint32 - Rdev uint32 - // "filename\x00" follows. -} - -type mkdirIn struct { - Mode uint32 - Padding uint32 - // filename follows -} - -type renameIn struct { - Newdir uint64 - // "oldname\x00newname\x00" follows -} - -// OS X -type exchangeIn struct { - Olddir uint64 - Newdir uint64 - Options uint64 -} - -type linkIn struct { - Oldnodeid uint64 -} - -type setattrInCommon struct { - Valid uint32 - Padding uint32 - Fh uint64 - Size uint64 - LockOwner uint64 // unused on OS X? - Atime uint64 - Mtime uint64 - Unused2 uint64 - AtimeNsec uint32 - MtimeNsec uint32 - Unused3 uint32 - Mode uint32 - Unused4 uint32 - Uid uint32 - Gid uint32 - Unused5 uint32 -} - -type openIn struct { - Flags uint32 - Mode uint32 -} - -type openOut struct { - outHeader - Fh uint64 - OpenFlags uint32 - Padding uint32 -} - -type createOut struct { - outHeader - - Nodeid uint64 // Inode ID - Generation uint64 // Inode generation - EntryValid uint64 // Cache timeout for the name - AttrValid uint64 // Cache timeout for the attributes - EntryValidNsec uint32 - AttrValidNsec uint32 - Attr attr - - Fh uint64 - OpenFlags uint32 - Padding uint32 -} - -type releaseIn struct { - Fh uint64 - Flags uint32 - ReleaseFlags uint32 - LockOwner uint32 -} - -type flushIn struct { - Fh uint64 - FlushFlags uint32 - Padding uint32 - LockOwner uint64 -} - -type readIn struct { - Fh uint64 - Offset uint64 - Size uint32 - Padding uint32 -} - -type writeIn struct { - Fh uint64 - Offset uint64 - Size uint32 - WriteFlags uint32 -} - -type writeOut struct { - outHeader - Size uint32 - Padding uint32 -} - -// The WriteFlags are returned in the WriteResponse. -type WriteFlags uint32 - -func (fl WriteFlags) String() string { - return flagString(uint32(fl), writeFlagNames) -} - -var writeFlagNames = []flagName{} - -const compatStatfsSize = 48 - -type statfsOut struct { - outHeader - St kstatfs -} - -type fsyncIn struct { - Fh uint64 - FsyncFlags uint32 - Padding uint32 -} - -type setxattrIn struct { - Size uint32 - Flags uint32 -} - -type setxattrInOSX struct { - Size uint32 - Flags uint32 - - // OS X only - Position uint32 - Padding uint32 -} - -type getxattrIn struct { - Size uint32 - Padding uint32 -} - -type getxattrInOSX struct { - Size uint32 - Padding uint32 - - // OS X only - Position uint32 - Padding2 uint32 -} - -type getxattrOut struct { - outHeader - Size uint32 - Padding uint32 -} - -type lkIn struct { - Fh uint64 - Owner uint64 - Lk fileLock -} - -type lkOut struct { - outHeader - Lk fileLock -} - -type accessIn struct { - Mask uint32 - Padding uint32 -} - -type initIn struct { - Major uint32 - Minor uint32 - MaxReadahead uint32 - Flags uint32 -} - -const initInSize = int(unsafe.Sizeof(initIn{})) - -type initOut struct { - outHeader - Major uint32 - Minor uint32 - MaxReadahead uint32 - Flags uint32 - Unused uint32 - MaxWrite uint32 -} - -type interruptIn struct { - Unique uint64 -} - -type bmapIn struct { - Block uint64 - BlockSize uint32 - Padding uint32 -} - -type bmapOut struct { - outHeader - Block uint64 -} - -type inHeader struct { - Len uint32 - Opcode uint32 - Unique uint64 - Nodeid uint64 - Uid uint32 - Gid uint32 - Pid uint32 - Padding uint32 -} - -const inHeaderSize = int(unsafe.Sizeof(inHeader{})) - -type outHeader struct { - Len uint32 - Error int32 - Unique uint64 -} - -type dirent struct { - Ino uint64 - Off uint64 - Namelen uint32 - Type uint32 - Name [0]byte -} - -const direntSize = 8 + 8 + 4 + 4 diff --git a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_darwin.go b/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_darwin.go deleted file mode 100644 index f7bc37766..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_darwin.go +++ /dev/null @@ -1,58 +0,0 @@ -package fuse - -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) -} - -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_ -} diff --git a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_linux.go b/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_linux.go deleted file mode 100644 index 914bc3063..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_linux.go +++ /dev/null @@ -1,50 +0,0 @@ -package fuse - -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 // Only in protocol 7.9 - // padding_ uint32 // Only in protocol 7.9 -} - -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 -} diff --git a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_std.go b/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_std.go deleted file mode 100644 index 074cfd322..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/fuse_kernel_std.go +++ /dev/null @@ -1 +0,0 @@ -package fuse diff --git a/vendor/github.com/mattermost/rsc/fuse/fuse_test.go b/vendor/github.com/mattermost/rsc/fuse/fuse_test.go deleted file mode 100644 index 61533b8c5..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/fuse_test.go +++ /dev/null @@ -1,594 +0,0 @@ -// Copyright 2012 The Go 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 ( - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "os/exec" - "runtime" - "syscall" - "testing" - "time" -) - -var fuseRun = flag.String("fuserun", "", "which fuse test to run. runs all if empty.") - -// umount tries its best to unmount dir. -func umount(dir string) { - err := exec.Command("umount", dir).Run() - if err != nil && runtime.GOOS == "linux" { - exec.Command("/bin/fusermount", "-u", dir).Run() - } -} - -func TestFuse(t *testing.T) { - Debugf = log.Printf - dir, err := ioutil.TempDir("", "fusetest") - if err != nil { - t.Fatal(err) - } - os.MkdirAll(dir, 0777) - - c, err := Mount(dir) - if err != nil { - t.Fatal(err) - } - defer umount(dir) - - go func() { - err := c.Serve(testFS{}) - if err != nil { - fmt.Printf("SERVE ERROR: %v\n", err) - } - }() - - waitForMount(t, dir) - - for _, tt := range fuseTests { - if *fuseRun == "" || *fuseRun == tt.name { - t.Logf("running %T", tt.node) - tt.node.test(dir+"/"+tt.name, t) - } - } -} - -func waitForMount(t *testing.T, dir string) { - // Filename to wait for in dir: - probeEntry := *fuseRun - if probeEntry == "" { - probeEntry = fuseTests[0].name - } - for tries := 0; tries < 100; tries++ { - _, err := os.Stat(dir + "/" + probeEntry) - if err == nil { - return - } - time.Sleep(10 * time.Millisecond) - } - t.Fatalf("mount did not work") -} - -var fuseTests = []struct { - name string - node interface { - Node - test(string, *testing.T) - } -}{ - {"readAll", readAll{}}, - {"readAll1", &readAll1{}}, - {"write", &write{}}, - {"writeAll", &writeAll{}}, - {"writeAll2", &writeAll2{}}, - {"release", &release{}}, - {"mkdir1", &mkdir1{}}, - {"create1", &create1{}}, - {"create2", &create2{}}, - {"symlink1", &symlink1{}}, - {"link1", &link1{}}, - {"rename1", &rename1{}}, - {"mknod1", &mknod1{}}, -} - -// TO TEST: -// Statfs -// Lookup(*LookupRequest, *LookupResponse) -// Getattr(*GetattrRequest, *GetattrResponse) -// Attr with explicit inode -// Setattr(*SetattrRequest, *SetattrResponse) -// Access(*AccessRequest) -// Open(*OpenRequest, *OpenResponse) -// Getxattr, Setxattr, Listxattr, Removexattr -// Write(*WriteRequest, *WriteResponse) -// Flush(*FlushRequest, *FlushResponse) - -// Test Read calling ReadAll. - -type readAll struct{ file } - -const hi = "hello, world" - -func (readAll) ReadAll(intr Intr) ([]byte, Error) { - return []byte(hi), nil -} - -func (readAll) test(path string, t *testing.T) { - data, err := ioutil.ReadFile(path) - if err != nil { - t.Errorf("readAll: %v", err) - return - } - if string(data) != hi { - t.Errorf("readAll = %q, want %q", data, hi) - } -} - -// Test Read. - -type readAll1 struct{ file } - -func (readAll1) Read(req *ReadRequest, resp *ReadResponse, intr Intr) Error { - HandleRead(req, resp, []byte(hi)) - return nil -} - -func (readAll1) test(path string, t *testing.T) { - readAll{}.test(path, t) -} - -// Test Write calling basic Write, with an fsync thrown in too. - -type write struct { - file - data []byte - gotfsync bool -} - -func (w *write) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error { - w.data = append(w.data, req.Data...) - resp.Size = len(req.Data) - return nil -} - -func (w *write) Fsync(r *FsyncRequest, intr Intr) Error { - w.gotfsync = true - return nil -} - -func (w *write) test(path string, t *testing.T) { - log.Printf("pre-write Create") - f, err := os.Create(path) - if err != nil { - t.Fatalf("Create: %v", err) - } - log.Printf("pre-write Write") - n, err := f.Write([]byte(hi)) - if err != nil { - t.Fatalf("Write: %v", err) - } - if n != len(hi) { - t.Fatalf("short write; n=%d; hi=%d", n, len(hi)) - } - - err = syscall.Fsync(int(f.Fd())) - if err != nil { - t.Fatalf("Fsync = %v", err) - } - if !w.gotfsync { - t.Errorf("never received expected fsync call") - } - - log.Printf("pre-write Close") - err = f.Close() - if err != nil { - t.Fatalf("Close: %v", err) - } - log.Printf("post-write Close") - if string(w.data) != hi { - t.Errorf("writeAll = %q, want %q", w.data, hi) - } -} - -// Test Write calling WriteAll. - -type writeAll struct { - file - data []byte - gotfsync bool -} - -func (w *writeAll) Fsync(r *FsyncRequest, intr Intr) Error { - w.gotfsync = true - return nil -} - -func (w *writeAll) WriteAll(data []byte, intr Intr) Error { - w.data = data - return nil -} - -func (w *writeAll) test(path string, t *testing.T) { - err := ioutil.WriteFile(path, []byte(hi), 0666) - if err != nil { - t.Fatalf("WriteFile: %v", err) - return - } - if string(w.data) != hi { - t.Errorf("writeAll = %q, want %q", w.data, hi) - } -} - -// Test Write calling Setattr+Write+Flush. - -type writeAll2 struct { - file - data []byte - setattr bool - flush bool -} - -func (w *writeAll2) Setattr(req *SetattrRequest, resp *SetattrResponse, intr Intr) Error { - w.setattr = true - return nil -} - -func (w *writeAll2) Flush(req *FlushRequest, intr Intr) Error { - w.flush = true - return nil -} - -func (w *writeAll2) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error { - w.data = append(w.data, req.Data...) - resp.Size = len(req.Data) - return nil -} - -func (w *writeAll2) test(path string, t *testing.T) { - err := ioutil.WriteFile(path, []byte(hi), 0666) - if err != nil { - t.Errorf("WriteFile: %v", err) - return - } - if !w.setattr || string(w.data) != hi || !w.flush { - t.Errorf("writeAll = %v, %q, %v, want %v, %q, %v", w.setattr, string(w.data), w.flush, true, hi, true) - } -} - -// Test Mkdir. - -type mkdir1 struct { - dir - name string -} - -func (f *mkdir1) Mkdir(req *MkdirRequest, intr Intr) (Node, Error) { - f.name = req.Name - return &mkdir1{}, nil -} - -func (f *mkdir1) test(path string, t *testing.T) { - f.name = "" - err := os.Mkdir(path+"/foo", 0777) - if err != nil { - t.Error(err) - return - } - if f.name != "foo" { - t.Error(err) - return - } -} - -// Test Create (and fsync) - -type create1 struct { - dir - name string - f *writeAll -} - -func (f *create1) Create(req *CreateRequest, resp *CreateResponse, intr Intr) (Node, Handle, Error) { - f.name = req.Name - f.f = &writeAll{} - return f.f, f.f, nil -} - -func (f *create1) test(path string, t *testing.T) { - f.name = "" - ff, err := os.Create(path + "/foo") - if err != nil { - t.Errorf("create1 WriteFile: %v", err) - return - } - - err = syscall.Fsync(int(ff.Fd())) - if err != nil { - t.Fatalf("Fsync = %v", err) - } - - if !f.f.gotfsync { - t.Errorf("never received expected fsync call") - } - - ff.Close() - if f.name != "foo" { - t.Errorf("create1 name=%q want foo", f.name) - } -} - -// Test Create + WriteAll + Remove - -type create2 struct { - dir - name string - f *writeAll - fooExists bool -} - -func (f *create2) Create(req *CreateRequest, resp *CreateResponse, intr Intr) (Node, Handle, Error) { - f.name = req.Name - f.f = &writeAll{} - return f.f, f.f, nil -} - -func (f *create2) Lookup(name string, intr Intr) (Node, Error) { - if f.fooExists && name == "foo" { - return file{}, nil - } - return nil, ENOENT -} - -func (f *create2) Remove(r *RemoveRequest, intr Intr) Error { - if f.fooExists && r.Name == "foo" && !r.Dir { - f.fooExists = false - return nil - } - return ENOENT -} - -func (f *create2) test(path string, t *testing.T) { - f.name = "" - err := ioutil.WriteFile(path+"/foo", []byte(hi), 0666) - if err != nil { - t.Fatalf("create2 WriteFile: %v", err) - } - if string(f.f.data) != hi { - t.Fatalf("create2 writeAll = %q, want %q", f.f.data, hi) - } - - f.fooExists = true - log.Printf("pre-Remove") - err = os.Remove(path + "/foo") - if err != nil { - t.Fatalf("Remove: %v", err) - } - err = os.Remove(path + "/foo") - if err == nil { - t.Fatalf("second Remove = nil; want some error") - } -} - -// Test symlink + readlink - -type symlink1 struct { - dir - newName, target string -} - -func (f *symlink1) Symlink(req *SymlinkRequest, intr Intr) (Node, Error) { - f.newName = req.NewName - f.target = req.Target - return symlink{target: req.Target}, nil -} - -func (f *symlink1) test(path string, t *testing.T) { - const target = "/some-target" - - err := os.Symlink(target, path+"/symlink.file") - if err != nil { - t.Errorf("os.Symlink: %v", err) - return - } - - if f.newName != "symlink.file" { - t.Errorf("symlink newName = %q; want %q", f.newName, "symlink.file") - } - if f.target != target { - t.Errorf("symlink target = %q; want %q", f.target, target) - } - - gotName, err := os.Readlink(path + "/symlink.file") - if err != nil { - t.Errorf("os.Readlink: %v", err) - return - } - if gotName != target { - t.Errorf("os.Readlink = %q; want %q", gotName, target) - } -} - -// Test link - -type link1 struct { - dir - newName string -} - -func (f *link1) Lookup(name string, intr Intr) (Node, Error) { - if name == "old" { - return file{}, nil - } - return nil, ENOENT -} - -func (f *link1) Link(r *LinkRequest, old Node, intr Intr) (Node, Error) { - f.newName = r.NewName - return file{}, nil -} - -func (f *link1) test(path string, t *testing.T) { - err := os.Link(path+"/old", path+"/new") - if err != nil { - t.Fatalf("Link: %v", err) - } - if f.newName != "new" { - t.Fatalf("saw Link for newName %q; want %q", f.newName, "new") - } -} - -// Test Rename - -type rename1 struct { - dir - renames int -} - -func (f *rename1) Lookup(name string, intr Intr) (Node, Error) { - if name == "old" { - return file{}, nil - } - return nil, ENOENT -} - -func (f *rename1) Rename(r *RenameRequest, newDir Node, intr Intr) Error { - if r.OldName == "old" && r.NewName == "new" && newDir == f { - f.renames++ - return nil - } - return EIO -} - -func (f *rename1) test(path string, t *testing.T) { - err := os.Rename(path+"/old", path+"/new") - if err != nil { - t.Fatalf("Rename: %v", err) - } - if f.renames != 1 { - t.Fatalf("expected rename didn't happen") - } - err = os.Rename(path+"/old2", path+"/new2") - if err == nil { - t.Fatal("expected error on second Rename; got nil") - } -} - -// Test Release. - -type release struct { - file - did bool -} - -func (r *release) Release(*ReleaseRequest, Intr) Error { - r.did = true - return nil -} - -func (r *release) test(path string, t *testing.T) { - r.did = false - f, err := os.Open(path) - if err != nil { - t.Error(err) - return - } - f.Close() - time.Sleep(1 * time.Second) - if !r.did { - t.Error("Close did not Release") - } -} - -// Test mknod - -type mknod1 struct { - dir - gotr *MknodRequest -} - -func (f *mknod1) Mknod(r *MknodRequest, intr Intr) (Node, Error) { - f.gotr = r - return fifo{}, nil -} - -func (f *mknod1) test(path string, t *testing.T) { - if os.Getuid() != 0 { - t.Logf("skipping unless root") - return - } - defer syscall.Umask(syscall.Umask(0)) - err := syscall.Mknod(path+"/node", syscall.S_IFIFO|0666, 123) - if err != nil { - t.Fatalf("Mknod: %v", err) - } - if f.gotr == nil { - t.Fatalf("no recorded MknodRequest") - } - if g, e := f.gotr.Name, "node"; g != e { - t.Errorf("got Name = %q; want %q", g, e) - } - if g, e := f.gotr.Rdev, uint32(123); g != e { - if runtime.GOOS == "linux" { - // Linux fuse doesn't echo back the rdev if the node - // isn't a device (we're using a FIFO here, as that - // bit is portable.) - } else { - t.Errorf("got Rdev = %v; want %v", g, e) - } - } - if g, e := f.gotr.Mode, os.FileMode(os.ModeNamedPipe|0666); g != e { - t.Errorf("got Mode = %v; want %v", g, e) - } - t.Logf("Got request: %#v", f.gotr) -} - -type file struct{} -type dir struct{} -type fifo struct{} -type symlink struct { - target string -} - -func (f file) Attr() Attr { return Attr{Mode: 0666} } -func (f dir) Attr() Attr { return Attr{Mode: os.ModeDir | 0777} } -func (f fifo) Attr() Attr { return Attr{Mode: os.ModeNamedPipe | 0666} } -func (f symlink) Attr() Attr { return Attr{Mode: os.ModeSymlink | 0666} } - -func (f symlink) Readlink(*ReadlinkRequest, Intr) (string, Error) { - return f.target, nil -} - -type testFS struct{} - -func (testFS) Root() (Node, Error) { - return testFS{}, nil -} - -func (testFS) Attr() Attr { - return Attr{Mode: os.ModeDir | 0555} -} - -func (testFS) Lookup(name string, intr Intr) (Node, Error) { - for _, tt := range fuseTests { - if tt.name == name { - return tt.node, nil - } - } - return nil, ENOENT -} - -func (testFS) ReadDir(intr Intr) ([]Dirent, Error) { - var dirs []Dirent - for _, tt := range fuseTests { - if *fuseRun == "" || *fuseRun == tt.name { - log.Printf("Readdir; adding %q", tt.name) - dirs = append(dirs, Dirent{Name: tt.name}) - } - } - return dirs, nil -} diff --git a/vendor/github.com/mattermost/rsc/fuse/hellofs/hello.go b/vendor/github.com/mattermost/rsc/fuse/hellofs/hello.go deleted file mode 100644 index d915473f1..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/hellofs/hello.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Hellofs implements a simple "hello world" file system. -package main - -import ( - "log" - "os" - - "github.com/mattermost/rsc/fuse" -) - -func main() { - c, err := fuse.Mount("/mnt/hellofs") - if err != nil { - log.Fatal(err) - } - - c.Serve(FS{}) -} - -// FS implements the hello world file system. -type FS struct{} - -func (FS) Root() (fuse.Node, fuse.Error) { - return Dir{}, nil -} - -// Dir implements both Node and Handle for the root directory. -type Dir struct{} - -func (Dir) Attr() fuse.Attr { - return fuse.Attr{Mode: os.ModeDir | 0555} -} - -func (Dir) Lookup(name string, intr fuse.Intr) (fuse.Node, fuse.Error) { - if name == "hello" { - return File{}, nil - } - return nil, fuse.ENOENT -} - -var dirDirs = []fuse.Dirent{ - {Inode: 2, Name: "hello", Type: 0}, -} - -func (Dir) ReadDir(intr fuse.Intr) ([]fuse.Dirent, fuse.Error) { - return dirDirs, nil -} - -// File implements both Node and Handle for the hello file. -type File struct{} - -func (File) Attr() fuse.Attr { - return fuse.Attr{Mode: 0444} -} - -func (File) ReadAll(intr fuse.Intr) ([]byte, fuse.Error) { - return []byte("hello, world\n"), nil -} diff --git a/vendor/github.com/mattermost/rsc/fuse/mount_darwin.go b/vendor/github.com/mattermost/rsc/fuse/mount_darwin.go deleted file mode 100644 index 5e2caaa76..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/mount_darwin.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// TODO: Rewrite using package syscall not cgo - -package fuse - -/* - -// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c, -// which carries this notice: -// -// The files in this directory are subject to the following license. -// -// The author of this software is Russ Cox. -// -// Copyright (c) 2006 Russ Cox -// -// Permission to use, copy, modify, and distribute this software for any -// purpose without fee is hereby granted, provided that this entire notice -// is included in all copies of any software which is or includes a copy -// or modification of this software and in all copies of the supporting -// documentation for such software. -// -// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED -// WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY -// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS -// FITNESS FOR ANY PARTICULAR PURPOSE. - -#include <stdlib.h> -#include <sys/param.h> -#include <sys/mount.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> - -#define nil ((void*)0) - -static int -mountfuse(char *mtpt, char **err) -{ - int i, pid, fd, r; - char buf[200]; - struct vfsconf vfs; - char *f; - - if(getvfsbyname("fusefs", &vfs) < 0){ - if(access(f="/Library/Filesystems/osxfusefs.fs" - "/Support/load_osxfusefs", 0) < 0){ - *err = strdup("cannot find load_fusefs"); - return -1; - } - if((r=system(f)) < 0){ - snprintf(buf, sizeof buf, "%s: %s", f, strerror(errno)); - *err = strdup(buf); - return -1; - } - if(r != 0){ - snprintf(buf, sizeof buf, "load_fusefs failed: exit %d", r); - *err = strdup(buf); - return -1; - } - if(getvfsbyname("osxfusefs", &vfs) < 0){ - snprintf(buf, sizeof buf, "getvfsbyname osxfusefs: %s", strerror(errno)); - *err = strdup(buf); - return -1; - } - } - - // Look for available FUSE device. - for(i=0;; i++){ - snprintf(buf, sizeof buf, "/dev/osxfuse%d", i); - if(access(buf, 0) < 0){ - *err = strdup("no available fuse devices"); - return -1; - } - if((fd = open(buf, O_RDWR)) >= 0) - break; - } - - pid = fork(); - if(pid < 0) - return -1; - if(pid == 0){ - snprintf(buf, sizeof buf, "%d", fd); - setenv("MOUNT_FUSEFS_CALL_BY_LIB", "", 1); - // Different versions of MacFUSE put the - // mount_fusefs binary in different places. - // Try all. - // Leopard location - setenv("MOUNT_FUSEFS_DAEMON_PATH", - "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs", 1); - execl("/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs", - "mount_osxfusefs", - "-o", "iosize=4096", buf, mtpt, nil); - fprintf(stderr, "exec mount_osxfusefs: %s\n", strerror(errno)); - _exit(1); - } - return fd; -} - -*/ -import "C" - -import "unsafe" - -func mount(dir string) (int, string) { - errp := (**C.char)(C.malloc(16)) - *errp = nil - defer C.free(unsafe.Pointer(errp)) - cdir := C.CString(dir) - defer C.free(unsafe.Pointer(cdir)) - fd := C.mountfuse(cdir, errp) - var err string - if *errp != nil { - err = C.GoString(*errp) - } - return int(fd), err -} diff --git a/vendor/github.com/mattermost/rsc/fuse/mount_linux.go b/vendor/github.com/mattermost/rsc/fuse/mount_linux.go deleted file mode 100644 index e5bc58b8a..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/mount_linux.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2012 The Go 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 ( - "fmt" - "net" - "os" - "os/exec" - "syscall" -) - -func mount(dir string) (fusefd int, errmsg string) { - fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0) - if err != nil { - return -1, fmt.Sprintf("socketpair error: %v", err) - } - defer syscall.Close(fds[0]) - defer syscall.Close(fds[1]) - - cmd := exec.Command("/bin/fusermount", "--", dir) - cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3") - - writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes") - defer writeFile.Close() - cmd.ExtraFiles = []*os.File{writeFile} - - out, err := cmd.CombinedOutput() - if len(out) > 0 || err != nil { - return -1, fmt.Sprintf("fusermount: %q, %v", out, err) - } - - readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads") - defer readFile.Close() - c, err := net.FileConn(readFile) - if err != nil { - return -1, fmt.Sprintf("FileConn from fusermount socket: %v", err) - } - defer c.Close() - - uc, ok := c.(*net.UnixConn) - if !ok { - return -1, fmt.Sprintf("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 -1, fmt.Sprintf("ParseSocketControlMessage: %v", err) - } - if len(scms) != 1 { - return -1, fmt.Sprintf("expected 1 SocketControlMessage; got scms = %#v", scms) - } - scm := scms[0] - gotFds, err := syscall.ParseUnixRights(&scm) - if err != nil { - return -1, fmt.Sprintf("syscall.ParseUnixRights: %v", err) - } - if len(gotFds) != 1 { - return -1, fmt.Sprintf("wanted 1 fd; got %#v", gotFds) - } - return gotFds[0], "" -} diff --git a/vendor/github.com/mattermost/rsc/fuse/serve.go b/vendor/github.com/mattermost/rsc/fuse/serve.go deleted file mode 100644 index fa4f27e3f..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/serve.go +++ /dev/null @@ -1,1022 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// FUSE service loop, for servers that wish to use it. - -package fuse - -import ( - "fmt" - "hash/fnv" - "io" - "log" - "os" - "path" - "sync" - "syscall" - "time" -) - -// TODO: FINISH DOCS - -// An Intr is a channel that signals that a request has been interrupted. -// Being able to receive from the channel means the request has been -// interrupted. -type Intr chan struct{} - -func (Intr) String() string { return "fuse.Intr" } - -// An FS is the interface required of a file system. -// -// Root() (Node, Error) -// -// Root is called to obtain the Node for the file system root. -// -// Optional Methods -// -// An FS implementation may implement -// additional methods to handle the corresponding FUSE requests: -// -// Init(req *InitRequest, resp *InitResponse) Error -// -// Init is called to initialize the FUSE connection. -// It can inspect the request and adjust the response as desired. -// The default response sets MaxReadahead to 0 and MaxWrite to 4096. -// Init must return promptly. -// -// Statfs(resp *StatfsResponse, intr Intr) Error -// -// Statfs is called to obtain file system metadata. It should write that data to resp. -// -// Rename(req *RenameRequest, intr Intr) Error -// -// XXXX this is not implemented like this. Instead, Rename is a method -// on the source dierctory node, and takes a newDir Node parameter. Fix it like this? -// Rename is called to rename the file req.OldName in the directory req.OldDir to -// become the file req.NewName in the directory req.NewDir. -// -type FS interface { - Root() (Node, Error) -} - -// A Node is the interface required of a file or directory. -// See the documentation for type FS for general information -// pertaining to all methods. -// -// Getattr(resp *GetattrResponse, intr Intr) fuse.Error -// -// Getattr obtains the standard metadata for the receiver. -// It should store that metadata in resp. -// -// Open(xxx, intr Intr) (Handle, fuse.Error) -// -// Open opens the receiver. -// XXX note about access. XXX OpenFlags. -// XXX note that the Node may be a file or directory. -// -// Optional Methods -// -// An Node implementation may implement additional methods -// to handle the corresponding FUSE requests. -// -// These optional requests can be called for both file and directory nodes: -// -// Access -// -// Access checks whether the calling context has permission for -// the given operations on the receiver. If so, Access should return nil. If not, Access should -// return EPERM. Note that this call affects the result of the access(2) system call -// but not the open(2) system call. If Access is not implemented, the Node behaves -// as if it always returns nil (permission granted), relying on checks in Open instead. -// -// Getxattr -// -// Getxattr obtains an extended attribute for the receiver. -// XXX -// -// Listxattr -// -// Listxattr lists the extended attributes recorded for the receiver. -// -// Removexattr -// -// Removexattr removes an extended attribute from the receiver. -// -// Setattr -// -// Setattr sets the standard metadata for the receiver. -// -// Setxattr -// -// Setxattr sets an extended attribute for the receiver. -// -// Optional Directory Methods -// -// These optional requests will be called only for directory nodes: -// -// Create(xxx) -// -// Create creates -// -// Link(xxx) -// -// Link XXX -// -// Lookup(name string, intr Intr) (Node, Error) -// -// Lookup looks up a specific entry in the receiver, -// which must be a directory. Lookup should return a Node -// corresponding to the entry. If the name does not exist in -// the directory, Lookup should return nil, err. -// -// Lookup need not to handle the names "." and "..". -// -// Mkdir -// -// Mkdir creates XXX -// -// Mknod XXX -// -// XXX -// -// Remove -// -// Remove removes the entry with the given name from -// the receiver, which must be a directory. The entry to be removed -// may correspond to a file (unlink) or to a directory (rmdir). -// -// Symlink -// -// Symlink creates a new symbolic link in the receiver, which must be a directory. -// The entry -// -// Optional Symlink Methods -// -// This optional request will be called only for symbolic link nodes: -// -// Readlink -// -// Readlink reads a symbolic link. -type Node interface { - Attr() Attr -} - -var startTime = time.Now() - -func nodeAttr(inode uint64, n Node) (attr Attr) { - attr = n.Attr() - if attr.Nlink == 0 { - attr.Nlink = 1 - } - if attr.Atime.IsZero() { - attr.Atime = startTime - } - if attr.Mtime.IsZero() { - attr.Mtime = startTime - } - if attr.Ctime.IsZero() { - attr.Ctime = startTime - } - if attr.Crtime.IsZero() { - attr.Crtime = startTime - } - if attr.Inode == 0 { - attr.Inode = inode - } - return -} - -// A Handle is the interface required of an opened file or directory. -// See the documentation for type FS for general information -// pertaining to all methods. -// -// Flush -// -// Flush is called each time the file or directory is closed. Because there can be -// multiple file descriptors referring to a single opened file, Flush can be called -// multiple times. -// -// Optional Methods -// -// A Handle implementation may implement additional methods to handle -// the corresponding FUSE requests. The most common to implement are -// Read, ReadDir, and Write. -// -// Fsync -// -// Getlk -// -// Read -// -// Readdir -// -// Release -// -// Setlk -// -// Setlkw -// -// Write -// -type Handle interface { -} - -// Serve serves the FUSE connection by making calls to the methods -// of fs and the Nodes and Handles it makes available. It returns only -// when the connection has been closed or an unexpected error occurs. -func (c *Conn) Serve(fs FS) error { - if c.req != nil { - panic("fuse: Serve called twice") - } - c.req = map[RequestID]*serveRequest{} - - root, err := fs.Root() - if err != nil { - return fmt.Errorf("cannot obtain root node: %v", syscall.Errno(err.(Errno)).Error()) - } - c.node = append(c.node, nil, &serveNode{name: "/", node: root}) - c.handle = append(c.handle, nil) - - for { - req, err := c.ReadRequest() - if err != nil { - if err == io.EOF { - break - } - return err - } - - go c.serve(fs, req) - } - return nil -} - -type serveConn struct { - meta sync.Mutex - req map[RequestID]*serveRequest - node []*serveNode - handle []*serveHandle - freeNode []NodeID - freeHandle []HandleID - nodeGen uint64 - nodeHandles []map[HandleID]bool // open handles for a node; slice index is NodeID -} - -type serveRequest struct { - Request Request - Intr Intr -} - -type serveNode struct { - name string - node Node - inode uint64 - isDir bool -} - -func (sn *serveNode) attr() (attr Attr) { - attr = nodeAttr(sn.inode, sn.node) - if attr.Inode == 0 { - sn.inode = hash(sn.name) - attr.Inode = sn.inode - } - sn.isDir = attr.Mode&os.ModeDir != 0 - return -} - -func hash(s string) uint64 { - f := fnv.New64() - f.Write([]byte(s)) - return f.Sum64() -} - -type serveHandle struct { - handle Handle - readData []byte - trunc bool - writeData []byte - nodeID NodeID -} - -func (c *Conn) saveNode(name string, node Node) (id NodeID, gen uint64, sn *serveNode) { - sn = &serveNode{name: name, node: node} - c.meta.Lock() - if n := len(c.freeNode); n > 0 { - id = c.freeNode[n-1] - c.freeNode = c.freeNode[:n-1] - c.node[id] = sn - c.nodeGen++ - } else { - id = NodeID(len(c.node)) - c.node = append(c.node, sn) - } - gen = c.nodeGen - c.meta.Unlock() - return -} - -func (c *Conn) saveHandle(handle Handle, nodeID NodeID) (id HandleID, shandle *serveHandle) { - c.meta.Lock() - shandle = &serveHandle{handle: handle, nodeID: nodeID} - if n := len(c.freeHandle); n > 0 { - id = c.freeHandle[n-1] - c.freeHandle = c.freeHandle[:n-1] - c.handle[id] = shandle - } else { - id = HandleID(len(c.handle)) - c.handle = append(c.handle, shandle) - } - - // Update mapping from node ID -> set of open Handle IDs. - for len(c.nodeHandles) <= int(nodeID) { - c.nodeHandles = append(c.nodeHandles, nil) - } - if c.nodeHandles[nodeID] == nil { - c.nodeHandles[nodeID] = make(map[HandleID]bool) - } - c.nodeHandles[nodeID][id] = true - - c.meta.Unlock() - return -} - -func (c *Conn) dropNode(id NodeID) { - c.meta.Lock() - c.node[id] = nil - if len(c.nodeHandles) > int(id) { - c.nodeHandles[id] = nil - } - c.freeNode = append(c.freeNode, id) - c.meta.Unlock() -} - -func (c *Conn) dropHandle(id HandleID) { - c.meta.Lock() - h := c.handle[id] - delete(c.nodeHandles[h.nodeID], id) - c.handle[id] = nil - c.freeHandle = append(c.freeHandle, id) - c.meta.Unlock() -} - -func (c *Conn) serve(fs FS, r Request) { - intr := make(Intr) - req := &serveRequest{Request: r, Intr: intr} - - Debugf("<- %s", req) - var node Node - var handle Handle - var snode *serveNode - var shandle *serveHandle - c.meta.Lock() - hdr := r.Hdr() - if id := hdr.Node; id != 0 { - if id < NodeID(len(c.node)) { - snode = c.node[uint(id)] - } - if snode == nil { - c.meta.Unlock() - println("missing node", id, len(c.node), snode) - Debugf("-> %#x %v", hdr.ID, ESTALE) - r.RespondError(ESTALE) - return - } - node = snode.node - } - if id := r.handle(); id != 0 { - if id < HandleID(len(c.handle)) { - shandle = c.handle[uint(id)] - } - if shandle == nil { - println("missing handle", id, len(c.handle), shandle) - c.meta.Unlock() - Debugf("-> %#x %v", hdr.ID, ESTALE) - r.RespondError(ESTALE) - return - } - handle = shandle.handle - } - intr = make(chan struct{}) - if c.req[hdr.ID] != nil { - // This happens with OSXFUSE. Assume it's okay and - // that we'll never see an interrupt for this one. - // Otherwise everything wedges. TODO: Report to OSXFUSE? - intr = nil - } else { - c.req[hdr.ID] = req - } - c.meta.Unlock() - - // Call this before responding. - // After responding is too late: we might get another request - // with the same ID and be very confused. - done := func(resp interface{}) { - Debugf("-> %#x %v", hdr.ID, resp) - c.meta.Lock() - c.req[hdr.ID] = nil - c.meta.Unlock() - } - - switch r := r.(type) { - default: - // Note: To FUSE, ENOSYS means "this server never implements this request." - // It would be inappropriate to return ENOSYS for other operations in this - // switch that might only be unavailable in some contexts, not all. - done(ENOSYS) - r.RespondError(ENOSYS) - - // FS operations. - case *InitRequest: - s := &InitResponse{ - MaxWrite: 4096, - } - if fs, ok := fs.(interface { - Init(*InitRequest, *InitResponse, Intr) Error - }); ok { - if err := fs.Init(r, s, intr); err != nil { - done(err) - r.RespondError(err) - break - } - } - done(s) - r.Respond(s) - - case *StatfsRequest: - s := &StatfsResponse{} - if fs, ok := fs.(interface { - Statfs(*StatfsRequest, *StatfsResponse, Intr) Error - }); ok { - if err := fs.Statfs(r, s, intr); err != nil { - done(err) - r.RespondError(err) - break - } - } - done(s) - r.Respond(s) - - // Node operations. - case *GetattrRequest: - s := &GetattrResponse{} - if n, ok := node.(interface { - Getattr(*GetattrRequest, *GetattrResponse, Intr) Error - }); ok { - if err := n.Getattr(r, s, intr); err != nil { - done(err) - r.RespondError(err) - break - } - } else { - s.AttrValid = 1 * time.Minute - s.Attr = snode.attr() - } - done(s) - r.Respond(s) - - case *SetattrRequest: - s := &SetattrResponse{} - - // Special-case truncation, if no other bits are set - // and the open Handles all have a WriteAll method. - if r.Valid&SetattrSize != 0 && r.Size == 0 { - type writeAll interface { - WriteAll([]byte, Intr) Error - } - switch r.Valid { - case SetattrLockOwner | SetattrSize, SetattrSize: - // Seen on Linux. Handle isn't set. - c.meta.Lock() - for hid := range c.nodeHandles[hdr.Node] { - shandle := c.handle[hid] - if _, ok := shandle.handle.(writeAll); ok { - shandle.trunc = true - } - } - c.meta.Unlock() - case SetattrHandle | SetattrSize: - // Seen on OS X; the Handle is provided. - if _, ok := handle.(writeAll); ok { - shandle.trunc = true - } - } - } - - log.Printf("setattr %v", r) - if n, ok := node.(interface { - Setattr(*SetattrRequest, *SetattrResponse, Intr) Error - }); ok { - if err := n.Setattr(r, s, intr); err != nil { - done(err) - r.RespondError(err) - break - } - done(s) - r.Respond(s) - break - } - - if s.AttrValid == 0 { - s.AttrValid = 1 * time.Minute - } - s.Attr = snode.attr() - done(s) - r.Respond(s) - - case *SymlinkRequest: - s := &SymlinkResponse{} - n, ok := node.(interface { - Symlink(*SymlinkRequest, Intr) (Node, Error) - }) - if !ok { - done(EIO) // XXX or EPERM like Mkdir? - r.RespondError(EIO) - break - } - n2, err := n.Symlink(r, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - c.saveLookup(&s.LookupResponse, snode, r.NewName, n2) - done(s) - r.Respond(s) - - case *ReadlinkRequest: - n, ok := node.(interface { - Readlink(*ReadlinkRequest, Intr) (string, Error) - }) - if !ok { - done(EIO) /// XXX or EPERM? - r.RespondError(EIO) - break - } - target, err := n.Readlink(r, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - done(target) - r.Respond(target) - - case *LinkRequest: - n, ok := node.(interface { - Link(r *LinkRequest, old Node, intr Intr) (Node, Error) - }) - if !ok { - log.Printf("Node %T doesn't implement fuse Link", node) - done(EIO) /// XXX or EPERM? - r.RespondError(EIO) - break - } - c.meta.Lock() - var oldNode *serveNode - if int(r.OldNode) < len(c.node) { - oldNode = c.node[r.OldNode] - } - c.meta.Unlock() - if oldNode == nil { - log.Printf("In LinkRequest, node %d not found", r.OldNode) - done(EIO) - r.RespondError(EIO) - break - } - n2, err := n.Link(r, oldNode.node, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - s := &LookupResponse{} - c.saveLookup(s, snode, r.NewName, n2) - done(s) - r.Respond(s) - - case *RemoveRequest: - n, ok := node.(interface { - Remove(*RemoveRequest, Intr) Error - }) - if !ok { - done(EIO) /// XXX or EPERM? - r.RespondError(EIO) - break - } - err := n.Remove(r, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - done(nil) - r.Respond() - - case *AccessRequest: - if n, ok := node.(interface { - Access(*AccessRequest, Intr) Error - }); ok { - if err := n.Access(r, intr); err != nil { - done(err) - r.RespondError(err) - break - } - } - done(r) - r.Respond() - - case *LookupRequest: - var n2 Node - var err Error - s := &LookupResponse{} - if n, ok := node.(interface { - Lookup(string, Intr) (Node, Error) - }); ok { - n2, err = n.Lookup(r.Name, intr) - } else if n, ok := node.(interface { - Lookup(*LookupRequest, *LookupResponse, Intr) (Node, Error) - }); ok { - n2, err = n.Lookup(r, s, intr) - } else { - done(ENOENT) - r.RespondError(ENOENT) - break - } - if err != nil { - done(err) - r.RespondError(err) - break - } - c.saveLookup(s, snode, r.Name, n2) - done(s) - r.Respond(s) - - case *MkdirRequest: - s := &MkdirResponse{} - n, ok := node.(interface { - Mkdir(*MkdirRequest, Intr) (Node, Error) - }) - if !ok { - done(EPERM) - r.RespondError(EPERM) - break - } - n2, err := n.Mkdir(r, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - c.saveLookup(&s.LookupResponse, snode, r.Name, n2) - done(s) - r.Respond(s) - - case *OpenRequest: - s := &OpenResponse{Flags: OpenDirectIO} - var h2 Handle - if n, ok := node.(interface { - Open(*OpenRequest, *OpenResponse, Intr) (Handle, Error) - }); ok { - hh, err := n.Open(r, s, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - h2 = hh - } else { - h2 = node - } - s.Handle, _ = c.saveHandle(h2, hdr.Node) - done(s) - r.Respond(s) - - case *CreateRequest: - n, ok := node.(interface { - Create(*CreateRequest, *CreateResponse, Intr) (Node, Handle, Error) - }) - if !ok { - // If we send back ENOSYS, FUSE will try mknod+open. - done(EPERM) - r.RespondError(EPERM) - break - } - s := &CreateResponse{OpenResponse: OpenResponse{Flags: OpenDirectIO}} - n2, h2, err := n.Create(r, s, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - c.saveLookup(&s.LookupResponse, snode, r.Name, n2) - h, shandle := c.saveHandle(h2, hdr.Node) - s.Handle = h - shandle.trunc = true - done(s) - r.Respond(s) - - case *GetxattrRequest, *SetxattrRequest, *ListxattrRequest, *RemovexattrRequest: - // TODO: Use n. - done(ENOSYS) - r.RespondError(ENOSYS) - - case *ForgetRequest: - n, ok := node.(interface { - Forget() - }) - if ok { - n.Forget() - } - c.dropNode(hdr.Node) - done(r) - r.Respond() - - // Handle operations. - case *ReadRequest: - s := &ReadResponse{Data: make([]byte, 0, r.Size)} - if snode.isDir { - if h, ok := handle.(interface { - ReadDir(Intr) ([]Dirent, Error) - }); ok { - if shandle.readData == nil { - attr := snode.attr() - dirs, err := h.ReadDir(intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - var data []byte - data = AppendDirent(data, Dirent{Inode: attr.Inode, Name: "."}) - data = AppendDirent(data, Dirent{Inode: attr.Inode, Name: ".."}) - for _, dir := range dirs { - if dir.Inode == 0 { - dir.Inode = hash(path.Join(snode.name, dir.Name)) - } - data = AppendDirent(data, dir) - } - shandle.readData = data - } - HandleRead(r, s, shandle.readData) - done(s) - r.Respond(s) - break - } - } else { - if h, ok := handle.(interface { - ReadAll(Intr) ([]byte, Error) - }); ok { - if shandle.readData == nil { - data, err := h.ReadAll(intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - if data == nil { - data = []byte{} - } - shandle.readData = data - } - HandleRead(r, s, shandle.readData) - done(s) - r.Respond(s) - break - } - } - h, ok := handle.(interface { - Read(*ReadRequest, *ReadResponse, Intr) Error - }) - if !ok { - fmt.Printf("NO READ FOR %T\n", handle) - done(EIO) - r.RespondError(EIO) - break - } - if err := h.Read(r, s, intr); err != nil { - done(err) - r.RespondError(err) - break - } - done(s) - r.Respond(s) - - case *WriteRequest: - s := &WriteResponse{} - if shandle.trunc && r.Offset == int64(len(shandle.writeData)) { - shandle.writeData = append(shandle.writeData, r.Data...) - s.Size = len(r.Data) - done(s) - r.Respond(s) - break - } - if h, ok := handle.(interface { - Write(*WriteRequest, *WriteResponse, Intr) Error - }); ok { - if err := h.Write(r, s, intr); err != nil { - done(err) - r.RespondError(err) - break - } - done(s) - r.Respond(s) - break - } - println("NO WRITE") - done(EIO) - r.RespondError(EIO) - - case *FlushRequest: - if shandle.trunc { - h := handle.(interface { - WriteAll([]byte, Intr) Error - }) - if err := h.WriteAll(shandle.writeData, intr); err != nil { - done(err) - r.RespondError(err) - break - } - shandle.writeData = nil - shandle.trunc = false - } - if h, ok := handle.(interface { - Flush(*FlushRequest, Intr) Error - }); ok { - if err := h.Flush(r, intr); err != nil { - done(err) - r.RespondError(err) - break - } - } - done(nil) - r.Respond() - - case *ReleaseRequest: - // No matter what, release the handle. - c.dropHandle(r.handle()) - if h, ok := handle.(interface { - Release(*ReleaseRequest, Intr) Error - }); ok { - if err := h.Release(r, intr); err != nil { - done(err) - r.RespondError(err) - break - } - } - done(nil) - r.Respond() - - case *DestroyRequest: - fs, ok := fs.(interface { - Destroy() - }) - if ok { - fs.Destroy() - } - done(nil) - r.Respond() - - case *RenameRequest: - c.meta.Lock() - var newDirNode *serveNode - if int(r.NewDir) < len(c.node) { - newDirNode = c.node[r.NewDir] - } - c.meta.Unlock() - if newDirNode == nil { - println("RENAME NEW DIR NODE NOT FOUND") - done(EIO) - r.RespondError(EIO) - break - } - n, ok := node.(interface { - Rename(r *RenameRequest, newDir Node, intr Intr) Error - }) - if !ok { - log.Printf("Node %T missing Rename method", node) - done(EIO) // XXX or EPERM like Mkdir? - r.RespondError(EIO) - break - } - err := n.Rename(r, newDirNode.node, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - done(nil) - r.Respond() - - case *MknodRequest: - n, ok := node.(interface { - Mknod(r *MknodRequest, intr Intr) (Node, Error) - }) - if !ok { - log.Printf("Node %T missing Mknod method", node) - done(EIO) - r.RespondError(EIO) - break - } - n2, err := n.Mknod(r, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - s := &LookupResponse{} - c.saveLookup(s, snode, r.Name, n2) - done(s) - r.Respond(s) - - case *FsyncRequest: - n, ok := node.(interface { - Fsync(r *FsyncRequest, intr Intr) Error - }) - if !ok { - log.Printf("Node %T missing Fsync method", node) - done(EIO) - r.RespondError(EIO) - break - } - err := n.Fsync(r, intr) - if err != nil { - done(err) - r.RespondError(err) - break - } - done(nil) - r.Respond() - - /* case *FsyncdirRequest: - done(ENOSYS) - r.RespondError(ENOSYS) - - case *GetlkRequest, *SetlkRequest, *SetlkwRequest: - done(ENOSYS) - r.RespondError(ENOSYS) - - // One of a kind. - case *InterruptRequest: - c.meta.Lock() - ireq := c.req[r.OldID] - if ireq != nil && ireq.Intr != nil { - close(ireq.Intr) - ireq.Intr = nil - } - c.meta.Unlock() - done(nil) - r.Respond() - - case *BmapRequest: - done(ENOSYS) - r.RespondError(ENOSYS) - - case *SetvolnameRequest, *GetxtimesRequest, *ExchangeRequest: - done(ENOSYS) - r.RespondError(ENOSYS) - */ - } -} - -func (c *Conn) saveLookup(s *LookupResponse, snode *serveNode, elem string, n2 Node) { - name := path.Join(snode.name, elem) - var sn *serveNode - s.Node, s.Generation, sn = c.saveNode(name, n2) - if s.EntryValid == 0 { - s.EntryValid = 1 * time.Minute - } - if s.AttrValid == 0 { - s.AttrValid = 1 * time.Minute - } - s.Attr = sn.attr() -} - -// HandleRead handles a read request assuming that data is the entire file content. -// It adjusts the amount returned in resp according to req.Offset and req.Size. -func HandleRead(req *ReadRequest, resp *ReadResponse, data []byte) { - if req.Offset >= int64(len(data)) { - data = nil - } else { - data = data[req.Offset:] - } - if len(data) > req.Size { - data = data[:req.Size] - } - n := copy(resp.Data[:req.Size], data) - resp.Data = resp.Data[:n] -} - -// DataHandle returns a read-only Handle that satisfies reads -// using the given data. -func DataHandle(data []byte) Handle { - return &dataHandle{data} -} - -type dataHandle struct { - data []byte -} - -func (d *dataHandle) Read(intr Intr) ([]byte, Error) { - return d.data, nil -} diff --git a/vendor/github.com/mattermost/rsc/fuse/tree.go b/vendor/github.com/mattermost/rsc/fuse/tree.go deleted file mode 100644 index fec0a748f..000000000 --- a/vendor/github.com/mattermost/rsc/fuse/tree.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// FUSE directory tree, for servers that wish to use it with the service loop. - -package fuse - -import ( - "os" - pathpkg "path" - "strings" -) - -// A Tree implements a basic directory tree for FUSE. -type Tree struct { - tree -} - -func (t *Tree) Root() (Node, Error) { - return &t.tree, nil -} - -// Add adds the path to the tree, resolving to the given node. -// If path or a prefix of path has already been added to the tree, -// Add panics. -func (t *Tree) Add(path string, node Node) { - path = pathpkg.Clean("/" + path)[1:] - elems := strings.Split(path, "/") - dir := Node(&t.tree) - for i, elem := range elems { - dt, ok := dir.(*tree) - if !ok { - panic("fuse: Tree.Add for " + strings.Join(elems[:i], "/") + " and " + path) - } - n := dt.lookup(elem) - if n != nil { - if i+1 == len(elems) { - panic("fuse: Tree.Add for " + path + " conflicts with " + elem) - } - dir = n - } else { - if i+1 == len(elems) { - dt.add(elem, node) - } else { - dir = &tree{} - dt.add(elem, dir) - } - } - } -} - -type treeDir struct { - name string - node Node -} - -type tree struct { - dir []treeDir -} - -func (t *tree) lookup(name string) Node { - for _, d := range t.dir { - if d.name == name { - return d.node - } - } - return nil -} - -func (t *tree) add(name string, n Node) { - t.dir = append(t.dir, treeDir{name, n}) -} - -func (t *tree) Attr() Attr { - return Attr{Mode: os.ModeDir | 0555} -} - -func (t *tree) Lookup(name string, intr Intr) (Node, Error) { - n := t.lookup(name) - if n != nil { - return n, nil - } - return nil, ENOENT -} - -func (t *tree) ReadDir(intr Intr) ([]Dirent, Error) { - var out []Dirent - for _, d := range t.dir { - out = append(out, Dirent{Name: d.name}) - } - return out, nil -} |