@cryptotaxi247 / kubo / commits / 91abcbe5e

deps: remove vendored fuse lib

License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>

Jakub Sztandera committed Feb 26, 2017 at 14:11 UTC 91abcbe5ed5b160fc33665459d99533cdcdd8e5a
70 files changed -9186
Godeps/_workspace/src/bazil.org/fuse/.gitattributes deleted
-2
@@ -1,2 +0,0 @@
1 -*.go filter=gofmt
2 -*.cgo filter=gofmt
Godeps/_workspace/src/bazil.org/fuse/.gitignore deleted
-8
@@ -1,8 +0,0 @@
1 -*~
2 -.#*
3 -## the next line needs to start with a backslash to avoid looking like
4 -## a comment
5 -\#*#
6 -.*.swp
7 -
8 -*.test
Godeps/_workspace/src/bazil.org/fuse/LICENSE deleted
-93
@@ -1,93 +0,0 @@
1 -Copyright (c) 2013-2015 Tommi Virtanen.
2 -Copyright (c) 2009, 2011, 2012 The Go Authors.
3 -All rights reserved.
4 -
5 -Redistribution and use in source and binary forms, with or without
6 -modification, are permitted provided that the following conditions are
7 -met:
8 -
9 - * Redistributions of source code must retain the above copyright
10 -notice, this list of conditions and the following disclaimer.
11 - * Redistributions in binary form must reproduce the above
12 -copyright notice, this list of conditions and the following disclaimer
13 -in the documentation and/or other materials provided with the
14 -distribution.
15 - * Neither the name of Google Inc. nor the names of its
16 -contributors may be used to endorse or promote products derived from
17 -this software without specific prior written permission.
18 -
19 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 -
31 -
32 -
33 -The following included software components have additional copyright
34 -notices and license terms that may differ from the above.
35 -
36 -
37 -File fuse.go:
38 -
39 -// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
40 -// which carries this notice:
41 -//
42 -// The files in this directory are subject to the following license.
43 -//
44 -// The author of this software is Russ Cox.
45 -//
46 -// Copyright (c) 2006 Russ Cox
47 -//
48 -// Permission to use, copy, modify, and distribute this software for any
49 -// purpose without fee is hereby granted, provided that this entire notice
50 -// is included in all copies of any software which is or includes a copy
51 -// or modification of this software and in all copies of the supporting
52 -// documentation for such software.
53 -//
54 -// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
55 -// WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY
56 -// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
57 -// FITNESS FOR ANY PARTICULAR PURPOSE.
58 -
59 -
60 -File fuse_kernel.go:
61 -
62 -// Derived from FUSE's fuse_kernel.h
63 -/*
64 - This file defines the kernel interface of FUSE
65 - Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
66 -
67 -
68 - This -- and only this -- header file may also be distributed under
69 - the terms of the BSD Licence as follows:
70 -
71 - Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
72 -
73 - Redistribution and use in source and binary forms, with or without
74 - modification, are permitted provided that the following conditions
75 - are met:
76 - 1. Redistributions of source code must retain the above copyright
77 - notice, this list of conditions and the following disclaimer.
78 - 2. Redistributions in binary form must reproduce the above copyright
79 - notice, this list of conditions and the following disclaimer in the
80 - documentation and/or other materials provided with the distribution.
81 -
82 - THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
83 - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85 - ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
86 - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
88 - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89 - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
90 - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91 - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
92 - SUCH DAMAGE.
93 -*/
Godeps/_workspace/src/bazil.org/fuse/README.md deleted
-23
@@ -1,23 +0,0 @@
1 -bazil.org/fuse -- Filesystems in Go
2 -===================================
3 -
4 -`bazil.org/fuse` is a Go library for writing FUSE userspace
5 -filesystems.
6 -
7 -It is a from-scratch implementation of the kernel-userspace
8 -communication protocol, and does not use the C library from the
9 -project called FUSE. `bazil.org/fuse` embraces Go fully for safety and
10 -ease of programming.
11 -
12 -Here’s how to get going:
13 -
14 - go get bazil.org/fuse
15 -
16 -Website: http://bazil.org/fuse/
17 -
18 -Github repository: https://github.com/bazil/fuse
19 -
20 -API docs: http://godoc.org/bazil.org/fuse
21 -
22 -Our thanks to Russ Cox for his fuse library, which this project is
23 -based on.
Godeps/_workspace/src/bazil.org/fuse/debug.go deleted
-21
@@ -1,21 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "runtime"
5 -)
6 -
7 -func stack() string {
8 - buf := make([]byte, 1024)
9 - return string(buf[:runtime.Stack(buf, false)])
10 -}
11 -
12 -func nop(msg interface{}) {}
13 -
14 -// Debug is called to output debug messages, including protocol
15 -// traces. The default behavior is to do nothing.
16 -//
17 -// The messages have human-friendly string representations and are
18 -// safe to marshal to JSON.
19 -//
20 -// Implementations must not retain msg.
21 -var Debug func(msg interface{}) = nop
Godeps/_workspace/src/bazil.org/fuse/doc/.gitignore deleted
-4
@@ -1,4 +0,0 @@
1 -/*.seq.svg
2 -
3 -# not ignoring *.seq.png; we want those committed to the repo
4 -# for embedding on Github
Godeps/_workspace/src/bazil.org/fuse/doc/README.md deleted
-6
@@ -1,6 +0,0 @@
1 -# bazil.org/fuse documentation
2 -
3 -See also API docs at http://godoc.org/bazil.org/fuse
4 -
5 -- [The mount sequence](mount-sequence.md)
6 -- [Writing documentation](writing-docs.md)
Godeps/_workspace/src/bazil.org/fuse/doc/mount-linux-error-init.seq deleted
-32
@@ -1,32 +0,0 @@
1 -seqdiag {
2 - app;
3 - fuse [label="bazil.org/fuse"];
4 - fusermount;
5 - kernel;
6 - mounts;
7 -
8 - app;
9 - fuse [label="bazil.org/fuse"];
10 - fusermount;
11 - kernel;
12 - mounts;
13 -
14 - app -> fuse [label="Mount"];
15 - fuse -> fusermount [label="spawn, pass socketpair fd"];
16 - fusermount -> kernel [label="open /dev/fuse"];
17 - fusermount -> kernel [label="mount(2)"];
18 - kernel ->> mounts [label="mount is visible"];
19 - fusermount <-- kernel [label="mount(2) returns"];
20 - fuse <<-- fusermount [diagonal, label="exit, receive /dev/fuse fd", leftnote="on Linux, successful exit here\nmeans the mount has happened,\nthough InitRequest might not have yet"];
21 - app <-- fuse [label="Mount returns\nConn.Ready is already closed"];
22 -
23 - app -> fuse [label="fs.Serve"];
24 - fuse => kernel [label="read /dev/fuse fd", note="starts with InitRequest"];
25 - fuse -> app [label="Init"];
26 - fuse <-- app [color=red];
27 - fuse -> kernel [label="write /dev/fuse fd", color=red];
28 - kernel -> kernel [label="set connection\nstate to error", color=red];
29 - fuse <-- kernel;
30 - ... conn.MountError == nil, so it is still mounted ...
31 - ... call conn.Close to clean up ...
32 -}
Godeps/_workspace/src/bazil.org/fuse/doc/mount-linux-error-init.seq.png
Binary files a/Godeps/_workspace/src/bazil.org/fuse/doc/mount-linux-error-init.seq.png and /dev/null differ
Godeps/_workspace/src/bazil.org/fuse/doc/mount-linux.seq deleted
-41
@@ -1,41 +0,0 @@
1 -seqdiag {
2 - // seqdiag -T svg -o doc/mount-osx.svg doc/mount-osx.seq
3 - app;
4 - fuse [label="bazil.org/fuse"];
5 - fusermount;
6 - kernel;
7 - mounts;
8 -
9 - app -> fuse [label="Mount"];
10 - fuse -> fusermount [label="spawn, pass socketpair fd"];
11 - fusermount -> kernel [label="open /dev/fuse"];
12 - fusermount -> kernel [label="mount(2)"];
13 - kernel ->> mounts [label="mount is visible"];
14 - fusermount <-- kernel [label="mount(2) returns"];
15 - fuse <<-- fusermount [diagonal, label="exit, receive /dev/fuse fd", leftnote="on Linux, successful exit here\nmeans the mount has happened,\nthough InitRequest might not have yet"];
16 - app <-- fuse [label="Mount returns\nConn.Ready is already closed", rightnote="InitRequest and StatfsRequest\nmay or may not be seen\nbefore Conn.Ready,\ndepending on platform"];
17 -
18 - app -> fuse [label="fs.Serve"];
19 - fuse => kernel [label="read /dev/fuse fd", note="starts with InitRequest"];
20 - fuse => app [label="FS/Node/Handle methods"];
21 - fuse => kernel [label="write /dev/fuse fd"];
22 - ... repeat ...
23 -
24 - ... shutting down ...
25 - app -> fuse [label="Unmount"];
26 - fuse -> fusermount [label="fusermount -u"];
27 - fusermount -> kernel;
28 - kernel <<-- mounts;
29 - fusermount <-- kernel;
30 - fuse <<-- fusermount [diagonal];
31 - app <-- fuse [label="Unmount returns"];
32 -
33 - // actually triggers before above
34 - fuse <<-- kernel [diagonal, label="/dev/fuse EOF"];
35 - app <-- fuse [label="fs.Serve returns"];
36 -
37 - app -> fuse [label="conn.Close"];
38 - fuse -> kernel [label="close /dev/fuse fd"];
39 - fuse <-- kernel;
40 - app <-- fuse;
41 -}
Godeps/_workspace/src/bazil.org/fuse/doc/mount-linux.seq.png
Binary files a/Godeps/_workspace/src/bazil.org/fuse/doc/mount-linux.seq.png and /dev/null differ
Godeps/_workspace/src/bazil.org/fuse/doc/mount-osx-error-init.seq deleted
-32
@@ -1,32 +0,0 @@
1 -seqdiag {
2 - app;
3 - fuse [label="bazil.org/fuse"];
4 - wait [label="callMount\nhelper goroutine"];
5 - mount_osxfusefs;
6 - kernel;
7 -
8 - app -> fuse [label="Mount"];
9 - fuse -> kernel [label="open /dev/osxfuseN"];
10 - fuse -> mount_osxfusefs [label="spawn, pass fd"];
11 - fuse -> wait [label="goroutine", note="blocks on cmd.Wait"];
12 - app <-- fuse [label="Mount returns"];
13 -
14 - mount_osxfusefs -> kernel [label="mount(2)"];
15 -
16 - app -> fuse [label="fs.Serve"];
17 - fuse => kernel [label="read /dev/osxfuseN fd", note="starts with InitRequest,\nalso seen before mount exits:\ntwo StatfsRequest calls"];
18 - fuse -> app [label="Init"];
19 - fuse <-- app [color=red];
20 - fuse -> kernel [label="write /dev/osxfuseN fd", color=red];
21 - fuse <-- kernel;
22 -
23 - mount_osxfusefs <-- kernel [label="mount(2) returns", color=red];
24 - wait <<-- mount_osxfusefs [diagonal, label="exit", color=red];
25 - app <<-- wait [diagonal, label="mount has failed,\nclose Conn.Ready", color=red];
26 -
27 - // actually triggers before above
28 - fuse <<-- kernel [diagonal, label="/dev/osxfuseN EOF"];
29 - app <-- fuse [label="fs.Serve returns"];
30 - ... conn.MountError != nil, so it was was never mounted ...
31 - ... call conn.Close to clean up ...
32 -}
Godeps/_workspace/src/bazil.org/fuse/doc/mount-osx-error-init.seq.png
Binary files a/Godeps/_workspace/src/bazil.org/fuse/doc/mount-osx-error-init.seq.png and /dev/null differ
Godeps/_workspace/src/bazil.org/fuse/doc/mount-osx.seq deleted
-45
@@ -1,45 +0,0 @@
1 -seqdiag {
2 - // seqdiag -T svg -o doc/mount-osx.svg doc/mount-osx.seq
3 - app;
4 - fuse [label="bazil.org/fuse"];
5 - wait [label="callMount\nhelper goroutine"];
6 - mount_osxfusefs;
7 - kernel;
8 - mounts;
9 -
10 - app -> fuse [label="Mount"];
11 - fuse -> kernel [label="open /dev/osxfuseN"];
12 - fuse -> mount_osxfusefs [label="spawn, pass fd"];
13 - fuse -> wait [label="goroutine", note="blocks on cmd.Wait"];
14 - app <-- fuse [label="Mount returns"];
15 -
16 - mount_osxfusefs -> kernel [label="mount(2)"];
17 -
18 - app -> fuse [label="fs.Serve"];
19 - fuse => kernel [label="read /dev/osxfuseN fd", note="starts with InitRequest,\nalso seen before mount exits:\ntwo StatfsRequest calls"];
20 - fuse => app [label="FS/Node/Handle methods"];
21 - fuse => kernel [label="write /dev/osxfuseN fd"];
22 - ... repeat ...
23 -
24 - kernel ->> mounts [label="mount is visible"];
25 - mount_osxfusefs <-- kernel [label="mount(2) returns"];
26 - wait <<-- mount_osxfusefs [diagonal, label="exit", leftnote="on OS X, successful exit\nhere means we finally know\nthe mount has happened\n(can't trust InitRequest,\nkernel might have timed out\nwaiting for InitResponse)"];
27 -
28 - app <<-- wait [diagonal, label="mount is ready,\nclose Conn.Ready", rightnote="InitRequest and StatfsRequest\nmay or may not be seen\nbefore Conn.Ready,\ndepending on platform"];
29 -
30 - ... shutting down ...
31 - app -> fuse [label="Unmount"];
32 - fuse -> kernel [label="umount(2)"];
33 - kernel <<-- mounts;
34 - fuse <-- kernel;
35 - app <-- fuse [label="Unmount returns"];
36 -
37 - // actually triggers before above
38 - fuse <<-- kernel [diagonal, label="/dev/osxfuseN EOF"];
39 - app <-- fuse [label="fs.Serve returns"];
40 -
41 - app -> fuse [label="conn.Close"];
42 - fuse -> kernel [label="close /dev/osxfuseN"];
43 - fuse <-- kernel;
44 - app <-- fuse;
45 -}
Godeps/_workspace/src/bazil.org/fuse/doc/mount-osx.seq.png
Binary files a/Godeps/_workspace/src/bazil.org/fuse/doc/mount-osx.seq.png and /dev/null differ
Godeps/_workspace/src/bazil.org/fuse/doc/mount-sequence.md deleted
-30
@@ -1,30 +0,0 @@
1 -# The mount sequence
2 -
3 -FUSE mounting is a little bit tricky. There's a userspace helper tool
4 -that performs the handshake with the kernel, and then steps out of the
5 -way. This helper behaves differently on different platforms, forcing a
6 -more complex API on us.
7 -
8 -## Successful runs
9 -
10 -On Linux, the mount is immediate and file system accesses wait until
11 -the requests are served.
12 -
13 -![Diagram of Linux FUSE mount sequence](mount-linux.seq.png)
14 -
15 -On OS X, the mount becomes visible only after `InitRequest` (and maybe
16 -more) have been served.
17 -
18 -![Diagram of OSXFUSE mount sequence](mount-osx.seq.png)
19 -
20 -
21 -## Errors
22 -
23 -Let's see what happens if `InitRequest` gets an error response. On
24 -Linux, the mountpoint is there but all operations will fail:
25 -
26 -![Diagram of Linux error handling](mount-linux-error-init.seq.png)
27 -
28 -On OS X, the mount never happened:
29 -
30 -![Diagram of OS X error handling](mount-osx-error-init.seq.png)
Godeps/_workspace/src/bazil.org/fuse/doc/writing-docs.md deleted
-16
@@ -1,16 +0,0 @@
1 -# Writing documentation
2 -
3 -## Sequence diagrams
4 -
5 -The sequence diagrams are generated with `seqdiag`:
6 -http://blockdiag.com/en/seqdiag/index.html
7 -
8 -An easy way to work on them is to automatically update the generated
9 -files with https://github.com/cespare/reflex :
10 -
11 - reflex -g 'doc/[^.]*.seq' -- seqdiag -T svg -o '{}.svg' '{}' &
12 -
13 - reflex -g 'doc/[^.]*.seq' -- seqdiag -T png -o '{}.png' '{}' &
14 -
15 -The markdown files refer to PNG images because of Github limitations,
16 -but the SVG is generally more pleasant to view.
Godeps/_workspace/src/bazil.org/fuse/error_darwin.go deleted
-17
@@ -1,17 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "syscall"
5 -)
6 -
7 -const (
8 - ENOATTR = Errno(syscall.ENOATTR)
9 -)
10 -
11 -const (
12 - errNoXattr = ENOATTR
13 -)
14 -
15 -func init() {
16 - errnoNames[errNoXattr] = "ENOATTR"
17 -}
Godeps/_workspace/src/bazil.org/fuse/error_freebsd.go deleted
-15
@@ -1,15 +0,0 @@
1 -package fuse
2 -
3 -import "syscall"
4 -
5 -const (
6 - ENOATTR = Errno(syscall.ENOATTR)
7 -)
8 -
9 -const (
10 - errNoXattr = ENOATTR
11 -)
12 -
13 -func init() {
14 - errnoNames[errNoXattr] = "ENOATTR"
15 -}
Godeps/_workspace/src/bazil.org/fuse/error_linux.go deleted
-17
@@ -1,17 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "syscall"
5 -)
6 -
7 -const (
8 - ENODATA = Errno(syscall.ENODATA)
9 -)
10 -
11 -const (
12 - errNoXattr = ENODATA
13 -)
14 -
15 -func init() {
16 - errnoNames[errNoXattr] = "ENODATA"
17 -}
Godeps/_workspace/src/bazil.org/fuse/error_std.go deleted
-31
@@ -1,31 +0,0 @@
1 -package fuse
2 -
3 -// There is very little commonality in extended attribute errors
4 -// across platforms.
5 -//
6 -// getxattr return value for "extended attribute does not exist" is
7 -// ENOATTR on OS X, and ENODATA on Linux and apparently at least
8 -// NetBSD. There may be a #define ENOATTR on Linux too, but the value
9 -// is ENODATA in the actual syscalls. FreeBSD and OpenBSD have no
10 -// ENODATA, only ENOATTR. ENOATTR is not in any of the standards,
11 -// ENODATA exists but is only used for STREAMs.
12 -//
13 -// Each platform will define it a errNoXattr constant, and this file
14 -// will enforce that it implements the right interfaces and hide the
15 -// implementation.
16 -//
17 -// https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/getxattr.2.html
18 -// http://mail-index.netbsd.org/tech-kern/2012/04/30/msg013090.html
19 -// http://mail-index.netbsd.org/tech-kern/2012/04/30/msg013097.html
20 -// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
21 -// http://www.freebsd.org/cgi/man.cgi?query=extattr_get_file&sektion=2
22 -// http://nixdoc.net/man-pages/openbsd/man2/extattr_get_file.2.html
23 -
24 -// ErrNoXattr is a platform-independent error value meaning the
25 -// extended attribute was not found. It can be used to respond to
26 -// GetxattrRequest and such.
27 -const ErrNoXattr = errNoXattr
28 -
29 -var _ error = ErrNoXattr
30 -var _ Errno = ErrNoXattr
31 -var _ ErrorNumber = ErrNoXattr
Godeps/_workspace/src/bazil.org/fuse/fs/bench/bench_test.go deleted
-273
@@ -1,273 +0,0 @@
1 -package bench_test
2 -
3 -import (
4 - "context"
5 - "io"
6 - "io/ioutil"
7 - "os"
8 - "path"
9 - "testing"
10 -
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
13 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
14 -)
15 -
16 -type benchConfig struct {
17 - directIO bool
18 -}
19 -
20 -type benchFS struct {
21 - conf *benchConfig
22 -}
23 -
24 -var _ = fs.FS(benchFS{})
25 -var _ = fs.FSIniter(benchFS{})
26 -
27 -func (benchFS) Init(ctx context.Context, req *fuse.InitRequest, resp *fuse.InitResponse) error {
28 - resp.MaxReadahead = 64 * 1024 * 1024
29 - resp.Flags |= fuse.InitAsyncRead
30 - return nil
31 -}
32 -
33 -func (f benchFS) Root() (fs.Node, error) {
34 - return benchDir{conf: f.conf}, nil
35 -}
36 -
37 -type benchDir struct {
38 - conf *benchConfig
39 -}
40 -
41 -var _ = fs.Node(benchDir{})
42 -var _ = fs.NodeStringLookuper(benchDir{})
43 -var _ = fs.Handle(benchDir{})
44 -var _ = fs.HandleReadDirAller(benchDir{})
45 -
46 -func (benchDir) Attr(ctx context.Context, a *fuse.Attr) error {
47 - a.Inode = 1
48 - a.Mode = os.ModeDir | 0555
49 - return nil
50 -}
51 -
52 -func (d benchDir) Lookup(ctx context.Context, name string) (fs.Node, error) {
53 - if name == "bench" {
54 - return benchFile{conf: d.conf}, nil
55 - }
56 - return nil, fuse.ENOENT
57 -}
58 -
59 -func (benchDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
60 - l := []fuse.Dirent{
61 - {Inode: 2, Name: "bench", Type: fuse.DT_File},
62 - }
63 - return l, nil
64 -}
65 -
66 -type benchFile struct {
67 - conf *benchConfig
68 -}
69 -
70 -var _ = fs.Node(benchFile{})
71 -var _ = fs.NodeOpener(benchFile{})
72 -var _ = fs.NodeFsyncer(benchFile{})
73 -var _ = fs.Handle(benchFile{})
74 -var _ = fs.HandleReader(benchFile{})
75 -var _ = fs.HandleWriter(benchFile{})
76 -
77 -func (benchFile) Attr(ctx context.Context, a *fuse.Attr) error {
78 - a.Inode = 2
79 - a.Mode = 0644
80 - a.Size = 9999999999999999
81 - return nil
82 -}
83 -
84 -func (f benchFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
85 - if f.conf.directIO {
86 - resp.Flags |= fuse.OpenDirectIO
87 - }
88 - // TODO configurable?
89 - resp.Flags |= fuse.OpenKeepCache
90 - return f, nil
91 -}
92 -
93 -func (benchFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
94 - resp.Data = resp.Data[:cap(resp.Data)]
95 - return nil
96 -}
97 -
98 -func (benchFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
99 - resp.Size = len(req.Data)
100 - return nil
101 -}
102 -
103 -func (benchFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
104 - return nil
105 -}
106 -
107 -func benchmark(b *testing.B, fn func(b *testing.B, mnt string), conf *benchConfig) {
108 - srv := &fs.Server{
109 - FS: benchFS{
110 - conf: conf,
111 - },
112 - }
113 - mnt, err := fstestutil.Mounted(srv)
114 - if err != nil {
115 - b.Fatal(err)
116 - }
117 - defer mnt.Close()
118 -
119 - fn(b, mnt.Dir)
120 -}
121 -
122 -type zero struct{}
123 -
124 -func (zero) Read(p []byte) (n int, err error) {
125 - return len(p), nil
126 -}
127 -
128 -var Zero io.Reader = zero{}
129 -
130 -func doWrites(size int64) func(b *testing.B, mnt string) {
131 - return func(b *testing.B, mnt string) {
132 - p := path.Join(mnt, "bench")
133 -
134 - f, err := os.Create(p)
135 - if err != nil {
136 - b.Fatalf("create: %v", err)
137 - }
138 - defer f.Close()
139 -
140 - b.ResetTimer()
141 - b.SetBytes(size)
142 -
143 - for i := 0; i < b.N; i++ {
144 - _, err = io.CopyN(f, Zero, size)
145 - if err != nil {
146 - b.Fatalf("write: %v", err)
147 - }
148 - }
149 - }
150 -}
151 -
152 -func BenchmarkWrite100(b *testing.B) {
153 - benchmark(b, doWrites(100), &benchConfig{})
154 -}
155 -
156 -func BenchmarkWrite10MB(b *testing.B) {
157 - benchmark(b, doWrites(10*1024*1024), &benchConfig{})
158 -}
159 -
160 -func BenchmarkWrite100MB(b *testing.B) {
161 - benchmark(b, doWrites(100*1024*1024), &benchConfig{})
162 -}
163 -
164 -func BenchmarkDirectWrite100(b *testing.B) {
165 - benchmark(b, doWrites(100), &benchConfig{
166 - directIO: true,
167 - })
168 -}
169 -
170 -func BenchmarkDirectWrite10MB(b *testing.B) {
171 - benchmark(b, doWrites(10*1024*1024), &benchConfig{
172 - directIO: true,
173 - })
174 -}
175 -
176 -func BenchmarkDirectWrite100MB(b *testing.B) {
177 - benchmark(b, doWrites(100*1024*1024), &benchConfig{
178 - directIO: true,
179 - })
180 -}
181 -
182 -func doWritesSync(size int64) func(b *testing.B, mnt string) {
183 - return func(b *testing.B, mnt string) {
184 - p := path.Join(mnt, "bench")
185 -
186 - f, err := os.Create(p)
187 - if err != nil {
188 - b.Fatalf("create: %v", err)
189 - }
190 - defer f.Close()
191 -
192 - b.ResetTimer()
193 - b.SetBytes(size)
194 -
195 - for i := 0; i < b.N; i++ {
196 - _, err = io.CopyN(f, Zero, size)
197 - if err != nil {
198 - b.Fatalf("write: %v", err)
199 - }
200 -
201 - if err := f.Sync(); err != nil {
202 - b.Fatalf("sync: %v", err)
203 - }
204 - }
205 - }
206 -}
207 -
208 -func BenchmarkWriteSync100(b *testing.B) {
209 - benchmark(b, doWritesSync(100), &benchConfig{})
210 -}
211 -
212 -func BenchmarkWriteSync10MB(b *testing.B) {
213 - benchmark(b, doWritesSync(10*1024*1024), &benchConfig{})
214 -}
215 -
216 -func BenchmarkWriteSync100MB(b *testing.B) {
217 - benchmark(b, doWritesSync(100*1024*1024), &benchConfig{})
218 -}
219 -
220 -func doReads(size int64) func(b *testing.B, mnt string) {
221 - return func(b *testing.B, mnt string) {
222 - p := path.Join(mnt, "bench")
223 -
224 - f, err := os.Open(p)
225 - if err != nil {
226 - b.Fatalf("close: %v", err)
227 - }
228 - defer f.Close()
229 -
230 - b.ResetTimer()
231 - b.SetBytes(size)
232 -
233 - for i := 0; i < b.N; i++ {
234 - n, err := io.CopyN(ioutil.Discard, f, size)
235 - if err != nil {
236 - b.Fatalf("read: %v", err)
237 - }
238 - if n != size {
239 - b.Errorf("unexpected size: %d != %d", n, size)
240 - }
241 - }
242 - }
243 -}
244 -
245 -func BenchmarkRead100(b *testing.B) {
246 - benchmark(b, doReads(100), &benchConfig{})
247 -}
248 -
249 -func BenchmarkRead10MB(b *testing.B) {
250 - benchmark(b, doReads(10*1024*1024), &benchConfig{})
251 -}
252 -
253 -func BenchmarkRead100MB(b *testing.B) {
254 - benchmark(b, doReads(100*1024*1024), &benchConfig{})
255 -}
256 -
257 -func BenchmarkDirectRead100(b *testing.B) {
258 - benchmark(b, doReads(100), &benchConfig{
259 - directIO: true,
260 - })
261 -}
262 -
263 -func BenchmarkDirectRead10MB(b *testing.B) {
264 - benchmark(b, doReads(10*1024*1024), &benchConfig{
265 - directIO: true,
266 - })
267 -}
268 -
269 -func BenchmarkDirectRead100MB(b *testing.B) {
270 - benchmark(b, doReads(100*1024*1024), &benchConfig{
271 - directIO: true,
272 - })
273 -}
Godeps/_workspace/src/bazil.org/fuse/fs/bench/doc.go deleted
-5
@@ -1,5 +0,0 @@
1 -// Package bench contains benchmarks.
2 -//
3 -// It is kept in a separate package to avoid conflicting with the
4 -// debug-heavy defaults for the actual tests.
5 -package bench
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/debug.go deleted
-65
@@ -1,65 +0,0 @@
1 -package fstestutil
2 -
3 -import (
4 - "flag"
5 - "log"
6 - "strconv"
7 -
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
9 -)
10 -
11 -type flagDebug bool
12 -
13 -var debug flagDebug
14 -
15 -var _ = flag.Value(&debug)
16 -
17 -func (f *flagDebug) IsBoolFlag() bool {
18 - return true
19 -}
20 -
21 -func nop(msg interface{}) {}
22 -
23 -func (f *flagDebug) Set(s string) error {
24 - v, err := strconv.ParseBool(s)
25 - if err != nil {
26 - return err
27 - }
28 - *f = flagDebug(v)
29 - if v {
30 - fuse.Debug = logMsg
31 - } else {
32 - fuse.Debug = nop
33 - }
34 - return nil
35 -}
36 -
37 -func (f *flagDebug) String() string {
38 - return strconv.FormatBool(bool(*f))
39 -}
40 -
41 -func logMsg(msg interface{}) {
42 - log.Printf("FUSE: %s\n", msg)
43 -}
44 -
45 -func init() {
46 - flag.Var(&debug, "fuse.debug", "log FUSE processing details")
47 -}
48 -
49 -// DebugByDefault changes the default of the `-fuse.debug` flag to
50 -// true.
51 -//
52 -// This package registers a command line flag `-fuse.debug` and when
53 -// run with that flag (and activated inside the tests), logs FUSE
54 -// debug messages.
55 -//
56 -// This is disabled by default, as most callers probably won't care
57 -// about FUSE details. Use DebugByDefault for tests where you'd
58 -// normally be passing `-fuse.debug` all the time anyway.
59 -//
60 -// Call from an init function.
61 -func DebugByDefault() {
62 - f := flag.Lookup("fuse.debug")
63 - f.DefValue = "true"
64 - f.Value.Set(f.DefValue)
65 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/doc.go deleted
-1
@@ -1 +0,0 @@
1 -package fstestutil
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/mounted.go deleted
-113
@@ -1,113 +0,0 @@
1 -package fstestutil
2 -
3 -import (
4 - "errors"
5 - "io/ioutil"
6 - "log"
7 - "os"
8 - "testing"
9 - "time"
10 -
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
13 -)
14 -
15 -// Mount contains information about the mount for the test to use.
16 -type Mount struct {
17 - // Dir is the temporary directory where the filesystem is mounted.
18 - Dir string
19 -
20 - Conn *fuse.Conn
21 -
22 - // Error will receive the return value of Serve.
23 - Error <-chan error
24 -
25 - done <-chan struct{}
26 - closed bool
27 -}
28 -
29 -// Close unmounts the filesystem and waits for fs.Serve to return. Any
30 -// returned error will be stored in Err. It is safe to call Close
31 -// multiple times.
32 -func (mnt *Mount) Close() {
33 - if mnt.closed {
34 - return
35 - }
36 - mnt.closed = true
37 - for tries := 0; tries < 1000; tries++ {
38 - err := fuse.Unmount(mnt.Dir)
39 - if err != nil {
40 - // TODO do more than log?
41 - log.Printf("unmount error: %v", err)
42 - time.Sleep(10 * time.Millisecond)
43 - continue
44 - }
45 - break
46 - }
47 - <-mnt.done
48 - mnt.Conn.Close()
49 - os.Remove(mnt.Dir)
50 -}
51 -
52 -// Mounted mounts the fuse.Server at a temporary directory.
53 -//
54 -// It also waits until the filesystem is known to be visible (OS X
55 -// workaround).
56 -//
57 -// After successful return, caller must clean up by calling Close.
58 -func Mounted(srv *fs.Server, options ...fuse.MountOption) (*Mount, error) {
59 - dir, err := ioutil.TempDir("", "fusetest")
60 - if err != nil {
61 - return nil, err
62 - }
63 - c, err := fuse.Mount(dir, options...)
64 - if err != nil {
65 - return nil, err
66 - }
67 -
68 - done := make(chan struct{})
69 - serveErr := make(chan error, 1)
70 - mnt := &Mount{
71 - Dir: dir,
72 - Conn: c,
73 - Error: serveErr,
74 - done: done,
75 - }
76 - go func() {
77 - defer close(done)
78 - serveErr <- srv.Serve(c)
79 - }()
80 -
81 - select {
82 - case <-mnt.Conn.Ready:
83 - if mnt.Conn.MountError != nil {
84 - return nil, err
85 - }
86 - return mnt, err
87 - case err = <-mnt.Error:
88 - // Serve quit early
89 - if err != nil {
90 - return nil, err
91 - }
92 - return nil, errors.New("Serve exited early")
93 - }
94 -}
95 -
96 -// MountedT mounts the filesystem at a temporary directory,
97 -// directing it's debug log to the testing logger.
98 -//
99 -// See Mounted for usage.
100 -//
101 -// The debug log is not enabled by default. Use `-fuse.debug` or call
102 -// DebugByDefault to enable.
103 -func MountedT(t testing.TB, filesys fs.FS, options ...fuse.MountOption) (*Mount, error) {
104 - srv := &fs.Server{
105 - FS: filesys,
106 - }
107 - if debug {
108 - srv.Debug = func(msg interface{}) {
109 - t.Logf("FUSE: %s", msg)
110 - }
111 - }
112 - return Mounted(srv, options...)
113 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/mountinfo.go deleted
-26
@@ -1,26 +0,0 @@
1 -package fstestutil
2 -
3 -// MountInfo describes a mounted file system.
4 -type MountInfo struct {
5 - FSName string
6 - Type string
7 -}
8 -
9 -// GetMountInfo finds information about the mount at mnt. It is
10 -// intended for use by tests only, and only fetches information
11 -// relevant to the current tests.
12 -func GetMountInfo(mnt string) (*MountInfo, error) {
13 - return getMountInfo(mnt)
14 -}
15 -
16 -// cstr converts a nil-terminated C string into a Go string
17 -func cstr(ca []int8) string {
18 - s := make([]byte, 0, len(ca))
19 - for _, c := range ca {
20 - if c == 0x00 {
21 - break
22 - }
23 - s = append(s, byte(c))
24 - }
25 - return string(s)
26 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/mountinfo_darwin.go deleted
-29
@@ -1,29 +0,0 @@
1 -package fstestutil
2 -
3 -import (
4 - "regexp"
5 - "syscall"
6 -)
7 -
8 -var re = regexp.MustCompile(`\\(.)`)
9 -
10 -// unescape removes backslash-escaping. The escaped characters are not
11 -// mapped in any way; that is, unescape(`\n` ) == `n`.
12 -func unescape(s string) string {
13 - return re.ReplaceAllString(s, `$1`)
14 -}
15 -
16 -func getMountInfo(mnt string) (*MountInfo, error) {
17 - var st syscall.Statfs_t
18 - err := syscall.Statfs(mnt, &st)
19 - if err != nil {
20 - return nil, err
21 - }
22 - i := &MountInfo{
23 - // osx getmntent(3) fails to un-escape the data, so we do it..
24 - // this might lead to double-unescaping in the future. fun.
25 - // TestMountOptionFSNameEvilBackslashDouble checks for that.
26 - FSName: unescape(cstr(st.Mntfromname[:])),
27 - }
28 - return i, nil
29 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/mountinfo_freebsd.go deleted
-7
@@ -1,7 +0,0 @@
1 -package fstestutil
2 -
3 -import "errors"
4 -
5 -func getMountInfo(mnt string) (*MountInfo, error) {
6 - return nil, errors.New("FreeBSD has no useful mount information")
7 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/mountinfo_linux.go deleted
-51
@@ -1,51 +0,0 @@
1 -package fstestutil
2 -
3 -import (
4 - "errors"
5 - "io/ioutil"
6 - "strings"
7 -)
8 -
9 -// Linux /proc/mounts shows current mounts.
10 -// Same format as /etc/fstab. Quoting getmntent(3):
11 -//
12 -// Since fields in the mtab and fstab files are separated by whitespace,
13 -// octal escapes are used to represent the four characters space (\040),
14 -// tab (\011), newline (\012) and backslash (\134) in those files when
15 -// they occur in one of the four strings in a mntent structure.
16 -//
17 -// http://linux.die.net/man/3/getmntent
18 -
19 -var fstabUnescape = strings.NewReplacer(
20 - `\040`, "\040",
21 - `\011`, "\011",
22 - `\012`, "\012",
23 - `\134`, "\134",
24 -)
25 -
26 -var errNotFound = errors.New("mount not found")
27 -
28 -func getMountInfo(mnt string) (*MountInfo, error) {
29 - data, err := ioutil.ReadFile("/proc/mounts")
30 - if err != nil {
31 - return nil, err
32 - }
33 - for _, line := range strings.Split(string(data), "\n") {
34 - fields := strings.Fields(line)
35 - if len(fields) < 3 {
36 - continue
37 - }
38 - // Fields are: fsname dir type opts freq passno
39 - fsname := fstabUnescape.Replace(fields[0])
40 - dir := fstabUnescape.Replace(fields[1])
41 - fstype := fstabUnescape.Replace(fields[2])
42 - if mnt == dir {
43 - info := &MountInfo{
44 - FSName: fsname,
45 - Type: fstype,
46 - }
47 - return info, nil
48 - }
49 - }
50 - return nil, errNotFound
51 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/buffer.go deleted
-28
@@ -1,28 +0,0 @@
1 -package record
2 -
3 -import (
4 - "bytes"
5 - "io"
6 - "sync"
7 -)
8 -
9 -// Buffer is like bytes.Buffer but safe to access from multiple
10 -// goroutines.
11 -type Buffer struct {
12 - mu sync.Mutex
13 - buf bytes.Buffer
14 -}
15 -
16 -var _ = io.Writer(&Buffer{})
17 -
18 -func (b *Buffer) Write(p []byte) (n int, err error) {
19 - b.mu.Lock()
20 - defer b.mu.Unlock()
21 - return b.buf.Write(p)
22 -}
23 -
24 -func (b *Buffer) Bytes() []byte {
25 - b.mu.Lock()
26 - defer b.mu.Unlock()
27 - return b.buf.Bytes()
28 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/record.go deleted
-381
@@ -1,381 +0,0 @@
1 -package record
2 -
3 -import (
4 - "context"
5 - "sync"
6 - "sync/atomic"
7 -
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
9 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
10 -)
11 -
12 -// Writes gathers data from FUSE Write calls.
13 -type Writes struct {
14 - buf Buffer
15 -}
16 -
17 -var _ = fs.HandleWriter(&Writes{})
18 -
19 -func (w *Writes) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
20 - n, err := w.buf.Write(req.Data)
21 - resp.Size = n
22 - if err != nil {
23 - return err
24 - }
25 - return nil
26 -}
27 -
28 -func (w *Writes) RecordedWriteData() []byte {
29 - return w.buf.Bytes()
30 -}
31 -
32 -// Counter records number of times a thing has occurred.
33 -type Counter struct {
34 - count uint32
35 -}
36 -
37 -func (r *Counter) Inc() {
38 - atomic.StoreUint32(&r.count, 1)
39 -}
40 -
41 -func (r *Counter) Count() uint32 {
42 - return atomic.LoadUint32(&r.count)
43 -}
44 -
45 -// MarkRecorder records whether a thing has occurred.
46 -type MarkRecorder struct {
47 - count Counter
48 -}
49 -
50 -func (r *MarkRecorder) Mark() {
51 - r.count.Inc()
52 -}
53 -
54 -func (r *MarkRecorder) Recorded() bool {
55 - return r.count.Count() > 0
56 -}
57 -
58 -// Flushes notes whether a FUSE Flush call has been seen.
59 -type Flushes struct {
60 - rec MarkRecorder
61 -}
62 -
63 -var _ = fs.HandleFlusher(&Flushes{})
64 -
65 -func (r *Flushes) Flush(ctx context.Context, req *fuse.FlushRequest) error {
66 - r.rec.Mark()
67 - return nil
68 -}
69 -
70 -func (r *Flushes) RecordedFlush() bool {
71 - return r.rec.Recorded()
72 -}
73 -
74 -type Recorder struct {
75 - mu sync.Mutex
76 - val interface{}
77 -}
78 -
79 -// Record that we've seen value. A nil value is indistinguishable from
80 -// no value recorded.
81 -func (r *Recorder) Record(value interface{}) {
82 - r.mu.Lock()
83 - r.val = value
84 - r.mu.Unlock()
85 -}
86 -
87 -func (r *Recorder) Recorded() interface{} {
88 - r.mu.Lock()
89 - val := r.val
90 - r.mu.Unlock()
91 - return val
92 -}
93 -
94 -type RequestRecorder struct {
95 - rec Recorder
96 -}
97 -
98 -// Record a fuse.Request, after zeroing header fields that are hard to
99 -// reproduce.
100 -//
101 -// Make sure to record a copy, not the original request.
102 -func (r *RequestRecorder) RecordRequest(req fuse.Request) {
103 - hdr := req.Hdr()
104 - *hdr = fuse.Header{}
105 - r.rec.Record(req)
106 -}
107 -
108 -func (r *RequestRecorder) Recorded() fuse.Request {
109 - val := r.rec.Recorded()
110 - if val == nil {
111 - return nil
112 - }
113 - return val.(fuse.Request)
114 -}
115 -
116 -// Setattrs records a Setattr request and its fields.
117 -type Setattrs struct {
118 - rec RequestRecorder
119 -}
120 -
121 -var _ = fs.NodeSetattrer(&Setattrs{})
122 -
123 -func (r *Setattrs) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
124 - tmp := *req
125 - r.rec.RecordRequest(&tmp)
126 - return nil
127 -}
128 -
129 -func (r *Setattrs) RecordedSetattr() fuse.SetattrRequest {
130 - val := r.rec.Recorded()
131 - if val == nil {
132 - return fuse.SetattrRequest{}
133 - }
134 - return *(val.(*fuse.SetattrRequest))
135 -}
136 -
137 -// Fsyncs records an Fsync request and its fields.
138 -type Fsyncs struct {
139 - rec RequestRecorder
140 -}
141 -
142 -var _ = fs.NodeFsyncer(&Fsyncs{})
143 -
144 -func (r *Fsyncs) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
145 - tmp := *req
146 - r.rec.RecordRequest(&tmp)
147 - return nil
148 -}
149 -
150 -func (r *Fsyncs) RecordedFsync() fuse.FsyncRequest {
151 - val := r.rec.Recorded()
152 - if val == nil {
153 - return fuse.FsyncRequest{}
154 - }
155 - return *(val.(*fuse.FsyncRequest))
156 -}
157 -
158 -// Mkdirs records a Mkdir request and its fields.
159 -type Mkdirs struct {
160 - rec RequestRecorder
161 -}
162 -
163 -var _ = fs.NodeMkdirer(&Mkdirs{})
164 -
165 -// Mkdir records the request and returns an error. Most callers should
166 -// wrap this call in a function that returns a more useful result.
167 -func (r *Mkdirs) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
168 - tmp := *req
169 - r.rec.RecordRequest(&tmp)
170 - return nil, fuse.EIO
171 -}
172 -
173 -// RecordedMkdir returns information about the Mkdir request.
174 -// If no request was seen, returns a zero value.
175 -func (r *Mkdirs) RecordedMkdir() fuse.MkdirRequest {
176 - val := r.rec.Recorded()
177 - if val == nil {
178 - return fuse.MkdirRequest{}
179 - }
180 - return *(val.(*fuse.MkdirRequest))
181 -}
182 -
183 -// Symlinks records a Symlink request and its fields.
184 -type Symlinks struct {
185 - rec RequestRecorder
186 -}
187 -
188 -var _ = fs.NodeSymlinker(&Symlinks{})
189 -
190 -// Symlink records the request and returns an error. Most callers should
191 -// wrap this call in a function that returns a more useful result.
192 -func (r *Symlinks) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) {
193 - tmp := *req
194 - r.rec.RecordRequest(&tmp)
195 - return nil, fuse.EIO
196 -}
197 -
198 -// RecordedSymlink returns information about the Symlink request.
199 -// If no request was seen, returns a zero value.
200 -func (r *Symlinks) RecordedSymlink() fuse.SymlinkRequest {
201 - val := r.rec.Recorded()
202 - if val == nil {
203 - return fuse.SymlinkRequest{}
204 - }
205 - return *(val.(*fuse.SymlinkRequest))
206 -}
207 -
208 -// Links records a Link request and its fields.
209 -type Links struct {
210 - rec RequestRecorder
211 -}
212 -
213 -var _ = fs.NodeLinker(&Links{})
214 -
215 -// Link records the request and returns an error. Most callers should
216 -// wrap this call in a function that returns a more useful result.
217 -func (r *Links) Link(ctx context.Context, req *fuse.LinkRequest, old fs.Node) (fs.Node, error) {
218 - tmp := *req
219 - r.rec.RecordRequest(&tmp)
220 - return nil, fuse.EIO
221 -}
222 -
223 -// RecordedLink returns information about the Link request.
224 -// If no request was seen, returns a zero value.
225 -func (r *Links) RecordedLink() fuse.LinkRequest {
226 - val := r.rec.Recorded()
227 - if val == nil {
228 - return fuse.LinkRequest{}
229 - }
230 - return *(val.(*fuse.LinkRequest))
231 -}
232 -
233 -// Mknods records a Mknod request and its fields.
234 -type Mknods struct {
235 - rec RequestRecorder
236 -}
237 -
238 -var _ = fs.NodeMknoder(&Mknods{})
239 -
240 -// Mknod records the request and returns an error. Most callers should
241 -// wrap this call in a function that returns a more useful result.
242 -func (r *Mknods) Mknod(ctx context.Context, req *fuse.MknodRequest) (fs.Node, error) {
243 - tmp := *req
244 - r.rec.RecordRequest(&tmp)
245 - return nil, fuse.EIO
246 -}
247 -
248 -// RecordedMknod returns information about the Mknod request.
249 -// If no request was seen, returns a zero value.
250 -func (r *Mknods) RecordedMknod() fuse.MknodRequest {
251 - val := r.rec.Recorded()
252 - if val == nil {
253 - return fuse.MknodRequest{}
254 - }
255 - return *(val.(*fuse.MknodRequest))
256 -}
257 -
258 -// Opens records a Open request and its fields.
259 -type Opens struct {
260 - rec RequestRecorder
261 -}
262 -
263 -var _ = fs.NodeOpener(&Opens{})
264 -
265 -// Open records the request and returns an error. Most callers should
266 -// wrap this call in a function that returns a more useful result.
267 -func (r *Opens) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
268 - tmp := *req
269 - r.rec.RecordRequest(&tmp)
270 - return nil, fuse.EIO
271 -}
272 -
273 -// RecordedOpen returns information about the Open request.
274 -// If no request was seen, returns a zero value.
275 -func (r *Opens) RecordedOpen() fuse.OpenRequest {
276 - val := r.rec.Recorded()
277 - if val == nil {
278 - return fuse.OpenRequest{}
279 - }
280 - return *(val.(*fuse.OpenRequest))
281 -}
282 -
283 -// Getxattrs records a Getxattr request and its fields.
284 -type Getxattrs struct {
285 - rec RequestRecorder
286 -}
287 -
288 -var _ = fs.NodeGetxattrer(&Getxattrs{})
289 -
290 -// Getxattr records the request and returns an error. Most callers should
291 -// wrap this call in a function that returns a more useful result.
292 -func (r *Getxattrs) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
293 - tmp := *req
294 - r.rec.RecordRequest(&tmp)
295 - return fuse.ErrNoXattr
296 -}
297 -
298 -// RecordedGetxattr returns information about the Getxattr request.
299 -// If no request was seen, returns a zero value.
300 -func (r *Getxattrs) RecordedGetxattr() fuse.GetxattrRequest {
301 - val := r.rec.Recorded()
302 - if val == nil {
303 - return fuse.GetxattrRequest{}
304 - }
305 - return *(val.(*fuse.GetxattrRequest))
306 -}
307 -
308 -// Listxattrs records a Listxattr request and its fields.
309 -type Listxattrs struct {
310 - rec RequestRecorder
311 -}
312 -
313 -var _ = fs.NodeListxattrer(&Listxattrs{})
314 -
315 -// Listxattr records the request and returns an error. Most callers should
316 -// wrap this call in a function that returns a more useful result.
317 -func (r *Listxattrs) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
318 - tmp := *req
319 - r.rec.RecordRequest(&tmp)
320 - return fuse.ErrNoXattr
321 -}
322 -
323 -// RecordedListxattr returns information about the Listxattr request.
324 -// If no request was seen, returns a zero value.
325 -func (r *Listxattrs) RecordedListxattr() fuse.ListxattrRequest {
326 - val := r.rec.Recorded()
327 - if val == nil {
328 - return fuse.ListxattrRequest{}
329 - }
330 - return *(val.(*fuse.ListxattrRequest))
331 -}
332 -
333 -// Setxattrs records a Setxattr request and its fields.
334 -type Setxattrs struct {
335 - rec RequestRecorder
336 -}
337 -
338 -var _ = fs.NodeSetxattrer(&Setxattrs{})
339 -
340 -// Setxattr records the request and returns an error. Most callers should
341 -// wrap this call in a function that returns a more useful result.
342 -func (r *Setxattrs) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error {
343 - tmp := *req
344 - r.rec.RecordRequest(&tmp)
345 - return nil
346 -}
347 -
348 -// RecordedSetxattr returns information about the Setxattr request.
349 -// If no request was seen, returns a zero value.
350 -func (r *Setxattrs) RecordedSetxattr() fuse.SetxattrRequest {
351 - val := r.rec.Recorded()
352 - if val == nil {
353 - return fuse.SetxattrRequest{}
354 - }
355 - return *(val.(*fuse.SetxattrRequest))
356 -}
357 -
358 -// Removexattrs records a Removexattr request and its fields.
359 -type Removexattrs struct {
360 - rec RequestRecorder
361 -}
362 -
363 -var _ = fs.NodeRemovexattrer(&Removexattrs{})
364 -
365 -// Removexattr records the request and returns an error. Most callers should
366 -// wrap this call in a function that returns a more useful result.
367 -func (r *Removexattrs) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error {
368 - tmp := *req
369 - r.rec.RecordRequest(&tmp)
370 - return nil
371 -}
372 -
373 -// RecordedRemovexattr returns information about the Removexattr request.
374 -// If no request was seen, returns a zero value.
375 -func (r *Removexattrs) RecordedRemovexattr() fuse.RemovexattrRequest {
376 - val := r.rec.Recorded()
377 - if val == nil {
378 - return fuse.RemovexattrRequest{}
379 - }
380 - return *(val.(*fuse.RemovexattrRequest))
381 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record/wait.go deleted
-55
@@ -1,55 +0,0 @@
1 -package record
2 -
3 -import (
4 - "context"
5 - "sync"
6 - "time"
7 -
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
9 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
10 -)
11 -
12 -type nothing struct{}
13 -
14 -// ReleaseWaiter notes whether a FUSE Release call has been seen.
15 -//
16 -// Releases are not guaranteed to happen synchronously with any client
17 -// call, so they must be waited for.
18 -type ReleaseWaiter struct {
19 - once sync.Once
20 - seen chan nothing
21 -}
22 -
23 -var _ = fs.HandleReleaser(&ReleaseWaiter{})
24 -
25 -func (r *ReleaseWaiter) init() {
26 - r.once.Do(func() {
27 - r.seen = make(chan nothing, 1)
28 - })
29 -}
30 -
31 -func (r *ReleaseWaiter) Release(ctx context.Context, req *fuse.ReleaseRequest) error {
32 - r.init()
33 - close(r.seen)
34 - return nil
35 -}
36 -
37 -// WaitForRelease waits for Release to be called.
38 -//
39 -// With zero duration, wait forever. Otherwise, timeout early
40 -// in a more controller way than `-test.timeout`.
41 -//
42 -// Returns whether a Release was seen. Always true if dur==0.
43 -func (r *ReleaseWaiter) WaitForRelease(dur time.Duration) bool {
44 - r.init()
45 - var timeout <-chan time.Time
46 - if dur > 0 {
47 - timeout = time.After(dur)
48 - }
49 - select {
50 - case <-r.seen:
51 - return true
52 - case <-timeout:
53 - return false
54 - }
55 -}
Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/testfs.go deleted
-55
@@ -1,55 +0,0 @@
1 -package fstestutil
2 -
3 -import (
4 - "context"
5 - "os"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
9 -)
10 -
11 -// SimpleFS is a trivial FS that just implements the Root method.
12 -type SimpleFS struct {
13 - Node fs.Node
14 -}
15 -
16 -var _ = fs.FS(SimpleFS{})
17 -
18 -func (f SimpleFS) Root() (fs.Node, error) {
19 - return f.Node, nil
20 -}
21 -
22 -// File can be embedded in a struct to make it look like a file.
23 -type File struct{}
24 -
25 -func (f File) Attr(ctx context.Context, a *fuse.Attr) error {
26 - a.Mode = 0666
27 - return nil
28 -}
29 -
30 -// Dir can be embedded in a struct to make it look like a directory.
31 -type Dir struct{}
32 -
33 -func (f Dir) Attr(ctx context.Context, a *fuse.Attr) error {
34 - a.Mode = os.ModeDir | 0777
35 - return nil
36 -}
37 -
38 -// ChildMap is a directory with child nodes looked up from a map.
39 -type ChildMap map[string]fs.Node
40 -
41 -var _ = fs.Node(ChildMap{})
42 -var _ = fs.NodeStringLookuper(ChildMap{})
43 -
44 -func (f ChildMap) Attr(ctx context.Context, a *fuse.Attr) error {
45 - a.Mode = os.ModeDir | 0777
46 - return nil
47 -}
48 -
49 -func (f ChildMap) Lookup(ctx context.Context, name string) (fs.Node, error) {
50 - child, ok := f[name]
51 - if !ok {
52 - return nil, fuse.ENOENT
53 - }
54 - return child, nil
55 -}
Godeps/_workspace/src/bazil.org/fuse/fs/helpers_test.go deleted
-67
@@ -1,67 +0,0 @@
1 -package fs_test
2 -
3 -import (
4 - "errors"
5 - "flag"
6 - "os"
7 - "os/exec"
8 - "path/filepath"
9 - "testing"
10 -)
11 -
12 -var childHelpers = map[string]func(){}
13 -
14 -type childProcess struct {
15 - name string
16 - fn func()
17 -}
18 -
19 -var _ flag.Value = (*childProcess)(nil)
20 -
21 -func (c *childProcess) String() string {
22 - return c.name
23 -}
24 -
25 -func (c *childProcess) Set(s string) error {
26 - fn, ok := childHelpers[s]
27 - if !ok {
28 - return errors.New("helper not found")
29 - }
30 - c.name = s
31 - c.fn = fn
32 - return nil
33 -}
34 -
35 -var childMode childProcess
36 -
37 -func init() {
38 - flag.Var(&childMode, "fuse.internal.child", "internal use only")
39 -}
40 -
41 -// childCmd prepares a test function to be run in a subprocess, with
42 -// childMode set to true. Caller must still call Run or Start.
43 -//
44 -// Re-using the test executable as the subprocess is useful because
45 -// now test executables can e.g. be cross-compiled, transferred
46 -// between hosts, and run in settings where the whole Go development
47 -// environment is not installed.
48 -func childCmd(childName string) (*exec.Cmd, error) {
49 - // caller may set cwd, so we can't rely on relative paths
50 - executable, err := filepath.Abs(os.Args[0])
51 - if err != nil {
52 - return nil, err
53 - }
54 - cmd := exec.Command(executable, "-fuse.internal.child="+childName)
55 - cmd.Stdout = os.Stdout
56 - cmd.Stderr = os.Stderr
57 - return cmd, nil
58 -}
59 -
60 -func TestMain(m *testing.M) {
61 - flag.Parse()
62 - if childMode.fn != nil {
63 - childMode.fn()
64 - os.Exit(0)
65 - }
66 - os.Exit(m.Run())
67 -}
Godeps/_workspace/src/bazil.org/fuse/fs/serve.go deleted
-1422
@@ -1,1422 +0,0 @@
1 -// FUSE service loop, for servers that wish to use it.
2 -
3 -package fs
4 -
5 -import (
6 - "encoding/binary"
7 - "fmt"
8 - "hash/fnv"
9 - "io"
10 - "log"
11 - "reflect"
12 - "runtime"
13 - "strings"
14 - "sync"
15 - "time"
16 -
17 - "context"
18 -)
19 -
20 -import (
21 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
22 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fuseutil"
23 -)
24 -
25 -const (
26 - attrValidTime = 1 * time.Minute
27 - entryValidTime = 1 * time.Minute
28 -)
29 -
30 -// TODO: FINISH DOCS
31 -
32 -// An FS is the interface required of a file system.
33 -//
34 -// Other FUSE requests can be handled by implementing methods from the
35 -// FS* interfaces, for example FSIniter.
36 -type FS interface {
37 - // Root is called to obtain the Node for the file system root.
38 - Root() (Node, error)
39 -}
40 -
41 -type FSIniter interface {
42 - // Init is called to initialize the FUSE connection.
43 - // It can inspect the request and adjust the response as desired.
44 - // Init must return promptly.
45 - Init(ctx context.Context, req *fuse.InitRequest, resp *fuse.InitResponse) error
46 -}
47 -
48 -type FSStatfser interface {
49 - // Statfs is called to obtain file system metadata.
50 - // It should write that data to resp.
51 - Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error
52 -}
53 -
54 -type FSDestroyer interface {
55 - // Destroy is called when the file system is shutting down.
56 - //
57 - // Linux only sends this request for block device backed (fuseblk)
58 - // filesystems, to allow them to flush writes to disk before the
59 - // unmount completes.
60 - Destroy()
61 -}
62 -
63 -type FSInodeGenerator interface {
64 - // GenerateInode is called to pick a dynamic inode number when it
65 - // would otherwise be 0.
66 - //
67 - // Not all filesystems bother tracking inodes, but FUSE requires
68 - // the inode to be set, and fewer duplicates in general makes UNIX
69 - // tools work better.
70 - //
71 - // Operations where the nodes may return 0 inodes include Getattr,
72 - // Setattr and ReadDir.
73 - //
74 - // If FS does not implement FSInodeGenerator, GenerateDynamicInode
75 - // is used.
76 - //
77 - // Implementing this is useful to e.g. constrain the range of
78 - // inode values used for dynamic inodes.
79 - GenerateInode(parentInode uint64, name string) uint64
80 -}
81 -
82 -// A Node is the interface required of a file or directory.
83 -// See the documentation for type FS for general information
84 -// pertaining to all methods.
85 -//
86 -// Other FUSE requests can be handled by implementing methods from the
87 -// Node* interfaces, for example NodeOpener.
88 -type Node interface {
89 - // Attr fills attr with the standard metadata for the node.
90 - Attr(ctx context.Context, attr *fuse.Attr) error
91 -}
92 -
93 -type NodeGetattrer interface {
94 - // Getattr obtains the standard metadata for the receiver.
95 - // It should store that metadata in resp.
96 - //
97 - // If this method is not implemented, the attributes will be
98 - // generated based on Attr(), with zero values filled in.
99 - Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error
100 -}
101 -
102 -type NodeSetattrer interface {
103 - // Setattr sets the standard metadata for the receiver.
104 - //
105 - // Note, this is also used to communicate changes in the size of
106 - // the file. Not implementing Setattr causes writes to be unable
107 - // to grow the file (except with OpenDirectIO, which bypasses that
108 - // mechanism).
109 - //
110 - // req.Valid is a bitmask of what fields are actually being set.
111 - // For example, the method should not change the mode of the file
112 - // unless req.Valid.Mode() is true.
113 - Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error
114 -}
115 -
116 -type NodeSymlinker interface {
117 - // Symlink creates a new symbolic link in the receiver, which must be a directory.
118 - //
119 - // TODO is the above true about directories?
120 - Symlink(ctx context.Context, req *fuse.SymlinkRequest) (Node, error)
121 -}
122 -
123 -// This optional request will be called only for symbolic link nodes.
124 -type NodeReadlinker interface {
125 - // Readlink reads a symbolic link.
126 - Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error)
127 -}
128 -
129 -type NodeLinker interface {
130 - // Link creates a new directory entry in the receiver based on an
131 - // existing Node. Receiver must be a directory.
132 - Link(ctx context.Context, req *fuse.LinkRequest, old Node) (Node, error)
133 -}
134 -
135 -type NodeRemover interface {
136 - // Remove removes the entry with the given name from
137 - // the receiver, which must be a directory. The entry to be removed
138 - // may correspond to a file (unlink) or to a directory (rmdir).
139 - Remove(ctx context.Context, req *fuse.RemoveRequest) error
140 -}
141 -
142 -type NodeAccesser interface {
143 - // Access checks whether the calling context has permission for
144 - // the given operations on the receiver. If so, Access should
145 - // return nil. If not, Access should return EPERM.
146 - //
147 - // Note that this call affects the result of the access(2) system
148 - // call but not the open(2) system call. If Access is not
149 - // implemented, the Node behaves as if it always returns nil
150 - // (permission granted), relying on checks in Open instead.
151 - Access(ctx context.Context, req *fuse.AccessRequest) error
152 -}
153 -
154 -type NodeStringLookuper interface {
155 - // Lookup looks up a specific entry in the receiver,
156 - // which must be a directory. Lookup should return a Node
157 - // corresponding to the entry. If the name does not exist in
158 - // the directory, Lookup should return nil, err.
159 - //
160 - // Lookup need not to handle the names "." and "..".
161 - Lookup(ctx context.Context, name string) (Node, error)
162 -}
163 -
164 -type NodeRequestLookuper interface {
165 - // Lookup looks up a specific entry in the receiver.
166 - // See NodeStringLookuper for more.
167 - Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (Node, error)
168 -}
169 -
170 -type NodeMkdirer interface {
171 - Mkdir(ctx context.Context, req *fuse.MkdirRequest) (Node, error)
172 -}
173 -
174 -type NodeOpener interface {
175 - // Open opens the receiver. After a successful open, a client
176 - // process has a file descriptor referring to this Handle.
177 - //
178 - // Open can also be also called on non-files. For example,
179 - // directories are Opened for ReadDir or fchdir(2).
180 - //
181 - // If this method is not implemented, the open will always
182 - // succeed, and the Node itself will be used as the Handle.
183 - //
184 - // XXX note about access. XXX OpenFlags.
185 - Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (Handle, error)
186 -}
187 -
188 -type NodeCreater interface {
189 - // Create creates a new directory entry in the receiver, which
190 - // must be a directory.
191 - Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (Node, Handle, error)
192 -}
193 -
194 -type NodeForgetter interface {
195 - // Forget about this node. This node will not receive further
196 - // method calls.
197 - //
198 - // Forget is not necessarily seen on unmount, as all nodes are
199 - // implicitly forgotten as part part of the unmount.
200 - Forget()
201 -}
202 -
203 -type NodeRenamer interface {
204 - Rename(ctx context.Context, req *fuse.RenameRequest, newDir Node) error
205 -}
206 -
207 -type NodeMknoder interface {
208 - Mknod(ctx context.Context, req *fuse.MknodRequest) (Node, error)
209 -}
210 -
211 -// TODO this should be on Handle not Node
212 -type NodeFsyncer interface {
213 - Fsync(ctx context.Context, req *fuse.FsyncRequest) error
214 -}
215 -
216 -type NodeGetxattrer interface {
217 - // Getxattr gets an extended attribute by the given name from the
218 - // node.
219 - //
220 - // If there is no xattr by that name, returns fuse.ErrNoXattr.
221 - Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error
222 -}
223 -
224 -type NodeListxattrer interface {
225 - // Listxattr lists the extended attributes recorded for the node.
226 - Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error
227 -}
228 -
229 -type NodeSetxattrer interface {
230 - // Setxattr sets an extended attribute with the given name and
231 - // value for the node.
232 - Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error
233 -}
234 -
235 -type NodeRemovexattrer interface {
236 - // Removexattr removes an extended attribute for the name.
237 - //
238 - // If there is no xattr by that name, returns fuse.ErrNoXattr.
239 - Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error
240 -}
241 -
242 -var startTime = time.Now()
243 -
244 -func nodeAttr(ctx context.Context, n Node, attr *fuse.Attr) error {
245 - attr.Valid = attrValidTime
246 - attr.Nlink = 1
247 - attr.Atime = startTime
248 - attr.Mtime = startTime
249 - attr.Ctime = startTime
250 - attr.Crtime = startTime
251 - if err := n.Attr(ctx, attr); err != nil {
252 - return err
253 - }
254 - return nil
255 -}
256 -
257 -// A Handle is the interface required of an opened file or directory.
258 -// See the documentation for type FS for general information
259 -// pertaining to all methods.
260 -//
261 -// Other FUSE requests can be handled by implementing methods from the
262 -// Handle* interfaces. The most common to implement are HandleReader,
263 -// HandleReadDirer, and HandleWriter.
264 -//
265 -// TODO implement methods: Getlk, Setlk, Setlkw
266 -type Handle interface {
267 -}
268 -
269 -type HandleFlusher interface {
270 - // Flush is called each time the file or directory is closed.
271 - // Because there can be multiple file descriptors referring to a
272 - // single opened file, Flush can be called multiple times.
273 - Flush(ctx context.Context, req *fuse.FlushRequest) error
274 -}
275 -
276 -type HandleReadAller interface {
277 - ReadAll(ctx context.Context) ([]byte, error)
278 -}
279 -
280 -type HandleReadDirAller interface {
281 - ReadDirAll(ctx context.Context) ([]fuse.Dirent, error)
282 -}
283 -
284 -type HandleReader interface {
285 - // Read requests to read data from the handle.
286 - //
287 - // There is a page cache in the kernel that normally submits only
288 - // page-aligned reads spanning one or more pages. However, you
289 - // should not rely on this. To see individual requests as
290 - // submitted by the file system clients, set OpenDirectIO.
291 - //
292 - // Note that reads beyond the size of the file as reported by Attr
293 - // are not even attempted (except in OpenDirectIO mode).
294 - Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error
295 -}
296 -
297 -type HandleWriter interface {
298 - // Write requests to write data into the handle.
299 - //
300 - // There is a writeback page cache in the kernel that normally submits
301 - // only page-aligned writes spanning one or more pages. However,
302 - // you should not rely on this. To see individual requests as
303 - // submitted by the file system clients, set OpenDirectIO.
304 - //
305 - // Note that file size changes are communicated through Setattr.
306 - // Writes beyond the size of the file as reported by Attr are not
307 - // even attempted (except in OpenDirectIO mode).
308 - Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error
309 -}
310 -
311 -type HandleReleaser interface {
312 - Release(ctx context.Context, req *fuse.ReleaseRequest) error
313 -}
314 -
315 -type Server struct {
316 - FS FS
317 -
318 - // Function to send debug log messages to. If nil, use fuse.Debug.
319 - // Note that changing this or fuse.Debug may not affect existing
320 - // calls to Serve.
321 - //
322 - // See fuse.Debug for the rules that log functions must follow.
323 - Debug func(msg interface{})
324 -
325 - // Used to ensure worker goroutines finish before Serve returns
326 - wg sync.WaitGroup
327 -}
328 -
329 -// Serve serves the FUSE connection by making calls to the methods
330 -// of fs and the Nodes and Handles it makes available. It returns only
331 -// when the connection has been closed or an unexpected error occurs.
332 -func (s *Server) Serve(c *fuse.Conn) error {
333 - defer s.wg.Wait() // Wait for worker goroutines to complete before return
334 -
335 - sc := serveConn{
336 - fs: s.FS,
337 - debug: s.Debug,
338 - req: map[fuse.RequestID]*serveRequest{},
339 - dynamicInode: GenerateDynamicInode,
340 - }
341 - if sc.debug == nil {
342 - sc.debug = fuse.Debug
343 - }
344 - if dyn, ok := sc.fs.(FSInodeGenerator); ok {
345 - sc.dynamicInode = dyn.GenerateInode
346 - }
347 -
348 - root, err := sc.fs.Root()
349 - if err != nil {
350 - return fmt.Errorf("cannot obtain root node: %v", err)
351 - }
352 - sc.node = append(sc.node, nil, &serveNode{inode: 1, node: root, refs: 1})
353 - sc.handle = append(sc.handle, nil)
354 -
355 - for {
356 - req, err := c.ReadRequest()
357 - if err != nil {
358 - if err == io.EOF {
359 - break
360 - }
361 - return err
362 - }
363 -
364 - s.wg.Add(1)
365 - go func() {
366 - defer s.wg.Done()
367 - sc.serve(req)
368 - }()
369 - }
370 - return nil
371 -}
372 -
373 -// Serve serves a FUSE connection with the default settings. See
374 -// Server.Serve.
375 -func Serve(c *fuse.Conn, fs FS) error {
376 - server := Server{
377 - FS: fs,
378 - }
379 - return server.Serve(c)
380 -}
381 -
382 -type nothing struct{}
383 -
384 -type serveConn struct {
385 - meta sync.Mutex
386 - fs FS
387 - req map[fuse.RequestID]*serveRequest
388 - node []*serveNode
389 - handle []*serveHandle
390 - freeNode []fuse.NodeID
391 - freeHandle []fuse.HandleID
392 - nodeGen uint64
393 - debug func(msg interface{})
394 - dynamicInode func(parent uint64, name string) uint64
395 -}
396 -
397 -type serveRequest struct {
398 - Request fuse.Request
399 - cancel func()
400 -}
401 -
402 -type serveNode struct {
403 - inode uint64
404 - node Node
405 - refs uint64
406 -}
407 -
408 -func (sn *serveNode) attr(ctx context.Context, attr *fuse.Attr) error {
409 - err := nodeAttr(ctx, sn.node, attr)
410 - if attr.Inode == 0 {
411 - attr.Inode = sn.inode
412 - }
413 - return err
414 -}
415 -
416 -type serveHandle struct {
417 - handle Handle
418 - readData []byte
419 - nodeID fuse.NodeID
420 -}
421 -
422 -// NodeRef can be embedded in a Node to recognize the same Node being
423 -// returned from multiple Lookup, Create etc calls.
424 -//
425 -// Without this, each Node will get a new NodeID, causing spurious
426 -// cache invalidations, extra lookups and aliasing anomalies. This may
427 -// not matter for a simple, read-only filesystem.
428 -type NodeRef struct {
429 - id fuse.NodeID
430 - generation uint64
431 -}
432 -
433 -// nodeRef is only ever accessed while holding serveConn.meta
434 -func (n *NodeRef) nodeRef() *NodeRef {
435 - return n
436 -}
437 -
438 -type nodeRef interface {
439 - nodeRef() *NodeRef
440 -}
441 -
442 -func (c *serveConn) saveNode(inode uint64, node Node) (id fuse.NodeID, gen uint64) {
443 - c.meta.Lock()
444 - defer c.meta.Unlock()
445 -
446 - var ref *NodeRef
447 - if nodeRef, ok := node.(nodeRef); ok {
448 - ref = nodeRef.nodeRef()
449 -
450 - if ref.id != 0 {
451 - // dropNode guarantees that NodeRef is zeroed at the same
452 - // time as the NodeID is removed from serveConn.node, as
453 - // guarded by c.meta; this means sn cannot be nil here
454 - sn := c.node[ref.id]
455 - sn.refs++
456 - return ref.id, ref.generation
457 - }
458 - }
459 -
460 - sn := &serveNode{inode: inode, node: node, refs: 1}
461 - if n := len(c.freeNode); n > 0 {
462 - id = c.freeNode[n-1]
463 - c.freeNode = c.freeNode[:n-1]
464 - c.node[id] = sn
465 - c.nodeGen++
466 - } else {
467 - id = fuse.NodeID(len(c.node))
468 - c.node = append(c.node, sn)
469 - }
470 - gen = c.nodeGen
471 - if ref != nil {
472 - ref.id = id
473 - ref.generation = gen
474 - }
475 - return
476 -}
477 -
478 -func (c *serveConn) saveHandle(handle Handle, nodeID fuse.NodeID) (id fuse.HandleID) {
479 - c.meta.Lock()
480 - shandle := &serveHandle{handle: handle, nodeID: nodeID}
481 - if n := len(c.freeHandle); n > 0 {
482 - id = c.freeHandle[n-1]
483 - c.freeHandle = c.freeHandle[:n-1]
484 - c.handle[id] = shandle
485 - } else {
486 - id = fuse.HandleID(len(c.handle))
487 - c.handle = append(c.handle, shandle)
488 - }
489 - c.meta.Unlock()
490 - return
491 -}
492 -
493 -type nodeRefcountDropBug struct {
494 - N uint64
495 - Refs uint64
496 - Node fuse.NodeID
497 -}
498 -
499 -func (n *nodeRefcountDropBug) String() string {
500 - return fmt.Sprintf("bug: trying to drop %d of %d references to %v", n.N, n.Refs, n.Node)
501 -}
502 -
503 -func (c *serveConn) dropNode(id fuse.NodeID, n uint64) (forget bool) {
504 - c.meta.Lock()
505 - defer c.meta.Unlock()
506 - snode := c.node[id]
507 -
508 - if snode == nil {
509 - // this should only happen if refcounts kernel<->us disagree
510 - // *and* two ForgetRequests for the same node race each other;
511 - // this indicates a bug somewhere
512 - c.debug(nodeRefcountDropBug{N: n, Node: id})
513 -
514 - // we may end up triggering Forget twice, but that's better
515 - // than not even once, and that's the best we can do
516 - return true
517 - }
518 -
519 - if n > snode.refs {
520 - c.debug(nodeRefcountDropBug{N: n, Refs: snode.refs, Node: id})
521 - n = snode.refs
522 - }
523 -
524 - snode.refs -= n
525 - if snode.refs == 0 {
526 - c.node[id] = nil
527 - if nodeRef, ok := snode.node.(nodeRef); ok {
528 - ref := nodeRef.nodeRef()
529 - *ref = NodeRef{}
530 - }
531 - c.freeNode = append(c.freeNode, id)
532 - return true
533 - }
534 - return false
535 -}
536 -
537 -func (c *serveConn) dropHandle(id fuse.HandleID) {
538 - c.meta.Lock()
539 - c.handle[id] = nil
540 - c.freeHandle = append(c.freeHandle, id)
541 - c.meta.Unlock()
542 -}
543 -
544 -type missingHandle struct {
545 - Handle fuse.HandleID
546 - MaxHandle fuse.HandleID
547 -}
548 -
549 -func (m missingHandle) String() string {
550 - return fmt.Sprint("missing handle", m.Handle, m.MaxHandle)
551 -}
552 -
553 -// Returns nil for invalid handles.
554 -func (c *serveConn) getHandle(id fuse.HandleID) (shandle *serveHandle) {
555 - c.meta.Lock()
556 - defer c.meta.Unlock()
557 - if id < fuse.HandleID(len(c.handle)) {
558 - shandle = c.handle[uint(id)]
559 - }
560 - if shandle == nil {
561 - c.debug(missingHandle{
562 - Handle: id,
563 - MaxHandle: fuse.HandleID(len(c.handle)),
564 - })
565 - }
566 - return
567 -}
568 -
569 -type request struct {
570 - Op string
571 - Request *fuse.Header
572 - In interface{} `json:",omitempty"`
573 -}
574 -
575 -func (r request) String() string {
576 - return fmt.Sprintf("<- %s", r.In)
577 -}
578 -
579 -type logResponseHeader struct {
580 - ID fuse.RequestID
581 -}
582 -
583 -func (m logResponseHeader) String() string {
584 - return fmt.Sprintf("ID=%#x", m.ID)
585 -}
586 -
587 -type response struct {
588 - Op string
589 - Request logResponseHeader
590 - Out interface{} `json:",omitempty"`
591 - // Errno contains the errno value as a string, for example "EPERM".
592 - Errno string `json:",omitempty"`
593 - // Error may contain a free form error message.
594 - Error string `json:",omitempty"`
595 -}
596 -
597 -func (r response) errstr() string {
598 - s := r.Errno
599 - if r.Error != "" {
600 - // prefix the errno constant to the long form message
601 - s = s + ": " + r.Error
602 - }
603 - return s
604 -}
605 -
606 -func (r response) String() string {
607 - switch {
608 - case r.Errno != "" && r.Out != nil:
609 - return fmt.Sprintf("-> %s error=%s %s", r.Request, r.errstr(), r.Out)
610 - case r.Errno != "":
611 - return fmt.Sprintf("-> %s error=%s", r.Request, r.errstr())
612 - case r.Out != nil:
613 - // make sure (seemingly) empty values are readable
614 - switch r.Out.(type) {
615 - case string:
616 - return fmt.Sprintf("-> %s %q", r.Request, r.Out)
617 - case []byte:
618 - return fmt.Sprintf("-> %s [% x]", r.Request, r.Out)
619 - default:
620 - return fmt.Sprintf("-> %s %s", r.Request, r.Out)
621 - }
622 - default:
623 - return fmt.Sprintf("-> %s", r.Request)
624 - }
625 -}
626 -
627 -type logMissingNode struct {
628 - MaxNode fuse.NodeID
629 -}
630 -
631 -func opName(req fuse.Request) string {
632 - t := reflect.Indirect(reflect.ValueOf(req)).Type()
633 - s := t.Name()
634 - s = strings.TrimSuffix(s, "Request")
635 - return s
636 -}
637 -
638 -type logLinkRequestOldNodeNotFound struct {
639 - Request *fuse.Header
640 - In *fuse.LinkRequest
641 -}
642 -
643 -func (m *logLinkRequestOldNodeNotFound) String() string {
644 - return fmt.Sprintf("In LinkRequest (request %#x), node %d not found", m.Request.Hdr().ID, m.In.OldNode)
645 -}
646 -
647 -type renameNewDirNodeNotFound struct {
648 - Request *fuse.Header
649 - In *fuse.RenameRequest
650 -}
651 -
652 -func (m *renameNewDirNodeNotFound) String() string {
653 - return fmt.Sprintf("In RenameRequest (request %#x), node %d not found", m.Request.Hdr().ID, m.In.NewDir)
654 -}
655 -
656 -type handlerPanickedError struct {
657 - Request interface{}
658 - Err interface{}
659 -}
660 -
661 -var _ error = handlerPanickedError{}
662 -
663 -func (h handlerPanickedError) Error() string {
664 - return fmt.Sprintf("handler panicked: %v", h.Err)
665 -}
666 -
667 -var _ fuse.ErrorNumber = handlerPanickedError{}
668 -
669 -func (h handlerPanickedError) Errno() fuse.Errno {
670 - if err, ok := h.Err.(fuse.ErrorNumber); ok {
671 - return err.Errno()
672 - }
673 - return fuse.DefaultErrno
674 -}
675 -
676 -func initLookupResponse(s *fuse.LookupResponse) {
677 - s.EntryValid = entryValidTime
678 -}
679 -
680 -func (c *serveConn) serve(r fuse.Request) {
681 - ctx, cancel := context.WithCancel(context.Background())
682 - defer cancel()
683 -
684 - req := &serveRequest{Request: r, cancel: cancel}
685 -
686 - c.debug(request{
687 - Op: opName(r),
688 - Request: r.Hdr(),
689 - In: r,
690 - })
691 - var node Node
692 - var snode *serveNode
693 - c.meta.Lock()
694 - hdr := r.Hdr()
695 - if id := hdr.Node; id != 0 {
696 - if id < fuse.NodeID(len(c.node)) {
697 - snode = c.node[uint(id)]
698 - }
699 - if snode == nil {
700 - c.meta.Unlock()
701 - c.debug(response{
702 - Op: opName(r),
703 - Request: logResponseHeader{ID: hdr.ID},
704 - Error: fuse.ESTALE.ErrnoName(),
705 - // this is the only place that sets both Error and
706 - // Out; not sure if i want to do that; might get rid
707 - // of len(c.node) things altogether
708 - Out: logMissingNode{
709 - MaxNode: fuse.NodeID(len(c.node)),
710 - },
711 - })
712 - r.RespondError(fuse.ESTALE)
713 - return
714 - }
715 - node = snode.node
716 - }
717 - if c.req[hdr.ID] != nil {
718 - // This happens with OSXFUSE. Assume it's okay and
719 - // that we'll never see an interrupt for this one.
720 - // Otherwise everything wedges. TODO: Report to OSXFUSE?
721 - //
722 - // TODO this might have been because of missing done() calls
723 - } else {
724 - c.req[hdr.ID] = req
725 - }
726 - c.meta.Unlock()
727 -
728 - // Call this before responding.
729 - // After responding is too late: we might get another request
730 - // with the same ID and be very confused.
731 - done := func(resp interface{}) {
732 - msg := response{
733 - Op: opName(r),
734 - Request: logResponseHeader{ID: hdr.ID},
735 - }
736 - if err, ok := resp.(error); ok {
737 - msg.Error = err.Error()
738 - if ferr, ok := err.(fuse.ErrorNumber); ok {
739 - errno := ferr.Errno()
740 - msg.Errno = errno.ErrnoName()
741 - if errno == err {
742 - // it's just a fuse.Errno with no extra detail;
743 - // skip the textual message for log readability
744 - msg.Error = ""
745 - }
746 - } else {
747 - msg.Errno = fuse.DefaultErrno.ErrnoName()
748 - }
749 - } else {
750 - msg.Out = resp
751 - }
752 - c.debug(msg)
753 -
754 - c.meta.Lock()
755 - delete(c.req, hdr.ID)
756 - c.meta.Unlock()
757 - }
758 -
759 - defer func() {
760 - if rec := recover(); rec != nil {
761 - const size = 1 << 16
762 - buf := make([]byte, size)
763 - n := runtime.Stack(buf, false)
764 - buf = buf[:n]
765 - log.Printf("fuse: panic in handler for %v: %v\n%s", r, rec, buf)
766 - err := handlerPanickedError{
767 - Request: r,
768 - Err: rec,
769 - }
770 - done(err)
771 - r.RespondError(err)
772 - }
773 - }()
774 -
775 - switch r := r.(type) {
776 - default:
777 - // NOTE: To FUSE, ENOSYS means "this server never implements this request."
778 - // It would be inappropriate to return ENOSYS for other operations in this
779 - // switch that might only be unavailable in some contexts, not all.
780 - done(fuse.ENOSYS)
781 - r.RespondError(fuse.ENOSYS)
782 -
783 - // FS operations.
784 - case *fuse.InitRequest:
785 - s := &fuse.InitResponse{
786 - MaxWrite: 128 * 1024,
787 - Flags: fuse.InitBigWrites,
788 - }
789 - if fs, ok := c.fs.(FSIniter); ok {
790 - if err := fs.Init(ctx, r, s); err != nil {
791 - done(err)
792 - r.RespondError(err)
793 - break
794 - }
795 - }
796 - done(s)
797 - r.Respond(s)
798 -
799 - case *fuse.StatfsRequest:
800 - s := &fuse.StatfsResponse{}
801 - if fs, ok := c.fs.(FSStatfser); ok {
802 - if err := fs.Statfs(ctx, r, s); err != nil {
803 - done(err)
804 - r.RespondError(err)
805 - break
806 - }
807 - }
808 - done(s)
809 - r.Respond(s)
810 -
811 - // Node operations.
812 - case *fuse.GetattrRequest:
813 - s := &fuse.GetattrResponse{}
814 - if n, ok := node.(NodeGetattrer); ok {
815 - if err := n.Getattr(ctx, r, s); err != nil {
816 - done(err)
817 - r.RespondError(err)
818 - break
819 - }
820 - } else {
821 - if err := snode.attr(ctx, &s.Attr); err != nil {
822 - done(err)
823 - r.RespondError(err)
824 - break
825 - }
826 - }
827 - done(s)
828 - r.Respond(s)
829 -
830 - case *fuse.SetattrRequest:
831 - s := &fuse.SetattrResponse{}
832 - if n, ok := node.(NodeSetattrer); ok {
833 - if err := n.Setattr(ctx, r, s); err != nil {
834 - done(err)
835 - r.RespondError(err)
836 - break
837 - }
838 - done(s)
839 - r.Respond(s)
840 - break
841 - }
842 -
843 - if err := snode.attr(ctx, &s.Attr); err != nil {
844 - done(err)
845 - r.RespondError(err)
846 - break
847 - }
848 - done(s)
849 - r.Respond(s)
850 -
851 - case *fuse.SymlinkRequest:
852 - s := &fuse.SymlinkResponse{}
853 - initLookupResponse(&s.LookupResponse)
854 - n, ok := node.(NodeSymlinker)
855 - if !ok {
856 - done(fuse.EIO) // XXX or EPERM like Mkdir?
857 - r.RespondError(fuse.EIO)
858 - break
859 - }
860 - n2, err := n.Symlink(ctx, r)
861 - if err != nil {
862 - done(err)
863 - r.RespondError(err)
864 - break
865 - }
866 - if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.NewName, n2); err != nil {
867 - done(err)
868 - r.RespondError(err)
869 - break
870 - }
871 - done(s)
872 - r.Respond(s)
873 -
874 - case *fuse.ReadlinkRequest:
875 - n, ok := node.(NodeReadlinker)
876 - if !ok {
877 - done(fuse.EIO) /// XXX or EPERM?
878 - r.RespondError(fuse.EIO)
879 - break
880 - }
881 - target, err := n.Readlink(ctx, r)
882 - if err != nil {
883 - done(err)
884 - r.RespondError(err)
885 - break
886 - }
887 - done(target)
888 - r.Respond(target)
889 -
890 - case *fuse.LinkRequest:
891 - n, ok := node.(NodeLinker)
892 - if !ok {
893 - done(fuse.EIO) /// XXX or EPERM?
894 - r.RespondError(fuse.EIO)
895 - break
896 - }
897 - c.meta.Lock()
898 - var oldNode *serveNode
899 - if int(r.OldNode) < len(c.node) {
900 - oldNode = c.node[r.OldNode]
901 - }
902 - c.meta.Unlock()
903 - if oldNode == nil {
904 - c.debug(logLinkRequestOldNodeNotFound{
905 - Request: r.Hdr(),
906 - In: r,
907 - })
908 - done(fuse.EIO)
909 - r.RespondError(fuse.EIO)
910 - break
911 - }
912 - n2, err := n.Link(ctx, r, oldNode.node)
913 - if err != nil {
914 - done(err)
915 - r.RespondError(err)
916 - break
917 - }
918 - s := &fuse.LookupResponse{}
919 - initLookupResponse(s)
920 - if err := c.saveLookup(ctx, s, snode, r.NewName, n2); err != nil {
921 - done(err)
922 - r.RespondError(err)
923 - break
924 - }
925 - done(s)
926 - r.Respond(s)
927 -
928 - case *fuse.RemoveRequest:
929 - n, ok := node.(NodeRemover)
930 - if !ok {
931 - done(fuse.EIO) /// XXX or EPERM?
932 - r.RespondError(fuse.EIO)
933 - break
934 - }
935 - err := n.Remove(ctx, r)
936 - if err != nil {
937 - done(err)
938 - r.RespondError(err)
939 - break
940 - }
941 - done(nil)
942 - r.Respond()
943 -
944 - case *fuse.AccessRequest:
945 - if n, ok := node.(NodeAccesser); ok {
946 - if err := n.Access(ctx, r); err != nil {
947 - done(err)
948 - r.RespondError(err)
949 - break
950 - }
951 - }
952 - done(nil)
953 - r.Respond()
954 -
955 - case *fuse.LookupRequest:
956 - var n2 Node
957 - var err error
958 - s := &fuse.LookupResponse{}
959 - initLookupResponse(s)
960 - if n, ok := node.(NodeStringLookuper); ok {
961 - n2, err = n.Lookup(ctx, r.Name)
962 - } else if n, ok := node.(NodeRequestLookuper); ok {
963 - n2, err = n.Lookup(ctx, r, s)
964 - } else {
965 - done(fuse.ENOENT)
966 - r.RespondError(fuse.ENOENT)
967 - break
968 - }
969 - if err != nil {
970 - done(err)
971 - r.RespondError(err)
972 - break
973 - }
974 - if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil {
975 - done(err)
976 - r.RespondError(err)
977 - break
978 - }
979 - done(s)
980 - r.Respond(s)
981 -
982 - case *fuse.MkdirRequest:
983 - s := &fuse.MkdirResponse{}
984 - initLookupResponse(&s.LookupResponse)
985 - n, ok := node.(NodeMkdirer)
986 - if !ok {
987 - done(fuse.EPERM)
988 - r.RespondError(fuse.EPERM)
989 - break
990 - }
991 - n2, err := n.Mkdir(ctx, r)
992 - if err != nil {
993 - done(err)
994 - r.RespondError(err)
995 - break
996 - }
997 - if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
998 - done(err)
999 - r.RespondError(err)
1000 - break
1001 - }
1002 - done(s)
1003 - r.Respond(s)
1004 -
1005 - case *fuse.OpenRequest:
1006 - s := &fuse.OpenResponse{}
1007 - var h2 Handle
1008 - if n, ok := node.(NodeOpener); ok {
1009 - hh, err := n.Open(ctx, r, s)
1010 - if err != nil {
1011 - done(err)
1012 - r.RespondError(err)
1013 - break
1014 - }
1015 - h2 = hh
1016 - } else {
1017 - h2 = node
1018 - }
1019 - s.Handle = c.saveHandle(h2, hdr.Node)
1020 - done(s)
1021 - r.Respond(s)
1022 -
1023 - case *fuse.CreateRequest:
1024 - n, ok := node.(NodeCreater)
1025 - if !ok {
1026 - // If we send back ENOSYS, FUSE will try mknod+open.
1027 - done(fuse.EPERM)
1028 - r.RespondError(fuse.EPERM)
1029 - break
1030 - }
1031 - s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}}
1032 - initLookupResponse(&s.LookupResponse)
1033 - n2, h2, err := n.Create(ctx, r, s)
1034 - if err != nil {
1035 - done(err)
1036 - r.RespondError(err)
1037 - break
1038 - }
1039 - if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
1040 - done(err)
1041 - r.RespondError(err)
1042 - break
1043 - }
1044 - s.Handle = c.saveHandle(h2, hdr.Node)
1045 - done(s)
1046 - r.Respond(s)
1047 -
1048 - case *fuse.GetxattrRequest:
1049 - n, ok := node.(NodeGetxattrer)
1050 - if !ok {
1051 - done(fuse.ENOTSUP)
1052 - r.RespondError(fuse.ENOTSUP)
1053 - break
1054 - }
1055 - s := &fuse.GetxattrResponse{}
1056 - err := n.Getxattr(ctx, r, s)
1057 - if err != nil {
1058 - done(err)
1059 - r.RespondError(err)
1060 - break
1061 - }
1062 - if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
1063 - done(fuse.ERANGE)
1064 - r.RespondError(fuse.ERANGE)
1065 - break
1066 - }
1067 - done(s)
1068 - r.Respond(s)
1069 -
1070 - case *fuse.ListxattrRequest:
1071 - n, ok := node.(NodeListxattrer)
1072 - if !ok {
1073 - done(fuse.ENOTSUP)
1074 - r.RespondError(fuse.ENOTSUP)
1075 - break
1076 - }
1077 - s := &fuse.ListxattrResponse{}
1078 - err := n.Listxattr(ctx, r, s)
1079 - if err != nil {
1080 - done(err)
1081 - r.RespondError(err)
1082 - break
1083 - }
1084 - if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
1085 - done(fuse.ERANGE)
1086 - r.RespondError(fuse.ERANGE)
1087 - break
1088 - }
1089 - done(s)
1090 - r.Respond(s)
1091 -
1092 - case *fuse.SetxattrRequest:
1093 - n, ok := node.(NodeSetxattrer)
1094 - if !ok {
1095 - done(fuse.ENOTSUP)
1096 - r.RespondError(fuse.ENOTSUP)
1097 - break
1098 - }
1099 - err := n.Setxattr(ctx, r)
1100 - if err != nil {
1101 - done(err)
1102 - r.RespondError(err)
1103 - break
1104 - }
1105 - done(nil)
1106 - r.Respond()
1107 -
1108 - case *fuse.RemovexattrRequest:
1109 - n, ok := node.(NodeRemovexattrer)
1110 - if !ok {
1111 - done(fuse.ENOTSUP)
1112 - r.RespondError(fuse.ENOTSUP)
1113 - break
1114 - }
1115 - err := n.Removexattr(ctx, r)
1116 - if err != nil {
1117 - done(err)
1118 - r.RespondError(err)
1119 - break
1120 - }
1121 - done(nil)
1122 - r.Respond()
1123 -
1124 - case *fuse.ForgetRequest:
1125 - forget := c.dropNode(hdr.Node, r.N)
1126 - if forget {
1127 - n, ok := node.(NodeForgetter)
1128 - if ok {
1129 - n.Forget()
1130 - }
1131 - }
1132 - done(nil)
1133 - r.Respond()
1134 -
1135 - // Handle operations.
1136 - case *fuse.ReadRequest:
1137 - shandle := c.getHandle(r.Handle)
1138 - if shandle == nil {
1139 - done(fuse.ESTALE)
1140 - r.RespondError(fuse.ESTALE)
1141 - return
1142 - }
1143 - handle := shandle.handle
1144 -
1145 - s := &fuse.ReadResponse{Data: make([]byte, 0, r.Size)}
1146 - if r.Dir {
1147 - if h, ok := handle.(HandleReadDirAller); ok {
1148 - if shandle.readData == nil {
1149 - dirs, err := h.ReadDirAll(ctx)
1150 - if err != nil {
1151 - done(err)
1152 - r.RespondError(err)
1153 - break
1154 - }
1155 - var data []byte
1156 - for _, dir := range dirs {
1157 - if dir.Inode == 0 {
1158 - dir.Inode = c.dynamicInode(snode.inode, dir.Name)
1159 - }
1160 - data = fuse.AppendDirent(data, dir)
1161 - }
1162 - shandle.readData = data
1163 - }
1164 - fuseutil.HandleRead(r, s, shandle.readData)
1165 - done(s)
1166 - r.Respond(s)
1167 - break
1168 - }
1169 - } else {
1170 - if h, ok := handle.(HandleReadAller); ok {
1171 - if shandle.readData == nil {
1172 - data, err := h.ReadAll(ctx)
1173 - if err != nil {
1174 - done(err)
1175 - r.RespondError(err)
1176 - break
1177 - }
1178 - if data == nil {
1179 - data = []byte{}
1180 - }
1181 - shandle.readData = data
1182 - }
1183 - fuseutil.HandleRead(r, s, shandle.readData)
1184 - done(s)
1185 - r.Respond(s)
1186 - break
1187 - }
1188 - h, ok := handle.(HandleReader)
1189 - if !ok {
1190 - fmt.Printf("NO READ FOR %T\n", handle)
1191 - done(fuse.EIO)
1192 - r.RespondError(fuse.EIO)
1193 - break
1194 - }
1195 - if err := h.Read(ctx, r, s); err != nil {
1196 - done(err)
1197 - r.RespondError(err)
1198 - break
1199 - }
1200 - }
1201 - done(s)
1202 - r.Respond(s)
1203 -
1204 - case *fuse.WriteRequest:
1205 - shandle := c.getHandle(r.Handle)
1206 - if shandle == nil {
1207 - done(fuse.ESTALE)
1208 - r.RespondError(fuse.ESTALE)
1209 - return
1210 - }
1211 -
1212 - s := &fuse.WriteResponse{}
1213 - if h, ok := shandle.handle.(HandleWriter); ok {
1214 - if err := h.Write(ctx, r, s); err != nil {
1215 - done(err)
1216 - r.RespondError(err)
1217 - break
1218 - }
1219 - done(s)
1220 - r.Respond(s)
1221 - break
1222 - }
1223 - done(fuse.EIO)
1224 - r.RespondError(fuse.EIO)
1225 -
1226 - case *fuse.FlushRequest:
1227 - shandle := c.getHandle(r.Handle)
1228 - if shandle == nil {
1229 - done(fuse.ESTALE)
1230 - r.RespondError(fuse.ESTALE)
1231 - return
1232 - }
1233 - handle := shandle.handle
1234 -
1235 - if h, ok := handle.(HandleFlusher); ok {
1236 - if err := h.Flush(ctx, r); err != nil {
1237 - done(err)
1238 - r.RespondError(err)
1239 - break
1240 - }
1241 - }
1242 - done(nil)
1243 - r.Respond()
1244 -
1245 - case *fuse.ReleaseRequest:
1246 - shandle := c.getHandle(r.Handle)
1247 - if shandle == nil {
1248 - done(fuse.ESTALE)
1249 - r.RespondError(fuse.ESTALE)
1250 - return
1251 - }
1252 - handle := shandle.handle
1253 -
1254 - // No matter what, release the handle.
1255 - c.dropHandle(r.Handle)
1256 -
1257 - if h, ok := handle.(HandleReleaser); ok {
1258 - if err := h.Release(ctx, r); err != nil {
1259 - done(err)
1260 - r.RespondError(err)
1261 - break
1262 - }
1263 - }
1264 - done(nil)
1265 - r.Respond()
1266 -
1267 - case *fuse.DestroyRequest:
1268 - if fs, ok := c.fs.(FSDestroyer); ok {
1269 - fs.Destroy()
1270 - }
1271 - done(nil)
1272 - r.Respond()
1273 -
1274 - case *fuse.RenameRequest:
1275 - c.meta.Lock()
1276 - var newDirNode *serveNode
1277 - if int(r.NewDir) < len(c.node) {
1278 - newDirNode = c.node[r.NewDir]
1279 - }
1280 - c.meta.Unlock()
1281 - if newDirNode == nil {
1282 - c.debug(renameNewDirNodeNotFound{
1283 - Request: r.Hdr(),
1284 - In: r,
1285 - })
1286 - done(fuse.EIO)
1287 - r.RespondError(fuse.EIO)
1288 - break
1289 - }
1290 - n, ok := node.(NodeRenamer)
1291 - if !ok {
1292 - done(fuse.EIO) // XXX or EPERM like Mkdir?
1293 - r.RespondError(fuse.EIO)
1294 - break
1295 - }
1296 - err := n.Rename(ctx, r, newDirNode.node)
1297 - if err != nil {
1298 - done(err)
1299 - r.RespondError(err)
1300 - break
1301 - }
1302 - done(nil)
1303 - r.Respond()
1304 -
1305 - case *fuse.MknodRequest:
1306 - n, ok := node.(NodeMknoder)
1307 - if !ok {
1308 - done(fuse.EIO)
1309 - r.RespondError(fuse.EIO)
1310 - break
1311 - }
1312 - n2, err := n.Mknod(ctx, r)
1313 - if err != nil {
1314 - done(err)
1315 - r.RespondError(err)
1316 - break
1317 - }
1318 - s := &fuse.LookupResponse{}
1319 - initLookupResponse(s)
1320 - if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil {
1321 - done(err)
1322 - r.RespondError(err)
1323 - break
1324 - }
1325 - done(s)
1326 - r.Respond(s)
1327 -
1328 - case *fuse.FsyncRequest:
1329 - n, ok := node.(NodeFsyncer)
1330 - if !ok {
1331 - done(fuse.EIO)
1332 - r.RespondError(fuse.EIO)
1333 - break
1334 - }
1335 - err := n.Fsync(ctx, r)
1336 - if err != nil {
1337 - done(err)
1338 - r.RespondError(err)
1339 - break
1340 - }
1341 - done(nil)
1342 - r.Respond()
1343 -
1344 - case *fuse.InterruptRequest:
1345 - c.meta.Lock()
1346 - ireq := c.req[r.IntrID]
1347 - if ireq != nil && ireq.cancel != nil {
1348 - ireq.cancel()
1349 - ireq.cancel = nil
1350 - }
1351 - c.meta.Unlock()
1352 - done(nil)
1353 - r.Respond()
1354 -
1355 - /* case *FsyncdirRequest:
1356 - done(ENOSYS)
1357 - r.RespondError(ENOSYS)
1358 -
1359 - case *GetlkRequest, *SetlkRequest, *SetlkwRequest:
1360 - done(ENOSYS)
1361 - r.RespondError(ENOSYS)
1362 -
1363 - case *BmapRequest:
1364 - done(ENOSYS)
1365 - r.RespondError(ENOSYS)
1366 -
1367 - case *SetvolnameRequest, *GetxtimesRequest, *ExchangeRequest:
1368 - done(ENOSYS)
1369 - r.RespondError(ENOSYS)
1370 - */
1371 - }
1372 -}
1373 -
1374 -func (c *serveConn) saveLookup(ctx context.Context, s *fuse.LookupResponse, snode *serveNode, elem string, n2 Node) error {
1375 - if err := nodeAttr(ctx, n2, &s.Attr); err != nil {
1376 - return err
1377 - }
1378 - if s.Attr.Inode == 0 {
1379 - s.Attr.Inode = c.dynamicInode(snode.inode, elem)
1380 - }
1381 -
1382 - s.Node, s.Generation = c.saveNode(s.Attr.Inode, n2)
1383 - return nil
1384 -}
1385 -
1386 -// DataHandle returns a read-only Handle that satisfies reads
1387 -// using the given data.
1388 -func DataHandle(data []byte) Handle {
1389 - return &dataHandle{data}
1390 -}
1391 -
1392 -type dataHandle struct {
1393 - data []byte
1394 -}
1395 -
1396 -func (d *dataHandle) ReadAll(ctx context.Context) ([]byte, error) {
1397 - return d.data, nil
1398 -}
1399 -
1400 -// GenerateDynamicInode returns a dynamic inode.
1401 -//
1402 -// The parent inode and current entry name are used as the criteria
1403 -// for choosing a pseudorandom inode. This makes it likely the same
1404 -// entry will get the same inode on multiple runs.
1405 -func GenerateDynamicInode(parent uint64, name string) uint64 {
1406 - h := fnv.New64a()
1407 - var buf [8]byte
1408 - binary.LittleEndian.PutUint64(buf[:], parent)
1409 - _, _ = h.Write(buf[:])
1410 - _, _ = h.Write([]byte(name))
1411 - var inode uint64
1412 - for {
1413 - inode = h.Sum64()
1414 - if inode != 0 {
1415 - break
1416 - }
1417 - // there's a tiny probability that result is zero; change the
1418 - // input a little and try again
1419 - _, _ = h.Write([]byte{'x'})
1420 - }
1421 - return inode
1422 -}
Godeps/_workspace/src/bazil.org/fuse/fs/serve_test.go deleted
-1919
@@ -1,1919 +0,0 @@
1 -package fs_test
2 -
3 -import (
4 - "bytes"
5 - "context"
6 - "errors"
7 - "io"
8 - "io/ioutil"
9 - "log"
10 - "os"
11 - "os/exec"
12 - "runtime"
13 - "strings"
14 - "sync"
15 - "syscall"
16 - "testing"
17 - "time"
18 -
19 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
20 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
21 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
22 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil/record"
23 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fuseutil"
24 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/syscallx"
25 -)
26 -
27 -// TO TEST:
28 -// Lookup(*LookupRequest, *LookupResponse)
29 -// Getattr(*GetattrRequest, *GetattrResponse)
30 -// Attr with explicit inode
31 -// Setattr(*SetattrRequest, *SetattrResponse)
32 -// Access(*AccessRequest)
33 -// Open(*OpenRequest, *OpenResponse)
34 -// Write(*WriteRequest, *WriteResponse)
35 -// Flush(*FlushRequest, *FlushResponse)
36 -
37 -func init() {
38 - fstestutil.DebugByDefault()
39 -}
40 -
41 -// symlink can be embedded in a struct to make it look like a symlink.
42 -type symlink struct {
43 - target string
44 -}
45 -
46 -func (f symlink) Attr(ctx context.Context, a *fuse.Attr) error {
47 - a.Mode = os.ModeSymlink | 0666
48 - return nil
49 -}
50 -
51 -// fifo can be embedded in a struct to make it look like a named pipe.
52 -type fifo struct{}
53 -
54 -func (f fifo) Attr(ctx context.Context, a *fuse.Attr) error {
55 - a.Mode = os.ModeNamedPipe | 0666
56 - return nil
57 -}
58 -
59 -type badRootFS struct{}
60 -
61 -func (badRootFS) Root() (fs.Node, error) {
62 - // pick a really distinct error, to identify it later
63 - return nil, fuse.Errno(syscall.ENAMETOOLONG)
64 -}
65 -
66 -func TestRootErr(t *testing.T) {
67 - t.Parallel()
68 - mnt, err := fstestutil.MountedT(t, badRootFS{})
69 - if err == nil {
70 - // path for synchronous mounts (linux): started out fine, now
71 - // wait for Serve to cycle through
72 - err = <-mnt.Error
73 - // without this, unmount will keep failing with EBUSY; nudge
74 - // kernel into realizing InitResponse will not happen
75 - mnt.Conn.Close()
76 - mnt.Close()
77 - }
78 -
79 - if err == nil {
80 - t.Fatal("expected an error")
81 - }
82 - // TODO this should not be a textual comparison, Serve hides
83 - // details
84 - if err.Error() != "cannot obtain root node: file name too long" {
85 - t.Errorf("Unexpected error: %v", err)
86 - }
87 -}
88 -
89 -type testPanic struct{}
90 -
91 -type panicSentinel struct{}
92 -
93 -var _ error = panicSentinel{}
94 -
95 -func (panicSentinel) Error() string { return "just a test" }
96 -
97 -var _ fuse.ErrorNumber = panicSentinel{}
98 -
99 -func (panicSentinel) Errno() fuse.Errno {
100 - return fuse.Errno(syscall.ENAMETOOLONG)
101 -}
102 -
103 -func (f testPanic) Root() (fs.Node, error) {
104 - return f, nil
105 -}
106 -
107 -func (f testPanic) Attr(ctx context.Context, a *fuse.Attr) error {
108 - a.Inode = 1
109 - a.Mode = os.ModeDir | 0777
110 - return nil
111 -}
112 -
113 -func (f testPanic) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
114 - panic(panicSentinel{})
115 -}
116 -
117 -func TestPanic(t *testing.T) {
118 - t.Parallel()
119 - mnt, err := fstestutil.MountedT(t, testPanic{})
120 - if err != nil {
121 - t.Fatal(err)
122 - }
123 - defer mnt.Close()
124 -
125 - var st syscall.Statfs_t
126 - err = syscall.Statfs(mnt.Dir, &st)
127 - if g, e := err, syscall.ENAMETOOLONG; g != e {
128 - t.Fatalf("wrong error from panicking handler: %v != %v", g, e)
129 - }
130 -}
131 -
132 -type testStatFS struct{}
133 -
134 -func (f testStatFS) Root() (fs.Node, error) {
135 - return f, nil
136 -}
137 -
138 -func (f testStatFS) Attr(ctx context.Context, a *fuse.Attr) error {
139 - a.Inode = 1
140 - a.Mode = os.ModeDir | 0777
141 - return nil
142 -}
143 -
144 -func (f testStatFS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
145 - resp.Blocks = 42
146 - resp.Files = 13
147 - return nil
148 -}
149 -
150 -func TestStatfs(t *testing.T) {
151 - t.Parallel()
152 - mnt, err := fstestutil.MountedT(t, testStatFS{})
153 - if err != nil {
154 - t.Fatal(err)
155 - }
156 - defer mnt.Close()
157 -
158 - {
159 - var st syscall.Statfs_t
160 - err = syscall.Statfs(mnt.Dir, &st)
161 - if err != nil {
162 - t.Errorf("Statfs failed: %v", err)
163 - }
164 - t.Logf("Statfs got: %#v", st)
165 - if g, e := st.Blocks, uint64(42); g != e {
166 - t.Errorf("got Blocks = %d; want %d", g, e)
167 - }
168 - if g, e := st.Files, uint64(13); g != e {
169 - t.Errorf("got Files = %d; want %d", g, e)
170 - }
171 - }
172 -
173 - {
174 - var st syscall.Statfs_t
175 - f, err := os.Open(mnt.Dir)
176 - if err != nil {
177 - t.Errorf("Open for fstatfs failed: %v", err)
178 - }
179 - defer f.Close()
180 - err = syscall.Fstatfs(int(f.Fd()), &st)
181 - if err != nil {
182 - t.Errorf("Fstatfs failed: %v", err)
183 - }
184 - t.Logf("Fstatfs got: %#v", st)
185 - if g, e := st.Blocks, uint64(42); g != e {
186 - t.Errorf("got Blocks = %d; want %d", g, e)
187 - }
188 - if g, e := st.Files, uint64(13); g != e {
189 - t.Errorf("got Files = %d; want %d", g, e)
190 - }
191 - }
192 -
193 -}
194 -
195 -// Test Stat of root.
196 -
197 -type root struct{}
198 -
199 -func (f root) Root() (fs.Node, error) {
200 - return f, nil
201 -}
202 -
203 -func (root) Attr(ctx context.Context, a *fuse.Attr) error {
204 - a.Inode = 1
205 - a.Mode = os.ModeDir | 0555
206 - return nil
207 -}
208 -
209 -func TestStatRoot(t *testing.T) {
210 - t.Parallel()
211 - mnt, err := fstestutil.MountedT(t, root{})
212 - if err != nil {
213 - t.Fatal(err)
214 - }
215 - defer mnt.Close()
216 -
217 - fi, err := os.Stat(mnt.Dir)
218 - if err != nil {
219 - t.Fatalf("root getattr failed with %v", err)
220 - }
221 - mode := fi.Mode()
222 - if (mode & os.ModeType) != os.ModeDir {
223 - t.Errorf("root is not a directory: %#v", fi)
224 - }
225 - if mode.Perm() != 0555 {
226 - t.Errorf("root has weird access mode: %v", mode.Perm())
227 - }
228 - switch stat := fi.Sys().(type) {
229 - case *syscall.Stat_t:
230 - if stat.Ino != 1 {
231 - t.Errorf("root has wrong inode: %v", stat.Ino)
232 - }
233 - if stat.Nlink != 1 {
234 - t.Errorf("root has wrong link count: %v", stat.Nlink)
235 - }
236 - if stat.Uid != 0 {
237 - t.Errorf("root has wrong uid: %d", stat.Uid)
238 - }
239 - if stat.Gid != 0 {
240 - t.Errorf("root has wrong gid: %d", stat.Gid)
241 - }
242 - }
243 -}
244 -
245 -// Test Read calling ReadAll.
246 -
247 -type readAll struct {
248 - fstestutil.File
249 -}
250 -
251 -const hi = "hello, world"
252 -
253 -func (readAll) Attr(ctx context.Context, a *fuse.Attr) error {
254 - a.Mode = 0666
255 - a.Size = uint64(len(hi))
256 - return nil
257 -}
258 -
259 -func (readAll) ReadAll(ctx context.Context) ([]byte, error) {
260 - return []byte(hi), nil
261 -}
262 -
263 -func testReadAll(t *testing.T, path string) {
264 - data, err := ioutil.ReadFile(path)
265 - if err != nil {
266 - t.Fatalf("readAll: %v", err)
267 - }
268 - if string(data) != hi {
269 - t.Errorf("readAll = %q, want %q", data, hi)
270 - }
271 -}
272 -
273 -func TestReadAll(t *testing.T) {
274 - t.Parallel()
275 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": readAll{}}})
276 - if err != nil {
277 - t.Fatal(err)
278 - }
279 - defer mnt.Close()
280 -
281 - testReadAll(t, mnt.Dir+"/child")
282 -}
283 -
284 -// Test Read.
285 -
286 -type readWithHandleRead struct {
287 - fstestutil.File
288 -}
289 -
290 -func (readWithHandleRead) Attr(ctx context.Context, a *fuse.Attr) error {
291 - a.Mode = 0666
292 - a.Size = uint64(len(hi))
293 - return nil
294 -}
295 -
296 -func (readWithHandleRead) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
297 - fuseutil.HandleRead(req, resp, []byte(hi))
298 - return nil
299 -}
300 -
301 -func TestReadAllWithHandleRead(t *testing.T) {
302 - t.Parallel()
303 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": readWithHandleRead{}}})
304 - if err != nil {
305 - t.Fatal(err)
306 - }
307 - defer mnt.Close()
308 -
309 - testReadAll(t, mnt.Dir+"/child")
310 -}
311 -
312 -// Test Release.
313 -
314 -type release struct {
315 - fstestutil.File
316 - record.ReleaseWaiter
317 -}
318 -
319 -func TestRelease(t *testing.T) {
320 - t.Parallel()
321 - r := &release{}
322 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": r}})
323 - if err != nil {
324 - t.Fatal(err)
325 - }
326 - defer mnt.Close()
327 -
328 - f, err := os.Open(mnt.Dir + "/child")
329 - if err != nil {
330 - t.Fatal(err)
331 - }
332 - f.Close()
333 - if !r.WaitForRelease(1 * time.Second) {
334 - t.Error("Close did not Release in time")
335 - }
336 -}
337 -
338 -// Test Write calling basic Write, with an fsync thrown in too.
339 -
340 -type write struct {
341 - fstestutil.File
342 - record.Writes
343 - record.Fsyncs
344 -}
345 -
346 -func TestWrite(t *testing.T) {
347 - t.Parallel()
348 - w := &write{}
349 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": w}})
350 - if err != nil {
351 - t.Fatal(err)
352 - }
353 - defer mnt.Close()
354 -
355 - f, err := os.Create(mnt.Dir + "/child")
356 - if err != nil {
357 - t.Fatalf("Create: %v", err)
358 - }
359 - defer f.Close()
360 - n, err := f.Write([]byte(hi))
361 - if err != nil {
362 - t.Fatalf("Write: %v", err)
363 - }
364 - if n != len(hi) {
365 - t.Fatalf("short write; n=%d; hi=%d", n, len(hi))
366 - }
367 -
368 - err = syscall.Fsync(int(f.Fd()))
369 - if err != nil {
370 - t.Fatalf("Fsync = %v", err)
371 - }
372 - if w.RecordedFsync() == (fuse.FsyncRequest{}) {
373 - t.Errorf("never received expected fsync call")
374 - }
375 -
376 - err = f.Close()
377 - if err != nil {
378 - t.Fatalf("Close: %v", err)
379 - }
380 -
381 - if got := string(w.RecordedWriteData()); got != hi {
382 - t.Errorf("write = %q, want %q", got, hi)
383 - }
384 -}
385 -
386 -// Test Write of a larger buffer.
387 -
388 -type writeLarge struct {
389 - fstestutil.File
390 - record.Writes
391 -}
392 -
393 -func TestWriteLarge(t *testing.T) {
394 - t.Parallel()
395 - w := &write{}
396 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": w}})
397 - if err != nil {
398 - t.Fatal(err)
399 - }
400 - defer mnt.Close()
401 -
402 - f, err := os.Create(mnt.Dir + "/child")
403 - if err != nil {
404 - t.Fatalf("Create: %v", err)
405 - }
406 - defer f.Close()
407 - const one = "xyzzyfoo"
408 - large := bytes.Repeat([]byte(one), 8192)
409 - n, err := f.Write(large)
410 - if err != nil {
411 - t.Fatalf("Write: %v", err)
412 - }
413 - if g, e := n, len(large); g != e {
414 - t.Fatalf("short write: %d != %d", g, e)
415 - }
416 -
417 - err = f.Close()
418 - if err != nil {
419 - t.Fatalf("Close: %v", err)
420 - }
421 -
422 - got := w.RecordedWriteData()
423 - if g, e := len(got), len(large); g != e {
424 - t.Errorf("write wrong length: %d != %d", g, e)
425 - }
426 - if g := strings.Replace(string(got), one, "", -1); g != "" {
427 - t.Errorf("write wrong data: expected repeats of %q, also got %q", one, g)
428 - }
429 -}
430 -
431 -// Test Write calling Setattr+Write+Flush.
432 -
433 -type writeTruncateFlush struct {
434 - fstestutil.File
435 - record.Writes
436 - record.Setattrs
437 - record.Flushes
438 -}
439 -
440 -func TestWriteTruncateFlush(t *testing.T) {
441 - t.Parallel()
442 - w := &writeTruncateFlush{}
443 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": w}})
444 - if err != nil {
445 - t.Fatal(err)
446 - }
447 - defer mnt.Close()
448 -
449 - err = ioutil.WriteFile(mnt.Dir+"/child", []byte(hi), 0666)
450 - if err != nil {
451 - t.Fatalf("WriteFile: %v", err)
452 - }
453 - if w.RecordedSetattr() == (fuse.SetattrRequest{}) {
454 - t.Errorf("writeTruncateFlush expected Setattr")
455 - }
456 - if !w.RecordedFlush() {
457 - t.Errorf("writeTruncateFlush expected Setattr")
458 - }
459 - if got := string(w.RecordedWriteData()); got != hi {
460 - t.Errorf("writeTruncateFlush = %q, want %q", got, hi)
461 - }
462 -}
463 -
464 -// Test Mkdir.
465 -
466 -type mkdir1 struct {
467 - fstestutil.Dir
468 - record.Mkdirs
469 -}
470 -
471 -func (f *mkdir1) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
472 - f.Mkdirs.Mkdir(ctx, req)
473 - return &mkdir1{}, nil
474 -}
475 -
476 -func TestMkdir(t *testing.T) {
477 - t.Parallel()
478 - f := &mkdir1{}
479 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
480 - if err != nil {
481 - t.Fatal(err)
482 - }
483 - defer mnt.Close()
484 -
485 - // uniform umask needed to make os.Mkdir's mode into something
486 - // reproducible
487 - defer syscall.Umask(syscall.Umask(0022))
488 - err = os.Mkdir(mnt.Dir+"/foo", 0771)
489 - if err != nil {
490 - t.Fatalf("mkdir: %v", err)
491 - }
492 - want := fuse.MkdirRequest{Name: "foo", Mode: os.ModeDir | 0751}
493 - if g, e := f.RecordedMkdir(), want; g != e {
494 - t.Errorf("mkdir saw %+v, want %+v", g, e)
495 - }
496 -}
497 -
498 -// Test Create (and fsync)
499 -
500 -type create1file struct {
501 - fstestutil.File
502 - record.Fsyncs
503 -}
504 -
505 -type create1 struct {
506 - fstestutil.Dir
507 - f create1file
508 -}
509 -
510 -func (f *create1) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
511 - if req.Name != "foo" {
512 - log.Printf("ERROR create1.Create unexpected name: %q\n", req.Name)
513 - return nil, nil, fuse.EPERM
514 - }
515 - flags := req.Flags
516 -
517 - // OS X does not pass O_TRUNC here, Linux does; as this is a
518 - // Create, that's acceptable
519 - flags &^= fuse.OpenTruncate
520 -
521 - if runtime.GOOS == "linux" {
522 - // Linux <3.7 accidentally leaks O_CLOEXEC through to FUSE;
523 - // avoid spurious test failures
524 - flags &^= fuse.OpenFlags(syscall.O_CLOEXEC)
525 - }
526 -
527 - if g, e := flags, fuse.OpenReadWrite|fuse.OpenCreate; g != e {
528 - log.Printf("ERROR create1.Create unexpected flags: %v != %v\n", g, e)
529 - return nil, nil, fuse.EPERM
530 - }
531 - if g, e := req.Mode, os.FileMode(0644); g != e {
532 - log.Printf("ERROR create1.Create unexpected mode: %v != %v\n", g, e)
533 - return nil, nil, fuse.EPERM
534 - }
535 - return &f.f, &f.f, nil
536 -}
537 -
538 -func TestCreate(t *testing.T) {
539 - t.Parallel()
540 - f := &create1{}
541 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
542 - if err != nil {
543 - t.Fatal(err)
544 - }
545 - defer mnt.Close()
546 -
547 - // uniform umask needed to make os.Create's 0666 into something
548 - // reproducible
549 - defer syscall.Umask(syscall.Umask(0022))
550 - ff, err := os.Create(mnt.Dir + "/foo")
551 - if err != nil {
552 - t.Fatalf("create1 WriteFile: %v", err)
553 - }
554 - defer ff.Close()
555 -
556 - err = syscall.Fsync(int(ff.Fd()))
557 - if err != nil {
558 - t.Fatalf("Fsync = %v", err)
559 - }
560 -
561 - if f.f.RecordedFsync() == (fuse.FsyncRequest{}) {
562 - t.Errorf("never received expected fsync call")
563 - }
564 -
565 - ff.Close()
566 -}
567 -
568 -// Test Create + Write + Remove
569 -
570 -type create3file struct {
571 - fstestutil.File
572 - record.Writes
573 -}
574 -
575 -type create3 struct {
576 - fstestutil.Dir
577 - f create3file
578 - fooCreated record.MarkRecorder
579 - fooRemoved record.MarkRecorder
580 -}
581 -
582 -func (f *create3) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
583 - if req.Name != "foo" {
584 - log.Printf("ERROR create3.Create unexpected name: %q\n", req.Name)
585 - return nil, nil, fuse.EPERM
586 - }
587 - f.fooCreated.Mark()
588 - return &f.f, &f.f, nil
589 -}
590 -
591 -func (f *create3) Lookup(ctx context.Context, name string) (fs.Node, error) {
592 - if f.fooCreated.Recorded() && !f.fooRemoved.Recorded() && name == "foo" {
593 - return &f.f, nil
594 - }
595 - return nil, fuse.ENOENT
596 -}
597 -
598 -func (f *create3) Remove(ctx context.Context, r *fuse.RemoveRequest) error {
599 - if f.fooCreated.Recorded() && !f.fooRemoved.Recorded() &&
600 - r.Name == "foo" && !r.Dir {
601 - f.fooRemoved.Mark()
602 - return nil
603 - }
604 - return fuse.ENOENT
605 -}
606 -
607 -func TestCreateWriteRemove(t *testing.T) {
608 - t.Parallel()
609 - f := &create3{}
610 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
611 - if err != nil {
612 - t.Fatal(err)
613 - }
614 - defer mnt.Close()
615 -
616 - err = ioutil.WriteFile(mnt.Dir+"/foo", []byte(hi), 0666)
617 - if err != nil {
618 - t.Fatalf("create3 WriteFile: %v", err)
619 - }
620 - if got := string(f.f.RecordedWriteData()); got != hi {
621 - t.Fatalf("create3 write = %q, want %q", got, hi)
622 - }
623 -
624 - err = os.Remove(mnt.Dir + "/foo")
625 - if err != nil {
626 - t.Fatalf("Remove: %v", err)
627 - }
628 - err = os.Remove(mnt.Dir + "/foo")
629 - if err == nil {
630 - t.Fatalf("second Remove = nil; want some error")
631 - }
632 -}
633 -
634 -// Test symlink + readlink
635 -
636 -// is a Node that is a symlink to target
637 -type symlink1link struct {
638 - symlink
639 - target string
640 -}
641 -
642 -func (f symlink1link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) {
643 - return f.target, nil
644 -}
645 -
646 -type symlink1 struct {
647 - fstestutil.Dir
648 - record.Symlinks
649 -}
650 -
651 -func (f *symlink1) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) {
652 - f.Symlinks.Symlink(ctx, req)
653 - return symlink1link{target: req.Target}, nil
654 -}
655 -
656 -func TestSymlink(t *testing.T) {
657 - t.Parallel()
658 - f := &symlink1{}
659 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
660 - if err != nil {
661 - t.Fatal(err)
662 - }
663 - defer mnt.Close()
664 -
665 - const target = "/some-target"
666 -
667 - err = os.Symlink(target, mnt.Dir+"/symlink.file")
668 - if err != nil {
669 - t.Fatalf("os.Symlink: %v", err)
670 - }
671 -
672 - want := fuse.SymlinkRequest{NewName: "symlink.file", Target: target}
673 - if g, e := f.RecordedSymlink(), want; g != e {
674 - t.Errorf("symlink saw %+v, want %+v", g, e)
675 - }
676 -
677 - gotName, err := os.Readlink(mnt.Dir + "/symlink.file")
678 - if err != nil {
679 - t.Fatalf("os.Readlink: %v", err)
680 - }
681 - if gotName != target {
682 - t.Errorf("os.Readlink = %q; want %q", gotName, target)
683 - }
684 -}
685 -
686 -// Test link
687 -
688 -type link1 struct {
689 - fstestutil.Dir
690 - record.Links
691 -}
692 -
693 -func (f *link1) Lookup(ctx context.Context, name string) (fs.Node, error) {
694 - if name == "old" {
695 - return fstestutil.File{}, nil
696 - }
697 - return nil, fuse.ENOENT
698 -}
699 -
700 -func (f *link1) Link(ctx context.Context, r *fuse.LinkRequest, old fs.Node) (fs.Node, error) {
701 - f.Links.Link(ctx, r, old)
702 - return fstestutil.File{}, nil
703 -}
704 -
705 -func TestLink(t *testing.T) {
706 - t.Parallel()
707 - f := &link1{}
708 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
709 - if err != nil {
710 - t.Fatal(err)
711 - }
712 - defer mnt.Close()
713 -
714 - err = os.Link(mnt.Dir+"/old", mnt.Dir+"/new")
715 - if err != nil {
716 - t.Fatalf("Link: %v", err)
717 - }
718 -
719 - got := f.RecordedLink()
720 - want := fuse.LinkRequest{
721 - NewName: "new",
722 - // unpredictable
723 - OldNode: got.OldNode,
724 - }
725 - if g, e := got, want; g != e {
726 - t.Fatalf("link saw %+v, want %+v", g, e)
727 - }
728 -}
729 -
730 -// Test Rename
731 -
732 -type rename1 struct {
733 - fstestutil.Dir
734 - renamed record.Counter
735 -}
736 -
737 -func (f *rename1) Lookup(ctx context.Context, name string) (fs.Node, error) {
738 - if name == "old" {
739 - return fstestutil.File{}, nil
740 - }
741 - return nil, fuse.ENOENT
742 -}
743 -
744 -func (f *rename1) Rename(ctx context.Context, r *fuse.RenameRequest, newDir fs.Node) error {
745 - if r.OldName == "old" && r.NewName == "new" && newDir == f {
746 - f.renamed.Inc()
747 - return nil
748 - }
749 - return fuse.EIO
750 -}
751 -
752 -func TestRename(t *testing.T) {
753 - t.Parallel()
754 - f := &rename1{}
755 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
756 - if err != nil {
757 - t.Fatal(err)
758 - }
759 - defer mnt.Close()
760 -
761 - err = os.Rename(mnt.Dir+"/old", mnt.Dir+"/new")
762 - if err != nil {
763 - t.Fatalf("Rename: %v", err)
764 - }
765 - if g, e := f.renamed.Count(), uint32(1); g != e {
766 - t.Fatalf("expected rename didn't happen: %d != %d", g, e)
767 - }
768 - err = os.Rename(mnt.Dir+"/old2", mnt.Dir+"/new2")
769 - if err == nil {
770 - t.Fatal("expected error on second Rename; got nil")
771 - }
772 -}
773 -
774 -// Test mknod
775 -
776 -type mknod1 struct {
777 - fstestutil.Dir
778 - record.Mknods
779 -}
780 -
781 -func (f *mknod1) Mknod(ctx context.Context, r *fuse.MknodRequest) (fs.Node, error) {
782 - f.Mknods.Mknod(ctx, r)
783 - return fifo{}, nil
784 -}
785 -
786 -func TestMknod(t *testing.T) {
787 - t.Parallel()
788 - if os.Getuid() != 0 {
789 - t.Skip("skipping unless root")
790 - }
791 -
792 - f := &mknod1{}
793 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
794 - if err != nil {
795 - t.Fatal(err)
796 - }
797 - defer mnt.Close()
798 -
799 - defer syscall.Umask(syscall.Umask(0))
800 - err = syscall.Mknod(mnt.Dir+"/node", syscall.S_IFIFO|0666, 123)
801 - if err != nil {
802 - t.Fatalf("Mknod: %v", err)
803 - }
804 -
805 - want := fuse.MknodRequest{
806 - Name: "node",
807 - Mode: os.FileMode(os.ModeNamedPipe | 0666),
808 - Rdev: uint32(123),
809 - }
810 - if runtime.GOOS == "linux" {
811 - // Linux fuse doesn't echo back the rdev if the node
812 - // isn't a device (we're using a FIFO here, as that
813 - // bit is portable.)
814 - want.Rdev = 0
815 - }
816 - if g, e := f.RecordedMknod(), want; g != e {
817 - t.Fatalf("mknod saw %+v, want %+v", g, e)
818 - }
819 -}
820 -
821 -// Test Read served with DataHandle.
822 -
823 -type dataHandleTest struct {
824 - fstestutil.File
825 -}
826 -
827 -func (dataHandleTest) Attr(ctx context.Context, a *fuse.Attr) error {
828 - a.Mode = 0666
829 - a.Size = uint64(len(hi))
830 - return nil
831 -}
832 -
833 -func (dataHandleTest) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
834 - return fs.DataHandle([]byte(hi)), nil
835 -}
836 -
837 -func TestDataHandle(t *testing.T) {
838 - t.Parallel()
839 - f := &dataHandleTest{}
840 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
841 - if err != nil {
842 - t.Fatal(err)
843 - }
844 - defer mnt.Close()
845 -
846 - data, err := ioutil.ReadFile(mnt.Dir + "/child")
847 - if err != nil {
848 - t.Errorf("readAll: %v", err)
849 - return
850 - }
851 - if string(data) != hi {
852 - t.Errorf("readAll = %q, want %q", data, hi)
853 - }
854 -}
855 -
856 -// Test interrupt
857 -
858 -type interrupt struct {
859 - fstestutil.File
860 -
861 - // strobes to signal we have a read hanging
862 - hanging chan struct{}
863 -}
864 -
865 -func (interrupt) Attr(ctx context.Context, a *fuse.Attr) error {
866 - a.Mode = 0666
867 - a.Size = 1
868 - return nil
869 -}
870 -
871 -func (it *interrupt) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
872 - select {
873 - case it.hanging <- struct{}{}:
874 - default:
875 - }
876 - <-ctx.Done()
877 - return fuse.EINTR
878 -}
879 -
880 -func TestInterrupt(t *testing.T) {
881 - t.Parallel()
882 - f := &interrupt{}
883 - f.hanging = make(chan struct{}, 1)
884 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
885 - if err != nil {
886 - t.Fatal(err)
887 - }
888 - defer mnt.Close()
889 -
890 - // start a subprocess that can hang until signaled
891 - cmd := exec.Command("cat", mnt.Dir+"/child")
892 -
893 - err = cmd.Start()
894 - if err != nil {
895 - t.Errorf("interrupt: cannot start cat: %v", err)
896 - return
897 - }
898 -
899 - // try to clean up if child is still alive when returning
900 - defer cmd.Process.Kill()
901 -
902 - // wait till we're sure it's hanging in read
903 - <-f.hanging
904 -
905 - err = cmd.Process.Signal(os.Interrupt)
906 - if err != nil {
907 - t.Errorf("interrupt: cannot interrupt cat: %v", err)
908 - return
909 - }
910 -
911 - p, err := cmd.Process.Wait()
912 - if err != nil {
913 - t.Errorf("interrupt: cat bork: %v", err)
914 - return
915 - }
916 - switch ws := p.Sys().(type) {
917 - case syscall.WaitStatus:
918 - if ws.CoreDump() {
919 - t.Errorf("interrupt: didn't expect cat to dump core: %v", ws)
920 - }
921 -
922 - if ws.Exited() {
923 - t.Errorf("interrupt: didn't expect cat to exit normally: %v", ws)
924 - }
925 -
926 - if !ws.Signaled() {
927 - t.Errorf("interrupt: expected cat to get a signal: %v", ws)
928 - } else {
929 - if ws.Signal() != os.Interrupt {
930 - t.Errorf("interrupt: cat got wrong signal: %v", ws)
931 - }
932 - }
933 - default:
934 - t.Logf("interrupt: this platform has no test coverage")
935 - }
936 -}
937 -
938 -// Test truncate
939 -
940 -type truncate struct {
941 - fstestutil.File
942 - record.Setattrs
943 -}
944 -
945 -func testTruncate(t *testing.T, toSize int64) {
946 - t.Parallel()
947 - f := &truncate{}
948 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
949 - if err != nil {
950 - t.Fatal(err)
951 - }
952 - defer mnt.Close()
953 -
954 - err = os.Truncate(mnt.Dir+"/child", toSize)
955 - if err != nil {
956 - t.Fatalf("Truncate: %v", err)
957 - }
958 - gotr := f.RecordedSetattr()
959 - if gotr == (fuse.SetattrRequest{}) {
960 - t.Fatalf("no recorded SetattrRequest")
961 - }
962 - if g, e := gotr.Size, uint64(toSize); g != e {
963 - t.Errorf("got Size = %q; want %q", g, e)
964 - }
965 - if g, e := gotr.Valid&^fuse.SetattrLockOwner, fuse.SetattrSize; g != e {
966 - t.Errorf("got Valid = %q; want %q", g, e)
967 - }
968 - t.Logf("Got request: %#v", gotr)
969 -}
970 -
971 -func TestTruncate42(t *testing.T) {
972 - testTruncate(t, 42)
973 -}
974 -
975 -func TestTruncate0(t *testing.T) {
976 - testTruncate(t, 0)
977 -}
978 -
979 -// Test ftruncate
980 -
981 -type ftruncate struct {
982 - fstestutil.File
983 - record.Setattrs
984 -}
985 -
986 -func testFtruncate(t *testing.T, toSize int64) {
987 - t.Parallel()
988 - f := &ftruncate{}
989 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
990 - if err != nil {
991 - t.Fatal(err)
992 - }
993 - defer mnt.Close()
994 -
995 - {
996 - fil, err := os.OpenFile(mnt.Dir+"/child", os.O_WRONLY, 0666)
997 - if err != nil {
998 - t.Error(err)
999 - return
1000 - }
1001 - defer fil.Close()
1002 -
1003 - err = fil.Truncate(toSize)
1004 - if err != nil {
1005 - t.Fatalf("Ftruncate: %v", err)
1006 - }
1007 - }
1008 - gotr := f.RecordedSetattr()
1009 - if gotr == (fuse.SetattrRequest{}) {
1010 - t.Fatalf("no recorded SetattrRequest")
1011 - }
1012 - if g, e := gotr.Size, uint64(toSize); g != e {
1013 - t.Errorf("got Size = %q; want %q", g, e)
1014 - }
1015 - if g, e := gotr.Valid&^fuse.SetattrLockOwner, fuse.SetattrHandle|fuse.SetattrSize; g != e {
1016 - t.Errorf("got Valid = %q; want %q", g, e)
1017 - }
1018 - t.Logf("Got request: %#v", gotr)
1019 -}
1020 -
1021 -func TestFtruncate42(t *testing.T) {
1022 - testFtruncate(t, 42)
1023 -}
1024 -
1025 -func TestFtruncate0(t *testing.T) {
1026 - testFtruncate(t, 0)
1027 -}
1028 -
1029 -// Test opening existing file truncates
1030 -
1031 -type truncateWithOpen struct {
1032 - fstestutil.File
1033 - record.Setattrs
1034 -}
1035 -
1036 -func TestTruncateWithOpen(t *testing.T) {
1037 - t.Parallel()
1038 - f := &truncateWithOpen{}
1039 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1040 - if err != nil {
1041 - t.Fatal(err)
1042 - }
1043 - defer mnt.Close()
1044 -
1045 - fil, err := os.OpenFile(mnt.Dir+"/child", os.O_WRONLY|os.O_TRUNC, 0666)
1046 - if err != nil {
1047 - t.Error(err)
1048 - return
1049 - }
1050 - fil.Close()
1051 -
1052 - gotr := f.RecordedSetattr()
1053 - if gotr == (fuse.SetattrRequest{}) {
1054 - t.Fatalf("no recorded SetattrRequest")
1055 - }
1056 - if g, e := gotr.Size, uint64(0); g != e {
1057 - t.Errorf("got Size = %q; want %q", g, e)
1058 - }
1059 - // osxfuse sets SetattrHandle here, linux does not
1060 - if g, e := gotr.Valid&^(fuse.SetattrLockOwner|fuse.SetattrHandle), fuse.SetattrSize; g != e {
1061 - t.Errorf("got Valid = %q; want %q", g, e)
1062 - }
1063 - t.Logf("Got request: %#v", gotr)
1064 -}
1065 -
1066 -// Test readdir calling ReadDirAll
1067 -
1068 -type readDirAll struct {
1069 - fstestutil.Dir
1070 -}
1071 -
1072 -func (d *readDirAll) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
1073 - return []fuse.Dirent{
1074 - {Name: "one", Inode: 11, Type: fuse.DT_Dir},
1075 - {Name: "three", Inode: 13},
1076 - {Name: "two", Inode: 12, Type: fuse.DT_File},
1077 - }, nil
1078 -}
1079 -
1080 -func TestReadDirAll(t *testing.T) {
1081 - t.Parallel()
1082 - f := &readDirAll{}
1083 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
1084 - if err != nil {
1085 - t.Fatal(err)
1086 - }
1087 - defer mnt.Close()
1088 -
1089 - fil, err := os.Open(mnt.Dir)
1090 - if err != nil {
1091 - t.Error(err)
1092 - return
1093 - }
1094 - defer fil.Close()
1095 -
1096 - // go Readdir is just Readdirnames + Lstat, there's no point in
1097 - // testing that here; we have no consumption API for the real
1098 - // dirent data
1099 - names, err := fil.Readdirnames(100)
1100 - if err != nil {
1101 - t.Error(err)
1102 - return
1103 - }
1104 -
1105 - t.Logf("Got readdir: %q", names)
1106 -
1107 - if len(names) != 3 ||
1108 - names[0] != "one" ||
1109 - names[1] != "three" ||
1110 - names[2] != "two" {
1111 - t.Errorf(`expected 3 entries of "one", "three", "two", got: %q`, names)
1112 - return
1113 - }
1114 -}
1115 -
1116 -// Test readdir without any ReadDir methods implemented.
1117 -
1118 -type readDirNotImplemented struct {
1119 - fstestutil.Dir
1120 -}
1121 -
1122 -func TestReadDirNotImplemented(t *testing.T) {
1123 - t.Parallel()
1124 - f := &readDirNotImplemented{}
1125 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
1126 - if err != nil {
1127 - t.Fatal(err)
1128 - }
1129 - defer mnt.Close()
1130 -
1131 - fil, err := os.Open(mnt.Dir)
1132 - if err != nil {
1133 - t.Error(err)
1134 - return
1135 - }
1136 - defer fil.Close()
1137 -
1138 - // go Readdir is just Readdirnames + Lstat, there's no point in
1139 - // testing that here; we have no consumption API for the real
1140 - // dirent data
1141 - names, err := fil.Readdirnames(100)
1142 - if len(names) > 0 || err != io.EOF {
1143 - t.Fatalf("expected EOF got names=%v err=%v", names, err)
1144 - }
1145 -}
1146 -
1147 -// Test Chmod.
1148 -
1149 -type chmod struct {
1150 - fstestutil.File
1151 - record.Setattrs
1152 -}
1153 -
1154 -func (f *chmod) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
1155 - if !req.Valid.Mode() {
1156 - log.Printf("setattr not a chmod: %v", req.Valid)
1157 - return fuse.EIO
1158 - }
1159 - f.Setattrs.Setattr(ctx, req, resp)
1160 - return nil
1161 -}
1162 -
1163 -func TestChmod(t *testing.T) {
1164 - t.Parallel()
1165 - f := &chmod{}
1166 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1167 - if err != nil {
1168 - t.Fatal(err)
1169 - }
1170 - defer mnt.Close()
1171 -
1172 - err = os.Chmod(mnt.Dir+"/child", 0764)
1173 - if err != nil {
1174 - t.Errorf("chmod: %v", err)
1175 - return
1176 - }
1177 - got := f.RecordedSetattr()
1178 - if g, e := got.Mode, os.FileMode(0764); g != e {
1179 - t.Errorf("wrong mode: %v != %v", g, e)
1180 - }
1181 -}
1182 -
1183 -// Test open
1184 -
1185 -type open struct {
1186 - fstestutil.File
1187 - record.Opens
1188 -}
1189 -
1190 -func (f *open) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
1191 - f.Opens.Open(ctx, req, resp)
1192 - // pick a really distinct error, to identify it later
1193 - return nil, fuse.Errno(syscall.ENAMETOOLONG)
1194 -
1195 -}
1196 -
1197 -func TestOpen(t *testing.T) {
1198 - t.Parallel()
1199 - f := &open{}
1200 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1201 - if err != nil {
1202 - t.Fatal(err)
1203 - }
1204 - defer mnt.Close()
1205 -
1206 - // node: mode only matters with O_CREATE
1207 - fil, err := os.OpenFile(mnt.Dir+"/child", os.O_WRONLY|os.O_APPEND, 0)
1208 - if err == nil {
1209 - t.Error("Open err == nil, expected ENAMETOOLONG")
1210 - fil.Close()
1211 - return
1212 - }
1213 -
1214 - switch err2 := err.(type) {
1215 - case *os.PathError:
1216 - if err2.Err == syscall.ENAMETOOLONG {
1217 - break
1218 - }
1219 - t.Errorf("unexpected inner error: %#v", err2)
1220 - default:
1221 - t.Errorf("unexpected error: %v", err)
1222 - }
1223 -
1224 - want := fuse.OpenRequest{Dir: false, Flags: fuse.OpenWriteOnly | fuse.OpenAppend}
1225 - if runtime.GOOS == "darwin" {
1226 - // osxfuse does not let O_APPEND through at all
1227 - //
1228 - // https://code.google.com/p/macfuse/issues/detail?id=233
1229 - // https://code.google.com/p/macfuse/issues/detail?id=132
1230 - // https://code.google.com/p/macfuse/issues/detail?id=133
1231 - want.Flags &^= fuse.OpenAppend
1232 - }
1233 - got := f.RecordedOpen()
1234 -
1235 - if runtime.GOOS == "linux" {
1236 - // Linux <3.7 accidentally leaks O_CLOEXEC through to FUSE;
1237 - // avoid spurious test failures
1238 - got.Flags &^= fuse.OpenFlags(syscall.O_CLOEXEC)
1239 - }
1240 -
1241 - if g, e := got, want; g != e {
1242 - t.Errorf("open saw %v, want %v", g, e)
1243 - return
1244 - }
1245 -}
1246 -
1247 -// Test Fsync on a dir
1248 -
1249 -type fsyncDir struct {
1250 - fstestutil.Dir
1251 - record.Fsyncs
1252 -}
1253 -
1254 -func TestFsyncDir(t *testing.T) {
1255 - t.Parallel()
1256 - f := &fsyncDir{}
1257 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{f})
1258 - if err != nil {
1259 - t.Fatal(err)
1260 - }
1261 - defer mnt.Close()
1262 -
1263 - fil, err := os.Open(mnt.Dir)
1264 - if err != nil {
1265 - t.Errorf("fsyncDir open: %v", err)
1266 - return
1267 - }
1268 - defer fil.Close()
1269 - err = fil.Sync()
1270 - if err != nil {
1271 - t.Errorf("fsyncDir sync: %v", err)
1272 - return
1273 - }
1274 -
1275 - got := f.RecordedFsync()
1276 - want := fuse.FsyncRequest{
1277 - Flags: 0,
1278 - Dir: true,
1279 - // unpredictable
1280 - Handle: got.Handle,
1281 - }
1282 - if runtime.GOOS == "darwin" {
1283 - // TODO document the meaning of these flags, figure out why
1284 - // they differ
1285 - want.Flags = 1
1286 - }
1287 - if g, e := got, want; g != e {
1288 - t.Fatalf("fsyncDir saw %+v, want %+v", g, e)
1289 - }
1290 -}
1291 -
1292 -// Test Getxattr
1293 -
1294 -type getxattr struct {
1295 - fstestutil.File
1296 - record.Getxattrs
1297 -}
1298 -
1299 -func (f *getxattr) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
1300 - f.Getxattrs.Getxattr(ctx, req, resp)
1301 - resp.Xattr = []byte("hello, world")
1302 - return nil
1303 -}
1304 -
1305 -func TestGetxattr(t *testing.T) {
1306 - t.Parallel()
1307 - f := &getxattr{}
1308 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1309 - if err != nil {
1310 - t.Fatal(err)
1311 - }
1312 - defer mnt.Close()
1313 -
1314 - buf := make([]byte, 8192)
1315 - n, err := syscallx.Getxattr(mnt.Dir+"/child", "not-there", buf)
1316 - if err != nil {
1317 - t.Errorf("unexpected error: %v", err)
1318 - return
1319 - }
1320 - buf = buf[:n]
1321 - if g, e := string(buf), "hello, world"; g != e {
1322 - t.Errorf("wrong getxattr content: %#v != %#v", g, e)
1323 - }
1324 - seen := f.RecordedGetxattr()
1325 - if g, e := seen.Name, "not-there"; g != e {
1326 - t.Errorf("wrong getxattr name: %#v != %#v", g, e)
1327 - }
1328 -}
1329 -
1330 -// Test Getxattr that has no space to return value
1331 -
1332 -type getxattrTooSmall struct {
1333 - fstestutil.File
1334 -}
1335 -
1336 -func (f *getxattrTooSmall) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
1337 - resp.Xattr = []byte("hello, world")
1338 - return nil
1339 -}
1340 -
1341 -func TestGetxattrTooSmall(t *testing.T) {
1342 - t.Parallel()
1343 - f := &getxattrTooSmall{}
1344 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1345 - if err != nil {
1346 - t.Fatal(err)
1347 - }
1348 - defer mnt.Close()
1349 -
1350 - buf := make([]byte, 3)
1351 - _, err = syscallx.Getxattr(mnt.Dir+"/child", "whatever", buf)
1352 - if err == nil {
1353 - t.Error("Getxattr = nil; want some error")
1354 - }
1355 - if err != syscall.ERANGE {
1356 - t.Errorf("unexpected error: %v", err)
1357 - return
1358 - }
1359 -}
1360 -
1361 -// Test Getxattr used to probe result size
1362 -
1363 -type getxattrSize struct {
1364 - fstestutil.File
1365 -}
1366 -
1367 -func (f *getxattrSize) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
1368 - resp.Xattr = []byte("hello, world")
1369 - return nil
1370 -}
1371 -
1372 -func TestGetxattrSize(t *testing.T) {
1373 - t.Parallel()
1374 - f := &getxattrSize{}
1375 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1376 - if err != nil {
1377 - t.Fatal(err)
1378 - }
1379 - defer mnt.Close()
1380 -
1381 - n, err := syscallx.Getxattr(mnt.Dir+"/child", "whatever", nil)
1382 - if err != nil {
1383 - t.Errorf("Getxattr unexpected error: %v", err)
1384 - return
1385 - }
1386 - if g, e := n, len("hello, world"); g != e {
1387 - t.Errorf("Getxattr incorrect size: %d != %d", g, e)
1388 - }
1389 -}
1390 -
1391 -// Test Listxattr
1392 -
1393 -type listxattr struct {
1394 - fstestutil.File
1395 - record.Listxattrs
1396 -}
1397 -
1398 -func (f *listxattr) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
1399 - f.Listxattrs.Listxattr(ctx, req, resp)
1400 - resp.Append("one", "two")
1401 - return nil
1402 -}
1403 -
1404 -func TestListxattr(t *testing.T) {
1405 - t.Parallel()
1406 - f := &listxattr{}
1407 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1408 - if err != nil {
1409 - t.Fatal(err)
1410 - }
1411 - defer mnt.Close()
1412 -
1413 - buf := make([]byte, 8192)
1414 - n, err := syscallx.Listxattr(mnt.Dir+"/child", buf)
1415 - if err != nil {
1416 - t.Errorf("unexpected error: %v", err)
1417 - return
1418 - }
1419 - buf = buf[:n]
1420 - if g, e := string(buf), "one\x00two\x00"; g != e {
1421 - t.Errorf("wrong listxattr content: %#v != %#v", g, e)
1422 - }
1423 -
1424 - want := fuse.ListxattrRequest{
1425 - Size: 8192,
1426 - }
1427 - if g, e := f.RecordedListxattr(), want; g != e {
1428 - t.Fatalf("listxattr saw %+v, want %+v", g, e)
1429 - }
1430 -}
1431 -
1432 -// Test Listxattr that has no space to return value
1433 -
1434 -type listxattrTooSmall struct {
1435 - fstestutil.File
1436 -}
1437 -
1438 -func (f *listxattrTooSmall) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
1439 - resp.Xattr = []byte("one\x00two\x00")
1440 - return nil
1441 -}
1442 -
1443 -func TestListxattrTooSmall(t *testing.T) {
1444 - t.Parallel()
1445 - f := &listxattrTooSmall{}
1446 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1447 - if err != nil {
1448 - t.Fatal(err)
1449 - }
1450 - defer mnt.Close()
1451 -
1452 - buf := make([]byte, 3)
1453 - _, err = syscallx.Listxattr(mnt.Dir+"/child", buf)
1454 - if err == nil {
1455 - t.Error("Listxattr = nil; want some error")
1456 - }
1457 - if err != syscall.ERANGE {
1458 - t.Errorf("unexpected error: %v", err)
1459 - return
1460 - }
1461 -}
1462 -
1463 -// Test Listxattr used to probe result size
1464 -
1465 -type listxattrSize struct {
1466 - fstestutil.File
1467 -}
1468 -
1469 -func (f *listxattrSize) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
1470 - resp.Xattr = []byte("one\x00two\x00")
1471 - return nil
1472 -}
1473 -
1474 -func TestListxattrSize(t *testing.T) {
1475 - t.Parallel()
1476 - f := &listxattrSize{}
1477 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1478 - if err != nil {
1479 - t.Fatal(err)
1480 - }
1481 - defer mnt.Close()
1482 -
1483 - n, err := syscallx.Listxattr(mnt.Dir+"/child", nil)
1484 - if err != nil {
1485 - t.Errorf("Listxattr unexpected error: %v", err)
1486 - return
1487 - }
1488 - if g, e := n, len("one\x00two\x00"); g != e {
1489 - t.Errorf("Getxattr incorrect size: %d != %d", g, e)
1490 - }
1491 -}
1492 -
1493 -// Test Setxattr
1494 -
1495 -type setxattr struct {
1496 - fstestutil.File
1497 - record.Setxattrs
1498 -}
1499 -
1500 -func testSetxattr(t *testing.T, size int) {
1501 - const linux_XATTR_NAME_MAX = 64 * 1024
1502 - if size > linux_XATTR_NAME_MAX && runtime.GOOS == "linux" {
1503 - t.Skip("large xattrs are not supported by linux")
1504 - }
1505 -
1506 - t.Parallel()
1507 - f := &setxattr{}
1508 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1509 - if err != nil {
1510 - t.Fatal(err)
1511 - }
1512 - defer mnt.Close()
1513 -
1514 - const g = "hello, world"
1515 - greeting := strings.Repeat(g, size/len(g)+1)[:size]
1516 - err = syscallx.Setxattr(mnt.Dir+"/child", "greeting", []byte(greeting), 0)
1517 - if err != nil {
1518 - t.Errorf("unexpected error: %v", err)
1519 - return
1520 - }
1521 -
1522 - // fuse.SetxattrRequest contains a byte slice and thus cannot be
1523 - // directly compared
1524 - got := f.RecordedSetxattr()
1525 -
1526 - if g, e := got.Name, "greeting"; g != e {
1527 - t.Errorf("Setxattr incorrect name: %q != %q", g, e)
1528 - }
1529 -
1530 - if g, e := got.Flags, uint32(0); g != e {
1531 - t.Errorf("Setxattr incorrect flags: %d != %d", g, e)
1532 - }
1533 -
1534 - if g, e := string(got.Xattr), greeting; g != e {
1535 - t.Errorf("Setxattr incorrect data: %q != %q", g, e)
1536 - }
1537 -}
1538 -
1539 -func TestSetxattr(t *testing.T) {
1540 - testSetxattr(t, 20)
1541 -}
1542 -
1543 -func TestSetxattr64kB(t *testing.T) {
1544 - testSetxattr(t, 64*1024)
1545 -}
1546 -
1547 -func TestSetxattr16MB(t *testing.T) {
1548 - testSetxattr(t, 16*1024*1024)
1549 -}
1550 -
1551 -// Test Removexattr
1552 -
1553 -type removexattr struct {
1554 - fstestutil.File
1555 - record.Removexattrs
1556 -}
1557 -
1558 -func TestRemovexattr(t *testing.T) {
1559 - t.Parallel()
1560 - f := &removexattr{}
1561 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": f}})
1562 - if err != nil {
1563 - t.Fatal(err)
1564 - }
1565 - defer mnt.Close()
1566 -
1567 - err = syscallx.Removexattr(mnt.Dir+"/child", "greeting")
1568 - if err != nil {
1569 - t.Errorf("unexpected error: %v", err)
1570 - return
1571 - }
1572 -
1573 - want := fuse.RemovexattrRequest{Name: "greeting"}
1574 - if g, e := f.RecordedRemovexattr(), want; g != e {
1575 - t.Errorf("removexattr saw %v, want %v", g, e)
1576 - }
1577 -}
1578 -
1579 -// Test default error.
1580 -
1581 -type defaultErrno struct {
1582 - fstestutil.Dir
1583 -}
1584 -
1585 -func (f defaultErrno) Lookup(ctx context.Context, name string) (fs.Node, error) {
1586 - return nil, errors.New("bork")
1587 -}
1588 -
1589 -func TestDefaultErrno(t *testing.T) {
1590 - t.Parallel()
1591 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{defaultErrno{}})
1592 - if err != nil {
1593 - t.Fatal(err)
1594 - }
1595 - defer mnt.Close()
1596 -
1597 - _, err = os.Stat(mnt.Dir + "/trigger")
1598 - if err == nil {
1599 - t.Fatalf("expected error")
1600 - }
1601 -
1602 - switch err2 := err.(type) {
1603 - case *os.PathError:
1604 - if err2.Err == syscall.EIO {
1605 - break
1606 - }
1607 - t.Errorf("unexpected inner error: Err=%v %#v", err2.Err, err2)
1608 - default:
1609 - t.Errorf("unexpected error: %v", err)
1610 - }
1611 -}
1612 -
1613 -// Test custom error.
1614 -
1615 -type customErrNode struct {
1616 - fstestutil.Dir
1617 -}
1618 -
1619 -type myCustomError struct {
1620 - fuse.ErrorNumber
1621 -}
1622 -
1623 -var _ = fuse.ErrorNumber(myCustomError{})
1624 -
1625 -func (myCustomError) Error() string {
1626 - return "bork"
1627 -}
1628 -
1629 -func (f customErrNode) Lookup(ctx context.Context, name string) (fs.Node, error) {
1630 - return nil, myCustomError{
1631 - ErrorNumber: fuse.Errno(syscall.ENAMETOOLONG),
1632 - }
1633 -}
1634 -
1635 -func TestCustomErrno(t *testing.T) {
1636 - t.Parallel()
1637 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{customErrNode{}})
1638 - if err != nil {
1639 - t.Fatal(err)
1640 - }
1641 - defer mnt.Close()
1642 -
1643 - _, err = os.Stat(mnt.Dir + "/trigger")
1644 - if err == nil {
1645 - t.Fatalf("expected error")
1646 - }
1647 -
1648 - switch err2 := err.(type) {
1649 - case *os.PathError:
1650 - if err2.Err == syscall.ENAMETOOLONG {
1651 - break
1652 - }
1653 - t.Errorf("unexpected inner error: %#v", err2)
1654 - default:
1655 - t.Errorf("unexpected error: %v", err)
1656 - }
1657 -}
1658 -
1659 -// Test Mmap writing
1660 -
1661 -type inMemoryFile struct {
1662 - mu sync.Mutex
1663 - data []byte
1664 -}
1665 -
1666 -func (f *inMemoryFile) bytes() []byte {
1667 - f.mu.Lock()
1668 - defer f.mu.Unlock()
1669 -
1670 - return f.data
1671 -}
1672 -
1673 -func (f *inMemoryFile) Attr(ctx context.Context, a *fuse.Attr) error {
1674 - f.mu.Lock()
1675 - defer f.mu.Unlock()
1676 -
1677 - a.Mode = 0666
1678 - a.Size = uint64(len(f.data))
1679 - return nil
1680 -}
1681 -
1682 -func (f *inMemoryFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
1683 - f.mu.Lock()
1684 - defer f.mu.Unlock()
1685 -
1686 - fuseutil.HandleRead(req, resp, f.data)
1687 - return nil
1688 -}
1689 -
1690 -func (f *inMemoryFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
1691 - f.mu.Lock()
1692 - defer f.mu.Unlock()
1693 -
1694 - resp.Size = copy(f.data[req.Offset:], req.Data)
1695 - return nil
1696 -}
1697 -
1698 -const mmapSize = 16 * 4096
1699 -
1700 -var mmapWrites = map[int]byte{
1701 - 10: 'a',
1702 - 4096: 'b',
1703 - 4097: 'c',
1704 - mmapSize - 4096: 'd',
1705 - mmapSize - 1: 'z',
1706 -}
1707 -
1708 -func helperMmap() {
1709 - f, err := os.Create("child")
1710 - if err != nil {
1711 - log.Fatalf("Create: %v", err)
1712 - }
1713 - defer f.Close()
1714 -
1715 - data, err := syscall.Mmap(int(f.Fd()), 0, mmapSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
1716 - if err != nil {
1717 - log.Fatalf("Mmap: %v", err)
1718 - }
1719 -
1720 - for i, b := range mmapWrites {
1721 - data[i] = b
1722 - }
1723 -
1724 - if err := syscallx.Msync(data, syscall.MS_SYNC); err != nil {
1725 - log.Fatalf("Msync: %v", err)
1726 - }
1727 -
1728 - if err := syscall.Munmap(data); err != nil {
1729 - log.Fatalf("Munmap: %v", err)
1730 - }
1731 -
1732 - if err := f.Sync(); err != nil {
1733 - log.Fatalf("Fsync = %v", err)
1734 - }
1735 -
1736 - err = f.Close()
1737 - if err != nil {
1738 - log.Fatalf("Close: %v", err)
1739 - }
1740 -}
1741 -
1742 -func init() {
1743 - childHelpers["mmap"] = helperMmap
1744 -}
1745 -
1746 -type mmap struct {
1747 - inMemoryFile
1748 - // We don't actually care about whether the fsync happened or not;
1749 - // this just lets us force the page cache to send the writes to
1750 - // FUSE, so we can reliably verify they came through.
1751 - record.Fsyncs
1752 -}
1753 -
1754 -func TestMmap(t *testing.T) {
1755 -
1756 - w := &mmap{}
1757 - w.data = make([]byte, mmapSize)
1758 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": w}})
1759 - if err != nil {
1760 - t.Fatal(err)
1761 - }
1762 - defer mnt.Close()
1763 -
1764 - // Run the mmap-using parts of the test in a subprocess, to avoid
1765 - // an intentional page fault hanging the whole process (because it
1766 - // would need to be served by the same process, and there might
1767 - // not be a thread free to do that). Merely bumping GOMAXPROCS is
1768 - // not enough to prevent the hangs reliably.
1769 - child, err := childCmd("mmap")
1770 - if err != nil {
1771 - t.Fatal(err)
1772 - }
1773 - child.Dir = mnt.Dir
1774 - if err := child.Run(); err != nil {
1775 - t.Fatal(err)
1776 - }
1777 -
1778 - got := w.bytes()
1779 - if g, e := len(got), mmapSize; g != e {
1780 - t.Fatalf("bad write length: %d != %d", g, e)
1781 - }
1782 - for i, g := range got {
1783 - // default '\x00' for writes[i] is good here
1784 - if e := mmapWrites[i]; g != e {
1785 - t.Errorf("wrong byte at offset %d: %q != %q", i, g, e)
1786 - }
1787 - }
1788 -}
1789 -
1790 -// Test direct Read.
1791 -
1792 -type directRead struct {
1793 - fstestutil.File
1794 -}
1795 -
1796 -// explicitly not defining Attr and setting Size
1797 -
1798 -func (f directRead) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
1799 - // do not allow the kernel to use page cache
1800 - resp.Flags |= fuse.OpenDirectIO
1801 - return f, nil
1802 -}
1803 -
1804 -func (directRead) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
1805 - fuseutil.HandleRead(req, resp, []byte(hi))
1806 - return nil
1807 -}
1808 -
1809 -func TestDirectRead(t *testing.T) {
1810 - t.Parallel()
1811 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": directRead{}}})
1812 - if err != nil {
1813 - t.Fatal(err)
1814 - }
1815 - defer mnt.Close()
1816 -
1817 - testReadAll(t, mnt.Dir+"/child")
1818 -}
1819 -
1820 -// Test direct Write.
1821 -
1822 -type directWrite struct {
1823 - fstestutil.File
1824 - record.Writes
1825 -}
1826 -
1827 -// explicitly not defining Attr / Setattr and managing Size
1828 -
1829 -func (f *directWrite) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
1830 - // do not allow the kernel to use page cache
1831 - resp.Flags |= fuse.OpenDirectIO
1832 - return f, nil
1833 -}
1834 -
1835 -func TestDirectWrite(t *testing.T) {
1836 - t.Parallel()
1837 - w := &directWrite{}
1838 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": w}})
1839 - if err != nil {
1840 - t.Fatal(err)
1841 - }
1842 - defer mnt.Close()
1843 -
1844 - f, err := os.OpenFile(mnt.Dir+"/child", os.O_RDWR, 0666)
1845 - if err != nil {
1846 - t.Fatalf("Create: %v", err)
1847 - }
1848 - defer f.Close()
1849 - n, err := f.Write([]byte(hi))
1850 - if err != nil {
1851 - t.Fatalf("Write: %v", err)
1852 - }
1853 - if n != len(hi) {
1854 - t.Fatalf("short write; n=%d; hi=%d", n, len(hi))
1855 - }
1856 -
1857 - err = f.Close()
1858 - if err != nil {
1859 - t.Fatalf("Close: %v", err)
1860 - }
1861 -
1862 - if got := string(w.RecordedWriteData()); got != hi {
1863 - t.Errorf("write = %q, want %q", got, hi)
1864 - }
1865 -}
1866 -
1867 -// Test Attr
1868 -
1869 -// attrUnlinked is a file that is unlinked (Nlink==0).
1870 -type attrUnlinked struct {
1871 - fstestutil.File
1872 -}
1873 -
1874 -var _ fs.Node = attrUnlinked{}
1875 -
1876 -func (f attrUnlinked) Attr(ctx context.Context, a *fuse.Attr) error {
1877 - if err := f.File.Attr(ctx, a); err != nil {
1878 - return err
1879 - }
1880 - a.Nlink = 0
1881 - return nil
1882 -}
1883 -
1884 -func TestAttrUnlinked(t *testing.T) {
1885 - t.Parallel()
1886 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": attrUnlinked{}}})
1887 -
1888 - fi, err := os.Stat(mnt.Dir + "/child")
1889 - if err != nil {
1890 - t.Fatalf("Stat failed with %v", err)
1891 - }
1892 - switch stat := fi.Sys().(type) {
1893 - case *syscall.Stat_t:
1894 - if stat.Nlink != 0 {
1895 - t.Errorf("wrong link count: %v", stat.Nlink)
1896 - }
1897 - }
1898 -}
1899 -
1900 -// Test behavior when Attr method fails
1901 -
1902 -type attrBad struct {
1903 -}
1904 -
1905 -var _ fs.Node = attrBad{}
1906 -
1907 -func (attrBad) Attr(ctx context.Context, attr *fuse.Attr) error {
1908 - return fuse.Errno(syscall.ENAMETOOLONG)
1909 -}
1910 -
1911 -func TestAttrBad(t *testing.T) {
1912 - t.Parallel()
1913 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.ChildMap{"child": attrBad{}}})
1914 -
1915 - _, err = os.Stat(mnt.Dir + "/child")
1916 - if nerr, ok := err.(*os.PathError); !ok || nerr.Err != syscall.ENAMETOOLONG {
1917 - t.Fatalf("wrong error: %v", err)
1918 - }
1919 -}
Godeps/_workspace/src/bazil.org/fuse/fs/tree.go deleted
-99
@@ -1,99 +0,0 @@
1 -// FUSE directory tree, for servers that wish to use it with the service loop.
2 -
3 -package fs
4 -
5 -import (
6 - "os"
7 - pathpkg "path"
8 - "strings"
9 -
10 - "context"
11 -)
12 -
13 -import (
14 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
15 -)
16 -
17 -// A Tree implements a basic read-only directory tree for FUSE.
18 -// The Nodes contained in it may still be writable.
19 -type Tree struct {
20 - tree
21 -}
22 -
23 -func (t *Tree) Root() (Node, error) {
24 - return &t.tree, nil
25 -}
26 -
27 -// Add adds the path to the tree, resolving to the given node.
28 -// If path or a prefix of path has already been added to the tree,
29 -// Add panics.
30 -//
31 -// Add is only safe to call before starting to serve requests.
32 -func (t *Tree) Add(path string, node Node) {
33 - path = pathpkg.Clean("/" + path)[1:]
34 - elems := strings.Split(path, "/")
35 - dir := Node(&t.tree)
36 - for i, elem := range elems {
37 - dt, ok := dir.(*tree)
38 - if !ok {
39 - panic("fuse: Tree.Add for " + strings.Join(elems[:i], "/") + " and " + path)
40 - }
41 - n := dt.lookup(elem)
42 - if n != nil {
43 - if i+1 == len(elems) {
44 - panic("fuse: Tree.Add for " + path + " conflicts with " + elem)
45 - }
46 - dir = n
47 - } else {
48 - if i+1 == len(elems) {
49 - dt.add(elem, node)
50 - } else {
51 - dir = &tree{}
52 - dt.add(elem, dir)
53 - }
54 - }
55 - }
56 -}
57 -
58 -type treeDir struct {
59 - name string
60 - node Node
61 -}
62 -
63 -type tree struct {
64 - dir []treeDir
65 -}
66 -
67 -func (t *tree) lookup(name string) Node {
68 - for _, d := range t.dir {
69 - if d.name == name {
70 - return d.node
71 - }
72 - }
73 - return nil
74 -}
75 -
76 -func (t *tree) add(name string, n Node) {
77 - t.dir = append(t.dir, treeDir{name, n})
78 -}
79 -
80 -func (t *tree) Attr(ctx context.Context, a *fuse.Attr) error {
81 - a.Mode = os.ModeDir | 0555
82 - return nil
83 -}
84 -
85 -func (t *tree) Lookup(ctx context.Context, name string) (Node, error) {
86 - n := t.lookup(name)
87 - if n != nil {
88 - return n, nil
89 - }
90 - return nil, fuse.ENOENT
91 -}
92 -
93 -func (t *tree) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
94 - var out []fuse.Dirent
95 - for _, d := range t.dir {
96 - out = append(out, fuse.Dirent{Name: d.name})
97 - }
98 - return out, nil
99 -}
Godeps/_workspace/src/bazil.org/fuse/fuse.go deleted
-2028
@@ -1,2028 +0,0 @@
1 -// See the file LICENSE for copyright and licensing information.
2 -
3 -// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
4 -// which carries this notice:
5 -//
6 -// The files in this directory are subject to the following license.
7 -//
8 -// The author of this software is Russ Cox.
9 -//
10 -// Copyright (c) 2006 Russ Cox
11 -//
12 -// Permission to use, copy, modify, and distribute this software for any
13 -// purpose without fee is hereby granted, provided that this entire notice
14 -// is included in all copies of any software which is or includes a copy
15 -// or modification of this software and in all copies of the supporting
16 -// documentation for such software.
17 -//
18 -// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
19 -// WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY
20 -// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
21 -// FITNESS FOR ANY PARTICULAR PURPOSE.
22 -
23 -// Package fuse enables writing FUSE file systems on Linux, OS X, and FreeBSD.
24 -//
25 -// On OS X, it requires OSXFUSE (http://osxfuse.github.com/).
26 -//
27 -// There are two approaches to writing a FUSE file system. The first is to speak
28 -// the low-level message protocol, reading from a Conn using ReadRequest and
29 -// writing using the various Respond methods. This approach is closest to
30 -// the actual interaction with the kernel and can be the simplest one in contexts
31 -// such as protocol translators.
32 -//
33 -// Servers of synthesized file systems tend to share common
34 -// bookkeeping abstracted away by the second approach, which is to
35 -// call fs.Serve to serve the FUSE protocol using an implementation of
36 -// the service methods in the interfaces FS* (file system), Node* (file
37 -// or directory), and Handle* (opened file or directory).
38 -// There are a daunting number of such methods that can be written,
39 -// but few are required.
40 -// The specific methods are described in the documentation for those interfaces.
41 -//
42 -// The hellofs subdirectory contains a simple illustration of the fs.Serve approach.
43 -//
44 -// Service Methods
45 -//
46 -// The required and optional methods for the FS, Node, and Handle interfaces
47 -// have the general form
48 -//
49 -// Op(ctx context.Context, req *OpRequest, resp *OpResponse) error
50 -//
51 -// where Op is the name of a FUSE operation. Op reads request
52 -// parameters from req and writes results to resp. An operation whose
53 -// only result is the error result omits the resp parameter.
54 -//
55 -// Multiple goroutines may call service methods simultaneously; the
56 -// methods being called are responsible for appropriate
57 -// synchronization.
58 -//
59 -// The operation must not hold on to the request or response,
60 -// including any []byte fields such as WriteRequest.Data or
61 -// SetxattrRequest.Xattr.
62 -//
63 -// Errors
64 -//
65 -// Operations can return errors. The FUSE interface can only
66 -// communicate POSIX errno error numbers to file system clients, the
67 -// message is not visible to file system clients. The returned error
68 -// can implement ErrorNumber to control the errno returned. Without
69 -// ErrorNumber, a generic errno (EIO) is returned.
70 -//
71 -// Error messages will be visible in the debug log as part of the
72 -// response.
73 -//
74 -// Interrupted Operations
75 -//
76 -// In some file systems, some operations
77 -// may take an undetermined amount of time. For example, a Read waiting for
78 -// a network message or a matching Write might wait indefinitely. If the request
79 -// is cancelled and no longer needed, the context will be cancelled.
80 -// Blocking operations should select on a receive from ctx.Done() and attempt to
81 -// abort the operation early if the receive succeeds (meaning the channel is closed).
82 -// To indicate that the operation failed because it was aborted, return fuse.EINTR.
83 -//
84 -// If an operation does not block for an indefinite amount of time, supporting
85 -// cancellation is not necessary.
86 -//
87 -// Authentication
88 -//
89 -// All requests types embed a Header, meaning that the method can
90 -// inspect req.Pid, req.Uid, and req.Gid as necessary to implement
91 -// permission checking. The kernel FUSE layer normally prevents other
92 -// users from accessing the FUSE file system (to change this, see
93 -// AllowOther, AllowRoot), but does not enforce access modes (to
94 -// change this, see DefaultPermissions).
95 -//
96 -// Mount Options
97 -//
98 -// Behavior and metadata of the mounted file system can be changed by
99 -// passing MountOption values to Mount.
100 -//
101 -package fuse
102 -
103 -import (
104 - "bytes"
105 - "encoding/json"
106 - "errors"
107 - "fmt"
108 - "io"
109 - "os"
110 - "sync"
111 - "syscall"
112 - "time"
113 - "unsafe"
114 -)
115 -
116 -// A Conn represents a connection to a mounted FUSE file system.
117 -type Conn struct {
118 - // Ready is closed when the mount is complete or has failed.
119 - Ready <-chan struct{}
120 -
121 - // MountError stores any error from the mount process. Only valid
122 - // after Ready is closed.
123 - MountError error
124 -
125 - // File handle for kernel communication. Only safe to access if
126 - // rio or wio is held.
127 - dev *os.File
128 - buf []byte
129 - wio sync.Mutex
130 - rio sync.RWMutex
131 -}
132 -
133 -// Mount mounts a new FUSE connection on the named directory
134 -// and returns a connection for reading and writing FUSE messages.
135 -//
136 -// After a successful return, caller must call Close to free
137 -// resources.
138 -//
139 -// Even on successful return, the new mount is not guaranteed to be
140 -// visible until after Conn.Ready is closed. See Conn.MountError for
141 -// possible errors. Incoming requests on Conn must be served to make
142 -// progress.
143 -func Mount(dir string, options ...MountOption) (*Conn, error) {
144 - conf := MountConfig{
145 - options: make(map[string]string),
146 - }
147 - for _, option := range options {
148 - if err := option(&conf); err != nil {
149 - return nil, err
150 - }
151 - }
152 -
153 - ready := make(chan struct{}, 1)
154 - c := &Conn{
155 - Ready: ready,
156 - }
157 - f, err := mount(dir, &conf, ready, &c.MountError)
158 - if err != nil {
159 - return nil, err
160 - }
161 - c.dev = f
162 - return c, nil
163 -}
164 -
165 -// A Request represents a single FUSE request received from the kernel.
166 -// Use a type switch to determine the specific kind.
167 -// A request of unrecognized type will have concrete type *Header.
168 -type Request interface {
169 - // Hdr returns the Header associated with this request.
170 - Hdr() *Header
171 -
172 - // RespondError responds to the request with the given error.
173 - RespondError(error)
174 -
175 - String() string
176 -}
177 -
178 -// A RequestID identifies an active FUSE request.
179 -type RequestID uint64
180 -
181 -// A NodeID is a number identifying a directory or file.
182 -// It must be unique among IDs returned in LookupResponses
183 -// that have not yet been forgotten by ForgetRequests.
184 -type NodeID uint64
185 -
186 -// A HandleID is a number identifying an open directory or file.
187 -// It only needs to be unique while the directory or file is open.
188 -type HandleID uint64
189 -
190 -// The RootID identifies the root directory of a FUSE file system.
191 -const RootID NodeID = rootID
192 -
193 -// A Header describes the basic information sent in every request.
194 -type Header struct {
195 - Conn *Conn `json:"-"` // connection this request was received on
196 - ID RequestID // unique ID for request
197 - Node NodeID // file or directory the request is about
198 - Uid uint32 // user ID of process making request
199 - Gid uint32 // group ID of process making request
200 - Pid uint32 // process ID of process making request
201 -
202 - // for returning to reqPool
203 - msg *message
204 -}
205 -
206 -func (h *Header) String() string {
207 - return fmt.Sprintf("ID=%#x Node=%#x Uid=%d Gid=%d Pid=%d", h.ID, h.Node, h.Uid, h.Gid, h.Pid)
208 -}
209 -
210 -func (h *Header) Hdr() *Header {
211 - return h
212 -}
213 -
214 -func (h *Header) noResponse() {
215 - putMessage(h.msg)
216 -}
217 -
218 -func (h *Header) respond(out *outHeader, n uintptr) {
219 - h.Conn.respond(out, n)
220 - putMessage(h.msg)
221 -}
222 -
223 -func (h *Header) respondData(out *outHeader, n uintptr, data []byte) {
224 - h.Conn.respondData(out, n, data)
225 - putMessage(h.msg)
226 -}
227 -
228 -// An ErrorNumber is an error with a specific error number.
229 -//
230 -// Operations may return an error value that implements ErrorNumber to
231 -// control what specific error number (errno) to return.
232 -type ErrorNumber interface {
233 - // Errno returns the the error number (errno) for this error.
234 - Errno() Errno
235 -}
236 -
237 -const (
238 - // ENOSYS indicates that the call is not supported.
239 - ENOSYS = Errno(syscall.ENOSYS)
240 -
241 - // ESTALE is used by Serve to respond to violations of the FUSE protocol.
242 - ESTALE = Errno(syscall.ESTALE)
243 -
244 - ENOENT = Errno(syscall.ENOENT)
245 - EIO = Errno(syscall.EIO)
246 - EPERM = Errno(syscall.EPERM)
247 -
248 - // EINTR indicates request was interrupted by an InterruptRequest.
249 - // See also fs.Intr.
250 - EINTR = Errno(syscall.EINTR)
251 -
252 - ERANGE = Errno(syscall.ERANGE)
253 - ENOTSUP = Errno(syscall.ENOTSUP)
254 - EEXIST = Errno(syscall.EEXIST)
255 -)
256 -
257 -// DefaultErrno is the errno used when error returned does not
258 -// implement ErrorNumber.
259 -const DefaultErrno = EIO
260 -
261 -var errnoNames = map[Errno]string{
262 - ENOSYS: "ENOSYS",
263 - ESTALE: "ESTALE",
264 - ENOENT: "ENOENT",
265 - EIO: "EIO",
266 - EPERM: "EPERM",
267 - EINTR: "EINTR",
268 - EEXIST: "EEXIST",
269 -}
270 -
271 -// Errno implements Error and ErrorNumber using a syscall.Errno.
272 -type Errno syscall.Errno
273 -
274 -var _ = ErrorNumber(Errno(0))
275 -var _ = error(Errno(0))
276 -
277 -func (e Errno) Errno() Errno {
278 - return e
279 -}
280 -
281 -func (e Errno) String() string {
282 - return syscall.Errno(e).Error()
283 -}
284 -
285 -func (e Errno) Error() string {
286 - return syscall.Errno(e).Error()
287 -}
288 -
289 -// ErrnoName returns the short non-numeric identifier for this errno.
290 -// For example, "EIO".
291 -func (e Errno) ErrnoName() string {
292 - s := errnoNames[e]
293 - if s == "" {
294 - s = fmt.Sprint(e.Errno())
295 - }
296 - return s
297 -}
298 -
299 -func (e Errno) MarshalText() ([]byte, error) {
300 - s := e.ErrnoName()
301 - return []byte(s), nil
302 -}
303 -
304 -func (h *Header) RespondError(err error) {
305 - errno := DefaultErrno
306 - if ferr, ok := err.(ErrorNumber); ok {
307 - errno = ferr.Errno()
308 - }
309 - // FUSE uses negative errors!
310 - // TODO: File bug report against OSXFUSE: positive error causes kernel panic.
311 - out := &outHeader{Error: -int32(errno), Unique: uint64(h.ID)}
312 - h.respond(out, unsafe.Sizeof(*out))
313 -}
314 -
315 -// Maximum file write size we are prepared to receive from the kernel.
316 -const maxWrite = 16 * 1024 * 1024
317 -
318 -// All requests read from the kernel, without data, are shorter than
319 -// this.
320 -var maxRequestSize = syscall.Getpagesize()
321 -var bufSize = maxRequestSize + maxWrite
322 -
323 -// reqPool is a pool of messages.
324 -//
325 -// Lifetime of a logical message is from getMessage to putMessage.
326 -// getMessage is called by ReadRequest. putMessage is called by
327 -// Conn.ReadRequest, Request.Respond, or Request.RespondError.
328 -//
329 -// Messages in the pool are guaranteed to have conn and off zeroed,
330 -// buf allocated and len==bufSize, and hdr set.
331 -var reqPool = sync.Pool{
332 - New: allocMessage,
333 -}
334 -
335 -func allocMessage() interface{} {
336 - m := &message{buf: make([]byte, bufSize)}
337 - m.hdr = (*inHeader)(unsafe.Pointer(&m.buf[0]))
338 - return m
339 -}
340 -
341 -func getMessage(c *Conn) *message {
342 - m := reqPool.Get().(*message)
343 - m.conn = c
344 - return m
345 -}
346 -
347 -func putMessage(m *message) {
348 - m.buf = m.buf[:bufSize]
349 - m.conn = nil
350 - m.off = 0
351 - reqPool.Put(m)
352 -}
353 -
354 -// a message represents the bytes of a single FUSE message
355 -type message struct {
356 - conn *Conn
357 - buf []byte // all bytes
358 - hdr *inHeader // header
359 - off int // offset for reading additional fields
360 -}
361 -
362 -func (m *message) len() uintptr {
363 - return uintptr(len(m.buf) - m.off)
364 -}
365 -
366 -func (m *message) data() unsafe.Pointer {
367 - var p unsafe.Pointer
368 - if m.off < len(m.buf) {
369 - p = unsafe.Pointer(&m.buf[m.off])
370 - }
371 - return p
372 -}
373 -
374 -func (m *message) bytes() []byte {
375 - return m.buf[m.off:]
376 -}
377 -
378 -func (m *message) Header() Header {
379 - h := m.hdr
380 - return Header{
381 - Conn: m.conn,
382 - ID: RequestID(h.Unique),
383 - Node: NodeID(h.Nodeid),
384 - Uid: h.Uid,
385 - Gid: h.Gid,
386 - Pid: h.Pid,
387 -
388 - msg: m,
389 - }
390 -}
391 -
392 -// fileMode returns a Go os.FileMode from a Unix mode.
393 -func fileMode(unixMode uint32) os.FileMode {
394 - mode := os.FileMode(unixMode & 0777)
395 - switch unixMode & syscall.S_IFMT {
396 - case syscall.S_IFREG:
397 - // nothing
398 - case syscall.S_IFDIR:
399 - mode |= os.ModeDir
400 - case syscall.S_IFCHR:
401 - mode |= os.ModeCharDevice | os.ModeDevice
402 - case syscall.S_IFBLK:
403 - mode |= os.ModeDevice
404 - case syscall.S_IFIFO:
405 - mode |= os.ModeNamedPipe
406 - case syscall.S_IFLNK:
407 - mode |= os.ModeSymlink
408 - case syscall.S_IFSOCK:
409 - mode |= os.ModeSocket
410 - default:
411 - // no idea
412 - mode |= os.ModeDevice
413 - }
414 - if unixMode&syscall.S_ISUID != 0 {
415 - mode |= os.ModeSetuid
416 - }
417 - if unixMode&syscall.S_ISGID != 0 {
418 - mode |= os.ModeSetgid
419 - }
420 - return mode
421 -}
422 -
423 -type noOpcode struct {
424 - Opcode uint32
425 -}
426 -
427 -func (m noOpcode) String() string {
428 - return fmt.Sprintf("No opcode %v", m.Opcode)
429 -}
430 -
431 -type malformedMessage struct {
432 -}
433 -
434 -func (malformedMessage) String() string {
435 - return "malformed message"
436 -}
437 -
438 -// Close closes the FUSE connection.
439 -func (c *Conn) Close() error {
440 - c.wio.Lock()
441 - defer c.wio.Unlock()
442 - c.rio.Lock()
443 - defer c.rio.Unlock()
444 - return c.dev.Close()
445 -}
446 -
447 -// caller must hold wio or rio
448 -func (c *Conn) fd() int {
449 - return int(c.dev.Fd())
450 -}
451 -
452 -// ReadRequest returns the next FUSE request from the kernel.
453 -//
454 -// Caller must call either Request.Respond or Request.RespondError in
455 -// a reasonable time. Caller must not retain Request after that call.
456 -func (c *Conn) ReadRequest() (Request, error) {
457 - m := getMessage(c)
458 -loop:
459 - c.rio.RLock()
460 - n, err := syscall.Read(c.fd(), m.buf)
461 - c.rio.RUnlock()
462 - if err == syscall.EINTR {
463 - // OSXFUSE sends EINTR to userspace when a request interrupt
464 - // completed before it got sent to userspace?
465 - goto loop
466 - }
467 - if err != nil && err != syscall.ENODEV {
468 - putMessage(m)
469 - return nil, err
470 - }
471 - if n <= 0 {
472 - putMessage(m)
473 - return nil, io.EOF
474 - }
475 - m.buf = m.buf[:n]
476 -
477 - if n < inHeaderSize {
478 - putMessage(m)
479 - return nil, errors.New("fuse: message too short")
480 - }
481 -
482 - // FreeBSD FUSE sends a short length in the header
483 - // for FUSE_INIT even though the actual read length is correct.
484 - if n == inHeaderSize+initInSize && m.hdr.Opcode == opInit && m.hdr.Len < uint32(n) {
485 - m.hdr.Len = uint32(n)
486 - }
487 -
488 - // OSXFUSE sometimes sends the wrong m.hdr.Len in a FUSE_WRITE message.
489 - if m.hdr.Len < uint32(n) && m.hdr.Len >= uint32(unsafe.Sizeof(writeIn{})) && m.hdr.Opcode == opWrite {
490 - m.hdr.Len = uint32(n)
491 - }
492 -
493 - if m.hdr.Len != uint32(n) {
494 - // prepare error message before returning m to pool
495 - err := fmt.Errorf("fuse: read %d opcode %d but expected %d", n, m.hdr.Opcode, m.hdr.Len)
496 - putMessage(m)
497 - return nil, err
498 - }
499 -
500 - m.off = inHeaderSize
501 -
502 - // Convert to data structures.
503 - // Do not trust kernel to hand us well-formed data.
504 - var req Request
505 - switch m.hdr.Opcode {
506 - default:
507 - Debug(noOpcode{Opcode: m.hdr.Opcode})
508 - goto unrecognized
509 -
510 - case opLookup:
511 - buf := m.bytes()
512 - n := len(buf)
513 - if n == 0 || buf[n-1] != '\x00' {
514 - goto corrupt
515 - }
516 - req = &LookupRequest{
517 - Header: m.Header(),
518 - Name: string(buf[:n-1]),
519 - }
520 -
521 - case opForget:
522 - in := (*forgetIn)(m.data())
523 - if m.len() < unsafe.Sizeof(*in) {
524 - goto corrupt
525 - }
526 - req = &ForgetRequest{
527 - Header: m.Header(),
528 - N: in.Nlookup,
529 - }
530 -
531 - case opGetattr:
532 - req = &GetattrRequest{
533 - Header: m.Header(),
534 - }
535 -
536 - case opSetattr:
537 - in := (*setattrIn)(m.data())
538 - if m.len() < unsafe.Sizeof(*in) {
539 - goto corrupt
540 - }
541 - req = &SetattrRequest{
542 - Header: m.Header(),
543 - Valid: SetattrValid(in.Valid),
544 - Handle: HandleID(in.Fh),
545 - Size: in.Size,
546 - Atime: time.Unix(int64(in.Atime), int64(in.AtimeNsec)),
547 - Mtime: time.Unix(int64(in.Mtime), int64(in.MtimeNsec)),
548 - Mode: fileMode(in.Mode),
549 - Uid: in.Uid,
550 - Gid: in.Gid,
551 - Bkuptime: in.BkupTime(),
552 - Chgtime: in.Chgtime(),
553 - Flags: in.Flags(),
554 - }
555 -
556 - case opReadlink:
557 - if len(m.bytes()) > 0 {
558 - goto corrupt
559 - }
560 - req = &ReadlinkRequest{
561 - Header: m.Header(),
562 - }
563 -
564 - case opSymlink:
565 - // m.bytes() is "newName\0target\0"
566 - names := m.bytes()
567 - if len(names) == 0 || names[len(names)-1] != 0 {
568 - goto corrupt
569 - }
570 - i := bytes.IndexByte(names, '\x00')
571 - if i < 0 {
572 - goto corrupt
573 - }
574 - newName, target := names[0:i], names[i+1:len(names)-1]
575 - req = &SymlinkRequest{
576 - Header: m.Header(),
577 - NewName: string(newName),
578 - Target: string(target),
579 - }
580 -
581 - case opLink:
582 - in := (*linkIn)(m.data())
583 - if m.len() < unsafe.Sizeof(*in) {
584 - goto corrupt
585 - }
586 - newName := m.bytes()[unsafe.Sizeof(*in):]
587 - if len(newName) < 2 || newName[len(newName)-1] != 0 {
588 - goto corrupt
589 - }
590 - newName = newName[:len(newName)-1]
591 - req = &LinkRequest{
592 - Header: m.Header(),
593 - OldNode: NodeID(in.Oldnodeid),
594 - NewName: string(newName),
595 - }
596 -
597 - case opMknod:
598 - in := (*mknodIn)(m.data())
599 - if m.len() < unsafe.Sizeof(*in) {
600 - goto corrupt
601 - }
602 - name := m.bytes()[unsafe.Sizeof(*in):]
603 - if len(name) < 2 || name[len(name)-1] != '\x00' {
604 - goto corrupt
605 - }
606 - name = name[:len(name)-1]
607 - req = &MknodRequest{
608 - Header: m.Header(),
609 - Mode: fileMode(in.Mode),
610 - Rdev: in.Rdev,
611 - Name: string(name),
612 - }
613 -
614 - case opMkdir:
615 - in := (*mkdirIn)(m.data())
616 - if m.len() < unsafe.Sizeof(*in) {
617 - goto corrupt
618 - }
619 - name := m.bytes()[unsafe.Sizeof(*in):]
620 - i := bytes.IndexByte(name, '\x00')
621 - if i < 0 {
622 - goto corrupt
623 - }
624 - req = &MkdirRequest{
625 - Header: m.Header(),
626 - Name: string(name[:i]),
627 - // observed on Linux: mkdirIn.Mode & syscall.S_IFMT == 0,
628 - // and this causes fileMode to go into it's "no idea"
629 - // code branch; enforce type to directory
630 - Mode: fileMode((in.Mode &^ syscall.S_IFMT) | syscall.S_IFDIR),
631 - }
632 -
633 - case opUnlink, opRmdir:
634 - buf := m.bytes()
635 - n := len(buf)
636 - if n == 0 || buf[n-1] != '\x00' {
637 - goto corrupt
638 - }
639 - req = &RemoveRequest{
640 - Header: m.Header(),
641 - Name: string(buf[:n-1]),
642 - Dir: m.hdr.Opcode == opRmdir,
643 - }
644 -
645 - case opRename:
646 - in := (*renameIn)(m.data())
647 - if m.len() < unsafe.Sizeof(*in) {
648 - goto corrupt
649 - }
650 - newDirNodeID := NodeID(in.Newdir)
651 - oldNew := m.bytes()[unsafe.Sizeof(*in):]
652 - // oldNew should be "old\x00new\x00"
653 - if len(oldNew) < 4 {
654 - goto corrupt
655 - }
656 - if oldNew[len(oldNew)-1] != '\x00' {
657 - goto corrupt
658 - }
659 - i := bytes.IndexByte(oldNew, '\x00')
660 - if i < 0 {
661 - goto corrupt
662 - }
663 - oldName, newName := string(oldNew[:i]), string(oldNew[i+1:len(oldNew)-1])
664 - req = &RenameRequest{
665 - Header: m.Header(),
666 - NewDir: newDirNodeID,
667 - OldName: oldName,
668 - NewName: newName,
669 - }
670 -
671 - case opOpendir, opOpen:
672 - in := (*openIn)(m.data())
673 - if m.len() < unsafe.Sizeof(*in) {
674 - goto corrupt
675 - }
676 - req = &OpenRequest{
677 - Header: m.Header(),
678 - Dir: m.hdr.Opcode == opOpendir,
679 - Flags: openFlags(in.Flags),
680 - }
681 -
682 - case opRead, opReaddir:
683 - in := (*readIn)(m.data())
684 - if m.len() < unsafe.Sizeof(*in) {
685 - goto corrupt
686 - }
687 - req = &ReadRequest{
688 - Header: m.Header(),
689 - Dir: m.hdr.Opcode == opReaddir,
690 - Handle: HandleID(in.Fh),
691 - Offset: int64(in.Offset),
692 - Size: int(in.Size),
693 - }
694 -
695 - case opWrite:
696 - in := (*writeIn)(m.data())
697 - if m.len() < unsafe.Sizeof(*in) {
698 - goto corrupt
699 - }
700 - r := &WriteRequest{
701 - Header: m.Header(),
702 - Handle: HandleID(in.Fh),
703 - Offset: int64(in.Offset),
704 - Flags: WriteFlags(in.WriteFlags),
705 - }
706 - buf := m.bytes()[unsafe.Sizeof(*in):]
707 - if uint32(len(buf)) < in.Size {
708 - goto corrupt
709 - }
710 - r.Data = buf
711 - req = r
712 -
713 - case opStatfs:
714 - req = &StatfsRequest{
715 - Header: m.Header(),
716 - }
717 -
718 - case opRelease, opReleasedir:
719 - in := (*releaseIn)(m.data())
720 - if m.len() < unsafe.Sizeof(*in) {
721 - goto corrupt
722 - }
723 - req = &ReleaseRequest{
724 - Header: m.Header(),
725 - Dir: m.hdr.Opcode == opReleasedir,
726 - Handle: HandleID(in.Fh),
727 - Flags: openFlags(in.Flags),
728 - ReleaseFlags: ReleaseFlags(in.ReleaseFlags),
729 - LockOwner: in.LockOwner,
730 - }
731 -
732 - case opFsync, opFsyncdir:
733 - in := (*fsyncIn)(m.data())
734 - if m.len() < unsafe.Sizeof(*in) {
735 - goto corrupt
736 - }
737 - req = &FsyncRequest{
738 - Dir: m.hdr.Opcode == opFsyncdir,
739 - Header: m.Header(),
740 - Handle: HandleID(in.Fh),
741 - Flags: in.FsyncFlags,
742 - }
743 -
744 - case opSetxattr:
745 - in := (*setxattrIn)(m.data())
746 - if m.len() < unsafe.Sizeof(*in) {
747 - goto corrupt
748 - }
749 - m.off += int(unsafe.Sizeof(*in))
750 - name := m.bytes()
751 - i := bytes.IndexByte(name, '\x00')
752 - if i < 0 {
753 - goto corrupt
754 - }
755 - xattr := name[i+1:]
756 - if uint32(len(xattr)) < in.Size {
757 - goto corrupt
758 - }
759 - xattr = xattr[:in.Size]
760 - req = &SetxattrRequest{
761 - Header: m.Header(),
762 - Flags: in.Flags,
763 - Position: in.position(),
764 - Name: string(name[:i]),
765 - Xattr: xattr,
766 - }
767 -
768 - case opGetxattr:
769 - in := (*getxattrIn)(m.data())
770 - if m.len() < unsafe.Sizeof(*in) {
771 - goto corrupt
772 - }
773 - name := m.bytes()[unsafe.Sizeof(*in):]
774 - i := bytes.IndexByte(name, '\x00')
775 - if i < 0 {
776 - goto corrupt
777 - }
778 - req = &GetxattrRequest{
779 - Header: m.Header(),
780 - Name: string(name[:i]),
781 - Size: in.Size,
782 - Position: in.position(),
783 - }
784 -
785 - case opListxattr:
786 - in := (*getxattrIn)(m.data())
787 - if m.len() < unsafe.Sizeof(*in) {
788 - goto corrupt
789 - }
790 - req = &ListxattrRequest{
791 - Header: m.Header(),
792 - Size: in.Size,
793 - Position: in.position(),
794 - }
795 -
796 - case opRemovexattr:
797 - buf := m.bytes()
798 - n := len(buf)
799 - if n == 0 || buf[n-1] != '\x00' {
800 - goto corrupt
801 - }
802 - req = &RemovexattrRequest{
803 - Header: m.Header(),
804 - Name: string(buf[:n-1]),
805 - }
806 -
807 - case opFlush:
808 - in := (*flushIn)(m.data())
809 - if m.len() < unsafe.Sizeof(*in) {
810 - goto corrupt
811 - }
812 - req = &FlushRequest{
813 - Header: m.Header(),
814 - Handle: HandleID(in.Fh),
815 - Flags: in.FlushFlags,
816 - LockOwner: in.LockOwner,
817 - }
818 -
819 - case opInit:
820 - in := (*initIn)(m.data())
821 - if m.len() < unsafe.Sizeof(*in) {
822 - goto corrupt
823 - }
824 - req = &InitRequest{
825 - Header: m.Header(),
826 - Major: in.Major,
827 - Minor: in.Minor,
828 - MaxReadahead: in.MaxReadahead,
829 - Flags: InitFlags(in.Flags),
830 - }
831 -
832 - case opGetlk:
833 - panic("opGetlk")
834 - case opSetlk:
835 - panic("opSetlk")
836 - case opSetlkw:
837 - panic("opSetlkw")
838 -
839 - case opAccess:
840 - in := (*accessIn)(m.data())
841 - if m.len() < unsafe.Sizeof(*in) {
842 - goto corrupt
843 - }
844 - req = &AccessRequest{
845 - Header: m.Header(),
846 - Mask: in.Mask,
847 - }
848 -
849 - case opCreate:
850 - in := (*createIn)(m.data())
851 - if m.len() < unsafe.Sizeof(*in) {
852 - goto corrupt
853 - }
854 - name := m.bytes()[unsafe.Sizeof(*in):]
855 - i := bytes.IndexByte(name, '\x00')
856 - if i < 0 {
857 - goto corrupt
858 - }
859 - req = &CreateRequest{
860 - Header: m.Header(),
861 - Flags: openFlags(in.Flags),
862 - Mode: fileMode(in.Mode),
863 - Name: string(name[:i]),
864 - }
865 -
866 - case opInterrupt:
867 - in := (*interruptIn)(m.data())
868 - if m.len() < unsafe.Sizeof(*in) {
869 - goto corrupt
870 - }
871 - req = &InterruptRequest{
872 - Header: m.Header(),
873 - IntrID: RequestID(in.Unique),
874 - }
875 -
876 - case opBmap:
877 - panic("opBmap")
878 -
879 - case opDestroy:
880 - req = &DestroyRequest{
881 - Header: m.Header(),
882 - }
883 -
884 - // OS X
885 - case opSetvolname:
886 - panic("opSetvolname")
887 - case opGetxtimes:
888 - panic("opGetxtimes")
889 - case opExchange:
890 - panic("opExchange")
891 - }
892 -
893 - return req, nil
894 -
895 -corrupt:
896 - Debug(malformedMessage{})
897 - putMessage(m)
898 - return nil, fmt.Errorf("fuse: malformed message")
899 -
900 -unrecognized:
901 - // Unrecognized message.
902 - // Assume higher-level code will send a "no idea what you mean" error.
903 - h := m.Header()
904 - return &h, nil
905 -}
906 -
907 -type bugShortKernelWrite struct {
908 - Written int64
909 - Length int64
910 - Error string
911 - Stack string
912 -}
913 -
914 -func (b bugShortKernelWrite) String() string {
915 - return fmt.Sprintf("short kernel write: written=%d/%d error=%q stack=\n%s", b.Written, b.Length, b.Error, b.Stack)
916 -}
917 -
918 -// safe to call even with nil error
919 -func errorString(err error) string {
920 - if err == nil {
921 - return ""
922 - }
923 - return err.Error()
924 -}
925 -
926 -func (c *Conn) respond(out *outHeader, n uintptr) {
927 - c.wio.Lock()
928 - defer c.wio.Unlock()
929 - out.Len = uint32(n)
930 - msg := (*[1 << 30]byte)(unsafe.Pointer(out))[:n]
931 - nn, err := syscall.Write(c.fd(), msg)
932 - if nn != len(msg) || err != nil {
933 - Debug(bugShortKernelWrite{
934 - Written: int64(nn),
935 - Length: int64(len(msg)),
936 - Error: errorString(err),
937 - Stack: stack(),
938 - })
939 - }
940 -}
941 -
942 -func (c *Conn) respondData(out *outHeader, n uintptr, data []byte) {
943 - c.wio.Lock()
944 - defer c.wio.Unlock()
945 - // TODO: use writev
946 - out.Len = uint32(n + uintptr(len(data)))
947 - msg := make([]byte, out.Len)
948 - copy(msg, (*[1 << 30]byte)(unsafe.Pointer(out))[:n])
949 - copy(msg[n:], data)
950 - syscall.Write(c.fd(), msg)
951 -}
952 -
953 -// An InitRequest is the first request sent on a FUSE file system.
954 -type InitRequest struct {
955 - Header `json:"-"`
956 - Major uint32
957 - Minor uint32
958 - // Maximum readahead in bytes that the kernel plans to use.
959 - MaxReadahead uint32
960 - Flags InitFlags
961 -}
962 -
963 -var _ = Request(&InitRequest{})
964 -
965 -func (r *InitRequest) String() string {
966 - return fmt.Sprintf("Init [%s] %d.%d ra=%d fl=%v", &r.Header, r.Major, r.Minor, r.MaxReadahead, r.Flags)
967 -}
968 -
969 -// An InitResponse is the response to an InitRequest.
970 -type InitResponse struct {
971 - // Maximum readahead in bytes that the kernel can use. Ignored if
972 - // greater than InitRequest.MaxReadahead.
973 - MaxReadahead uint32
974 - Flags InitFlags
975 - // Maximum size of a single write operation.
976 - // Linux enforces a minimum of 4 KiB.
977 - MaxWrite uint32
978 -}
979 -
980 -func (r *InitResponse) String() string {
981 - return fmt.Sprintf("Init %+v", *r)
982 -}
983 -
984 -// Respond replies to the request with the given response.
985 -func (r *InitRequest) Respond(resp *InitResponse) {
986 - out := &initOut{
987 - outHeader: outHeader{Unique: uint64(r.ID)},
988 - Major: kernelVersion,
989 - Minor: kernelMinorVersion,
990 - MaxReadahead: resp.MaxReadahead,
991 - Flags: uint32(resp.Flags),
992 - MaxWrite: resp.MaxWrite,
993 - }
994 - // MaxWrite larger than our receive buffer would just lead to
995 - // errors on large writes.
996 - if out.MaxWrite > maxWrite {
997 - out.MaxWrite = maxWrite
998 - }
999 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1000 -}
1001 -
1002 -// A StatfsRequest requests information about the mounted file system.
1003 -type StatfsRequest struct {
1004 - Header `json:"-"`
1005 -}
1006 -
1007 -var _ = Request(&StatfsRequest{})
1008 -
1009 -func (r *StatfsRequest) String() string {
1010 - return fmt.Sprintf("Statfs [%s]", &r.Header)
1011 -}
1012 -
1013 -// Respond replies to the request with the given response.
1014 -func (r *StatfsRequest) Respond(resp *StatfsResponse) {
1015 - out := &statfsOut{
1016 - outHeader: outHeader{Unique: uint64(r.ID)},
1017 - St: kstatfs{
1018 - Blocks: resp.Blocks,
1019 - Bfree: resp.Bfree,
1020 - Bavail: resp.Bavail,
1021 - Files: resp.Files,
1022 - Bsize: resp.Bsize,
1023 - Namelen: resp.Namelen,
1024 - Frsize: resp.Frsize,
1025 - },
1026 - }
1027 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1028 -}
1029 -
1030 -// A StatfsResponse is the response to a StatfsRequest.
1031 -type StatfsResponse struct {
1032 - Blocks uint64 // Total data blocks in file system.
1033 - Bfree uint64 // Free blocks in file system.
1034 - Bavail uint64 // Free blocks in file system if you're not root.
1035 - Files uint64 // Total files in file system.
1036 - Ffree uint64 // Free files in file system.
1037 - Bsize uint32 // Block size
1038 - Namelen uint32 // Maximum file name length?
1039 - Frsize uint32 // Fragment size, smallest addressable data size in the file system.
1040 -}
1041 -
1042 -func (r *StatfsResponse) String() string {
1043 - return fmt.Sprintf("Statfs %+v", *r)
1044 -}
1045 -
1046 -// An AccessRequest asks whether the file can be accessed
1047 -// for the purpose specified by the mask.
1048 -type AccessRequest struct {
1049 - Header `json:"-"`
1050 - Mask uint32
1051 -}
1052 -
1053 -var _ = Request(&AccessRequest{})
1054 -
1055 -func (r *AccessRequest) String() string {
1056 - return fmt.Sprintf("Access [%s] mask=%#x", &r.Header, r.Mask)
1057 -}
1058 -
1059 -// Respond replies to the request indicating that access is allowed.
1060 -// To deny access, use RespondError.
1061 -func (r *AccessRequest) Respond() {
1062 - out := &outHeader{Unique: uint64(r.ID)}
1063 - r.respond(out, unsafe.Sizeof(*out))
1064 -}
1065 -
1066 -// An Attr is the metadata for a single file or directory.
1067 -type Attr struct {
1068 - Valid time.Duration // how long Attr can be cached
1069 -
1070 - Inode uint64 // inode number
1071 - Size uint64 // size in bytes
1072 - Blocks uint64 // size in blocks
1073 - Atime time.Time // time of last access
1074 - Mtime time.Time // time of last modification
1075 - Ctime time.Time // time of last inode change
1076 - Crtime time.Time // time of creation (OS X only)
1077 - Mode os.FileMode // file mode
1078 - Nlink uint32 // number of links
1079 - Uid uint32 // owner uid
1080 - Gid uint32 // group gid
1081 - Rdev uint32 // device numbers
1082 - Flags uint32 // chflags(2) flags (OS X only)
1083 -}
1084 -
1085 -func unix(t time.Time) (sec uint64, nsec uint32) {
1086 - nano := t.UnixNano()
1087 - sec = uint64(nano / 1e9)
1088 - nsec = uint32(nano % 1e9)
1089 - return
1090 -}
1091 -
1092 -func (a *Attr) attr() (out attr) {
1093 - out.Ino = a.Inode
1094 - out.Size = a.Size
1095 - out.Blocks = a.Blocks
1096 - out.Atime, out.AtimeNsec = unix(a.Atime)
1097 - out.Mtime, out.MtimeNsec = unix(a.Mtime)
1098 - out.Ctime, out.CtimeNsec = unix(a.Ctime)
1099 - out.SetCrtime(unix(a.Crtime))
1100 - out.Mode = uint32(a.Mode) & 0777
1101 - switch {
1102 - default:
1103 - out.Mode |= syscall.S_IFREG
1104 - case a.Mode&os.ModeDir != 0:
1105 - out.Mode |= syscall.S_IFDIR
1106 - case a.Mode&os.ModeDevice != 0:
1107 - if a.Mode&os.ModeCharDevice != 0 {
1108 - out.Mode |= syscall.S_IFCHR
1109 - } else {
1110 - out.Mode |= syscall.S_IFBLK
1111 - }
1112 - case a.Mode&os.ModeNamedPipe != 0:
1113 - out.Mode |= syscall.S_IFIFO
1114 - case a.Mode&os.ModeSymlink != 0:
1115 - out.Mode |= syscall.S_IFLNK
1116 - case a.Mode&os.ModeSocket != 0:
1117 - out.Mode |= syscall.S_IFSOCK
1118 - }
1119 - if a.Mode&os.ModeSetuid != 0 {
1120 - out.Mode |= syscall.S_ISUID
1121 - }
1122 - if a.Mode&os.ModeSetgid != 0 {
1123 - out.Mode |= syscall.S_ISGID
1124 - }
1125 - out.Nlink = a.Nlink
1126 - out.Uid = a.Uid
1127 - out.Gid = a.Gid
1128 - out.Rdev = a.Rdev
1129 - out.SetFlags(a.Flags)
1130 -
1131 - return
1132 -}
1133 -
1134 -// A GetattrRequest asks for the metadata for the file denoted by r.Node.
1135 -type GetattrRequest struct {
1136 - Header `json:"-"`
1137 -}
1138 -
1139 -var _ = Request(&GetattrRequest{})
1140 -
1141 -func (r *GetattrRequest) String() string {
1142 - return fmt.Sprintf("Getattr [%s]", &r.Header)
1143 -}
1144 -
1145 -// Respond replies to the request with the given response.
1146 -func (r *GetattrRequest) Respond(resp *GetattrResponse) {
1147 - out := &attrOut{
1148 - outHeader: outHeader{Unique: uint64(r.ID)},
1149 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1150 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1151 - Attr: resp.Attr.attr(),
1152 - }
1153 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1154 -}
1155 -
1156 -// A GetattrResponse is the response to a GetattrRequest.
1157 -type GetattrResponse struct {
1158 - Attr Attr // file attributes
1159 -}
1160 -
1161 -func (r *GetattrResponse) String() string {
1162 - return fmt.Sprintf("Getattr %+v", *r)
1163 -}
1164 -
1165 -// A GetxattrRequest asks for the extended attributes associated with r.Node.
1166 -type GetxattrRequest struct {
1167 - Header `json:"-"`
1168 -
1169 - // Maximum size to return.
1170 - Size uint32
1171 -
1172 - // Name of the attribute requested.
1173 - Name string
1174 -
1175 - // Offset within extended attributes.
1176 - //
1177 - // Only valid for OS X, and then only with the resource fork
1178 - // attribute.
1179 - Position uint32
1180 -}
1181 -
1182 -var _ = Request(&GetxattrRequest{})
1183 -
1184 -func (r *GetxattrRequest) String() string {
1185 - return fmt.Sprintf("Getxattr [%s] %q %d @%d", &r.Header, r.Name, r.Size, r.Position)
1186 -}
1187 -
1188 -// Respond replies to the request with the given response.
1189 -func (r *GetxattrRequest) Respond(resp *GetxattrResponse) {
1190 - if r.Size == 0 {
1191 - out := &getxattrOut{
1192 - outHeader: outHeader{Unique: uint64(r.ID)},
1193 - Size: uint32(len(resp.Xattr)),
1194 - }
1195 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1196 - } else {
1197 - out := &outHeader{Unique: uint64(r.ID)}
1198 - r.respondData(out, unsafe.Sizeof(*out), resp.Xattr)
1199 - }
1200 -}
1201 -
1202 -// A GetxattrResponse is the response to a GetxattrRequest.
1203 -type GetxattrResponse struct {
1204 - Xattr []byte
1205 -}
1206 -
1207 -func (r *GetxattrResponse) String() string {
1208 - return fmt.Sprintf("Getxattr %x", r.Xattr)
1209 -}
1210 -
1211 -// A ListxattrRequest asks to list the extended attributes associated with r.Node.
1212 -type ListxattrRequest struct {
1213 - Header `json:"-"`
1214 - Size uint32 // maximum size to return
1215 - Position uint32 // offset within attribute list
1216 -}
1217 -
1218 -var _ = Request(&ListxattrRequest{})
1219 -
1220 -func (r *ListxattrRequest) String() string {
1221 - return fmt.Sprintf("Listxattr [%s] %d @%d", &r.Header, r.Size, r.Position)
1222 -}
1223 -
1224 -// Respond replies to the request with the given response.
1225 -func (r *ListxattrRequest) Respond(resp *ListxattrResponse) {
1226 - if r.Size == 0 {
1227 - out := &getxattrOut{
1228 - outHeader: outHeader{Unique: uint64(r.ID)},
1229 - Size: uint32(len(resp.Xattr)),
1230 - }
1231 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1232 - } else {
1233 - out := &outHeader{Unique: uint64(r.ID)}
1234 - r.respondData(out, unsafe.Sizeof(*out), resp.Xattr)
1235 - }
1236 -}
1237 -
1238 -// A ListxattrResponse is the response to a ListxattrRequest.
1239 -type ListxattrResponse struct {
1240 - Xattr []byte
1241 -}
1242 -
1243 -func (r *ListxattrResponse) String() string {
1244 - return fmt.Sprintf("Listxattr %x", r.Xattr)
1245 -}
1246 -
1247 -// Append adds an extended attribute name to the response.
1248 -func (r *ListxattrResponse) Append(names ...string) {
1249 - for _, name := range names {
1250 - r.Xattr = append(r.Xattr, name...)
1251 - r.Xattr = append(r.Xattr, '\x00')
1252 - }
1253 -}
1254 -
1255 -// A RemovexattrRequest asks to remove an extended attribute associated with r.Node.
1256 -type RemovexattrRequest struct {
1257 - Header `json:"-"`
1258 - Name string // name of extended attribute
1259 -}
1260 -
1261 -var _ = Request(&RemovexattrRequest{})
1262 -
1263 -func (r *RemovexattrRequest) String() string {
1264 - return fmt.Sprintf("Removexattr [%s] %q", &r.Header, r.Name)
1265 -}
1266 -
1267 -// Respond replies to the request, indicating that the attribute was removed.
1268 -func (r *RemovexattrRequest) Respond() {
1269 - out := &outHeader{Unique: uint64(r.ID)}
1270 - r.respond(out, unsafe.Sizeof(*out))
1271 -}
1272 -
1273 -// A SetxattrRequest asks to set an extended attribute associated with a file.
1274 -type SetxattrRequest struct {
1275 - Header `json:"-"`
1276 -
1277 - // Flags can make the request fail if attribute does/not already
1278 - // exist. Unfortunately, the constants are platform-specific and
1279 - // not exposed by Go1.2. Look for XATTR_CREATE, XATTR_REPLACE.
1280 - //
1281 - // TODO improve this later
1282 - //
1283 - // TODO XATTR_CREATE and exist -> EEXIST
1284 - //
1285 - // TODO XATTR_REPLACE and not exist -> ENODATA
1286 - Flags uint32
1287 -
1288 - // Offset within extended attributes.
1289 - //
1290 - // Only valid for OS X, and then only with the resource fork
1291 - // attribute.
1292 - Position uint32
1293 -
1294 - Name string
1295 - Xattr []byte
1296 -}
1297 -
1298 -var _ = Request(&SetxattrRequest{})
1299 -
1300 -func trunc(b []byte, max int) ([]byte, string) {
1301 - if len(b) > max {
1302 - return b[:max], "..."
1303 - }
1304 - return b, ""
1305 -}
1306 -
1307 -func (r *SetxattrRequest) String() string {
1308 - xattr, tail := trunc(r.Xattr, 16)
1309 - return fmt.Sprintf("Setxattr [%s] %q %x%s fl=%v @%#x", &r.Header, r.Name, xattr, tail, r.Flags, r.Position)
1310 -}
1311 -
1312 -// Respond replies to the request, indicating that the extended attribute was set.
1313 -func (r *SetxattrRequest) Respond() {
1314 - out := &outHeader{Unique: uint64(r.ID)}
1315 - r.respond(out, unsafe.Sizeof(*out))
1316 -}
1317 -
1318 -// A LookupRequest asks to look up the given name in the directory named by r.Node.
1319 -type LookupRequest struct {
1320 - Header `json:"-"`
1321 - Name string
1322 -}
1323 -
1324 -var _ = Request(&LookupRequest{})
1325 -
1326 -func (r *LookupRequest) String() string {
1327 - return fmt.Sprintf("Lookup [%s] %q", &r.Header, r.Name)
1328 -}
1329 -
1330 -// Respond replies to the request with the given response.
1331 -func (r *LookupRequest) Respond(resp *LookupResponse) {
1332 - out := &entryOut{
1333 - outHeader: outHeader{Unique: uint64(r.ID)},
1334 - Nodeid: uint64(resp.Node),
1335 - Generation: resp.Generation,
1336 - EntryValid: uint64(resp.EntryValid / time.Second),
1337 - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
1338 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1339 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1340 - Attr: resp.Attr.attr(),
1341 - }
1342 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1343 -}
1344 -
1345 -// A LookupResponse is the response to a LookupRequest.
1346 -type LookupResponse struct {
1347 - Node NodeID
1348 - Generation uint64
1349 - EntryValid time.Duration
1350 - Attr Attr
1351 -}
1352 -
1353 -func (r *LookupResponse) String() string {
1354 - return fmt.Sprintf("Lookup %+v", *r)
1355 -}
1356 -
1357 -// An OpenRequest asks to open a file or directory
1358 -type OpenRequest struct {
1359 - Header `json:"-"`
1360 - Dir bool // is this Opendir?
1361 - Flags OpenFlags
1362 -}
1363 -
1364 -var _ = Request(&OpenRequest{})
1365 -
1366 -func (r *OpenRequest) String() string {
1367 - return fmt.Sprintf("Open [%s] dir=%v fl=%v", &r.Header, r.Dir, r.Flags)
1368 -}
1369 -
1370 -// Respond replies to the request with the given response.
1371 -func (r *OpenRequest) Respond(resp *OpenResponse) {
1372 - out := &openOut{
1373 - outHeader: outHeader{Unique: uint64(r.ID)},
1374 - Fh: uint64(resp.Handle),
1375 - OpenFlags: uint32(resp.Flags),
1376 - }
1377 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1378 -}
1379 -
1380 -// A OpenResponse is the response to a OpenRequest.
1381 -type OpenResponse struct {
1382 - Handle HandleID
1383 - Flags OpenResponseFlags
1384 -}
1385 -
1386 -func (r *OpenResponse) String() string {
1387 - return fmt.Sprintf("Open %+v", *r)
1388 -}
1389 -
1390 -// A CreateRequest asks to create and open a file (not a directory).
1391 -type CreateRequest struct {
1392 - Header `json:"-"`
1393 - Name string
1394 - Flags OpenFlags
1395 - Mode os.FileMode
1396 -}
1397 -
1398 -var _ = Request(&CreateRequest{})
1399 -
1400 -func (r *CreateRequest) String() string {
1401 - return fmt.Sprintf("Create [%s] %q fl=%v mode=%v", &r.Header, r.Name, r.Flags, r.Mode)
1402 -}
1403 -
1404 -// Respond replies to the request with the given response.
1405 -func (r *CreateRequest) Respond(resp *CreateResponse) {
1406 - out := &createOut{
1407 - outHeader: outHeader{Unique: uint64(r.ID)},
1408 -
1409 - Nodeid: uint64(resp.Node),
1410 - Generation: resp.Generation,
1411 - EntryValid: uint64(resp.EntryValid / time.Second),
1412 - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
1413 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1414 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1415 - Attr: resp.Attr.attr(),
1416 -
1417 - Fh: uint64(resp.Handle),
1418 - OpenFlags: uint32(resp.Flags),
1419 - }
1420 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1421 -}
1422 -
1423 -// A CreateResponse is the response to a CreateRequest.
1424 -// It describes the created node and opened handle.
1425 -type CreateResponse struct {
1426 - LookupResponse
1427 - OpenResponse
1428 -}
1429 -
1430 -func (r *CreateResponse) String() string {
1431 - return fmt.Sprintf("Create %+v", *r)
1432 -}
1433 -
1434 -// A MkdirRequest asks to create (but not open) a directory.
1435 -type MkdirRequest struct {
1436 - Header `json:"-"`
1437 - Name string
1438 - Mode os.FileMode
1439 -}
1440 -
1441 -var _ = Request(&MkdirRequest{})
1442 -
1443 -func (r *MkdirRequest) String() string {
1444 - return fmt.Sprintf("Mkdir [%s] %q mode=%v", &r.Header, r.Name, r.Mode)
1445 -}
1446 -
1447 -// Respond replies to the request with the given response.
1448 -func (r *MkdirRequest) Respond(resp *MkdirResponse) {
1449 - out := &entryOut{
1450 - outHeader: outHeader{Unique: uint64(r.ID)},
1451 - Nodeid: uint64(resp.Node),
1452 - Generation: resp.Generation,
1453 - EntryValid: uint64(resp.EntryValid / time.Second),
1454 - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
1455 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1456 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1457 - Attr: resp.Attr.attr(),
1458 - }
1459 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1460 -}
1461 -
1462 -// A MkdirResponse is the response to a MkdirRequest.
1463 -type MkdirResponse struct {
1464 - LookupResponse
1465 -}
1466 -
1467 -func (r *MkdirResponse) String() string {
1468 - return fmt.Sprintf("Mkdir %+v", *r)
1469 -}
1470 -
1471 -// A ReadRequest asks to read from an open file.
1472 -type ReadRequest struct {
1473 - Header `json:"-"`
1474 - Dir bool // is this Readdir?
1475 - Handle HandleID
1476 - Offset int64
1477 - Size int
1478 -}
1479 -
1480 -var _ = Request(&ReadRequest{})
1481 -
1482 -func (r *ReadRequest) String() string {
1483 - return fmt.Sprintf("Read [%s] %#x %d @%#x dir=%v", &r.Header, r.Handle, r.Size, r.Offset, r.Dir)
1484 -}
1485 -
1486 -// Respond replies to the request with the given response.
1487 -func (r *ReadRequest) Respond(resp *ReadResponse) {
1488 - out := &outHeader{Unique: uint64(r.ID)}
1489 - r.respondData(out, unsafe.Sizeof(*out), resp.Data)
1490 -}
1491 -
1492 -// A ReadResponse is the response to a ReadRequest.
1493 -type ReadResponse struct {
1494 - Data []byte
1495 -}
1496 -
1497 -func (r *ReadResponse) String() string {
1498 - return fmt.Sprintf("Read %d", len(r.Data))
1499 -}
1500 -
1501 -type jsonReadResponse struct {
1502 - Len uint64
1503 -}
1504 -
1505 -func (r *ReadResponse) MarshalJSON() ([]byte, error) {
1506 - j := jsonReadResponse{
1507 - Len: uint64(len(r.Data)),
1508 - }
1509 - return json.Marshal(j)
1510 -}
1511 -
1512 -// A ReleaseRequest asks to release (close) an open file handle.
1513 -type ReleaseRequest struct {
1514 - Header `json:"-"`
1515 - Dir bool // is this Releasedir?
1516 - Handle HandleID
1517 - Flags OpenFlags // flags from OpenRequest
1518 - ReleaseFlags ReleaseFlags
1519 - LockOwner uint32
1520 -}
1521 -
1522 -var _ = Request(&ReleaseRequest{})
1523 -
1524 -func (r *ReleaseRequest) String() string {
1525 - return fmt.Sprintf("Release [%s] %#x fl=%v rfl=%v owner=%#x", &r.Header, r.Handle, r.Flags, r.ReleaseFlags, r.LockOwner)
1526 -}
1527 -
1528 -// Respond replies to the request, indicating that the handle has been released.
1529 -func (r *ReleaseRequest) Respond() {
1530 - out := &outHeader{Unique: uint64(r.ID)}
1531 - r.respond(out, unsafe.Sizeof(*out))
1532 -}
1533 -
1534 -// A DestroyRequest is sent by the kernel when unmounting the file system.
1535 -// No more requests will be received after this one, but it should still be
1536 -// responded to.
1537 -type DestroyRequest struct {
1538 - Header `json:"-"`
1539 -}
1540 -
1541 -var _ = Request(&DestroyRequest{})
1542 -
1543 -func (r *DestroyRequest) String() string {
1544 - return fmt.Sprintf("Destroy [%s]", &r.Header)
1545 -}
1546 -
1547 -// Respond replies to the request.
1548 -func (r *DestroyRequest) Respond() {
1549 - out := &outHeader{Unique: uint64(r.ID)}
1550 - r.respond(out, unsafe.Sizeof(*out))
1551 -}
1552 -
1553 -// A ForgetRequest is sent by the kernel when forgetting about r.Node
1554 -// as returned by r.N lookup requests.
1555 -type ForgetRequest struct {
1556 - Header `json:"-"`
1557 - N uint64
1558 -}
1559 -
1560 -var _ = Request(&ForgetRequest{})
1561 -
1562 -func (r *ForgetRequest) String() string {
1563 - return fmt.Sprintf("Forget [%s] %d", &r.Header, r.N)
1564 -}
1565 -
1566 -// Respond replies to the request, indicating that the forgetfulness has been recorded.
1567 -func (r *ForgetRequest) Respond() {
1568 - // Don't reply to forget messages.
1569 - r.noResponse()
1570 -}
1571 -
1572 -// A Dirent represents a single directory entry.
1573 -type Dirent struct {
1574 - // Inode this entry names.
1575 - Inode uint64
1576 -
1577 - // Type of the entry, for example DT_File.
1578 - //
1579 - // Setting this is optional. The zero value (DT_Unknown) means
1580 - // callers will just need to do a Getattr when the type is
1581 - // needed. Providing a type can speed up operations
1582 - // significantly.
1583 - Type DirentType
1584 -
1585 - // Name of the entry
1586 - Name string
1587 -}
1588 -
1589 -// Type of an entry in a directory listing.
1590 -type DirentType uint32
1591 -
1592 -const (
1593 - // These don't quite match os.FileMode; especially there's an
1594 - // explicit unknown, instead of zero value meaning file. They
1595 - // are also not quite syscall.DT_*; nothing says the FUSE
1596 - // protocol follows those, and even if they were, we don't
1597 - // want each fs to fiddle with syscall.
1598 -
1599 - // The shift by 12 is hardcoded in the FUSE userspace
1600 - // low-level C library, so it's safe here.
1601 -
1602 - DT_Unknown DirentType = 0
1603 - DT_Socket DirentType = syscall.S_IFSOCK >> 12
1604 - DT_Link DirentType = syscall.S_IFLNK >> 12
1605 - DT_File DirentType = syscall.S_IFREG >> 12
1606 - DT_Block DirentType = syscall.S_IFBLK >> 12
1607 - DT_Dir DirentType = syscall.S_IFDIR >> 12
1608 - DT_Char DirentType = syscall.S_IFCHR >> 12
1609 - DT_FIFO DirentType = syscall.S_IFIFO >> 12
1610 -)
1611 -
1612 -func (t DirentType) String() string {
1613 - switch t {
1614 - case DT_Unknown:
1615 - return "unknown"
1616 - case DT_Socket:
1617 - return "socket"
1618 - case DT_Link:
1619 - return "link"
1620 - case DT_File:
1621 - return "file"
1622 - case DT_Block:
1623 - return "block"
1624 - case DT_Dir:
1625 - return "dir"
1626 - case DT_Char:
1627 - return "char"
1628 - case DT_FIFO:
1629 - return "fifo"
1630 - }
1631 - return "invalid"
1632 -}
1633 -
1634 -// AppendDirent appends the encoded form of a directory entry to data
1635 -// and returns the resulting slice.
1636 -func AppendDirent(data []byte, dir Dirent) []byte {
1637 - de := dirent{
1638 - Ino: dir.Inode,
1639 - Namelen: uint32(len(dir.Name)),
1640 - Type: uint32(dir.Type),
1641 - }
1642 - de.Off = uint64(len(data) + direntSize + (len(dir.Name)+7)&^7)
1643 - data = append(data, (*[direntSize]byte)(unsafe.Pointer(&de))[:]...)
1644 - data = append(data, dir.Name...)
1645 - n := direntSize + uintptr(len(dir.Name))
1646 - if n%8 != 0 {
1647 - var pad [8]byte
1648 - data = append(data, pad[:8-n%8]...)
1649 - }
1650 - return data
1651 -}
1652 -
1653 -// A WriteRequest asks to write to an open file.
1654 -type WriteRequest struct {
1655 - Header
1656 - Handle HandleID
1657 - Offset int64
1658 - Data []byte
1659 - Flags WriteFlags
1660 -}
1661 -
1662 -var _ = Request(&WriteRequest{})
1663 -
1664 -func (r *WriteRequest) String() string {
1665 - return fmt.Sprintf("Write [%s] %#x %d @%d fl=%v", &r.Header, r.Handle, len(r.Data), r.Offset, r.Flags)
1666 -}
1667 -
1668 -type jsonWriteRequest struct {
1669 - Handle HandleID
1670 - Offset int64
1671 - Len uint64
1672 - Flags WriteFlags
1673 -}
1674 -
1675 -func (r *WriteRequest) MarshalJSON() ([]byte, error) {
1676 - j := jsonWriteRequest{
1677 - Handle: r.Handle,
1678 - Offset: r.Offset,
1679 - Len: uint64(len(r.Data)),
1680 - Flags: r.Flags,
1681 - }
1682 - return json.Marshal(j)
1683 -}
1684 -
1685 -// Respond replies to the request with the given response.
1686 -func (r *WriteRequest) Respond(resp *WriteResponse) {
1687 - out := &writeOut{
1688 - outHeader: outHeader{Unique: uint64(r.ID)},
1689 - Size: uint32(resp.Size),
1690 - }
1691 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1692 -}
1693 -
1694 -// A WriteResponse replies to a write indicating how many bytes were written.
1695 -type WriteResponse struct {
1696 - Size int
1697 -}
1698 -
1699 -func (r *WriteResponse) String() string {
1700 - return fmt.Sprintf("Write %+v", *r)
1701 -}
1702 -
1703 -// A SetattrRequest asks to change one or more attributes associated with a file,
1704 -// as indicated by Valid.
1705 -type SetattrRequest struct {
1706 - Header `json:"-"`
1707 - Valid SetattrValid
1708 - Handle HandleID
1709 - Size uint64
1710 - Atime time.Time
1711 - Mtime time.Time
1712 - Mode os.FileMode
1713 - Uid uint32
1714 - Gid uint32
1715 -
1716 - // OS X only
1717 - Bkuptime time.Time
1718 - Chgtime time.Time
1719 - Crtime time.Time
1720 - Flags uint32 // see chflags(2)
1721 -}
1722 -
1723 -var _ = Request(&SetattrRequest{})
1724 -
1725 -func (r *SetattrRequest) String() string {
1726 - var buf bytes.Buffer
1727 - fmt.Fprintf(&buf, "Setattr [%s]", &r.Header)
1728 - if r.Valid.Mode() {
1729 - fmt.Fprintf(&buf, " mode=%v", r.Mode)
1730 - }
1731 - if r.Valid.Uid() {
1732 - fmt.Fprintf(&buf, " uid=%d", r.Uid)
1733 - }
1734 - if r.Valid.Gid() {
1735 - fmt.Fprintf(&buf, " gid=%d", r.Gid)
1736 - }
1737 - if r.Valid.Size() {
1738 - fmt.Fprintf(&buf, " size=%d", r.Size)
1739 - }
1740 - if r.Valid.Atime() {
1741 - fmt.Fprintf(&buf, " atime=%v", r.Atime)
1742 - }
1743 - if r.Valid.AtimeNow() {
1744 - fmt.Fprintf(&buf, " atime=now")
1745 - }
1746 - if r.Valid.Mtime() {
1747 - fmt.Fprintf(&buf, " mtime=%v", r.Mtime)
1748 - }
1749 - if r.Valid.MtimeNow() {
1750 - fmt.Fprintf(&buf, " mtime=now")
1751 - }
1752 - if r.Valid.Handle() {
1753 - fmt.Fprintf(&buf, " handle=%#x", r.Handle)
1754 - } else {
1755 - fmt.Fprintf(&buf, " handle=INVALID-%#x", r.Handle)
1756 - }
1757 - if r.Valid.LockOwner() {
1758 - fmt.Fprintf(&buf, " lockowner")
1759 - }
1760 - if r.Valid.Crtime() {
1761 - fmt.Fprintf(&buf, " crtime=%v", r.Crtime)
1762 - }
1763 - if r.Valid.Chgtime() {
1764 - fmt.Fprintf(&buf, " chgtime=%v", r.Chgtime)
1765 - }
1766 - if r.Valid.Bkuptime() {
1767 - fmt.Fprintf(&buf, " bkuptime=%v", r.Bkuptime)
1768 - }
1769 - if r.Valid.Flags() {
1770 - fmt.Fprintf(&buf, " flags=%#x", r.Flags)
1771 - }
1772 - return buf.String()
1773 -}
1774 -
1775 -// Respond replies to the request with the given response,
1776 -// giving the updated attributes.
1777 -func (r *SetattrRequest) Respond(resp *SetattrResponse) {
1778 - out := &attrOut{
1779 - outHeader: outHeader{Unique: uint64(r.ID)},
1780 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1781 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1782 - Attr: resp.Attr.attr(),
1783 - }
1784 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1785 -}
1786 -
1787 -// A SetattrResponse is the response to a SetattrRequest.
1788 -type SetattrResponse struct {
1789 - Attr Attr // file attributes
1790 -}
1791 -
1792 -func (r *SetattrResponse) String() string {
1793 - return fmt.Sprintf("Setattr %+v", *r)
1794 -}
1795 -
1796 -// A FlushRequest asks for the current state of an open file to be flushed
1797 -// to storage, as when a file descriptor is being closed. A single opened Handle
1798 -// may receive multiple FlushRequests over its lifetime.
1799 -type FlushRequest struct {
1800 - Header `json:"-"`
1801 - Handle HandleID
1802 - Flags uint32
1803 - LockOwner uint64
1804 -}
1805 -
1806 -var _ = Request(&FlushRequest{})
1807 -
1808 -func (r *FlushRequest) String() string {
1809 - return fmt.Sprintf("Flush [%s] %#x fl=%#x lk=%#x", &r.Header, r.Handle, r.Flags, r.LockOwner)
1810 -}
1811 -
1812 -// Respond replies to the request, indicating that the flush succeeded.
1813 -func (r *FlushRequest) Respond() {
1814 - out := &outHeader{Unique: uint64(r.ID)}
1815 - r.respond(out, unsafe.Sizeof(*out))
1816 -}
1817 -
1818 -// A RemoveRequest asks to remove a file or directory from the
1819 -// directory r.Node.
1820 -type RemoveRequest struct {
1821 - Header `json:"-"`
1822 - Name string // name of the entry to remove
1823 - Dir bool // is this rmdir?
1824 -}
1825 -
1826 -var _ = Request(&RemoveRequest{})
1827 -
1828 -func (r *RemoveRequest) String() string {
1829 - return fmt.Sprintf("Remove [%s] %q dir=%v", &r.Header, r.Name, r.Dir)
1830 -}
1831 -
1832 -// Respond replies to the request, indicating that the file was removed.
1833 -func (r *RemoveRequest) Respond() {
1834 - out := &outHeader{Unique: uint64(r.ID)}
1835 - r.respond(out, unsafe.Sizeof(*out))
1836 -}
1837 -
1838 -// A SymlinkRequest is a request to create a symlink making NewName point to Target.
1839 -type SymlinkRequest struct {
1840 - Header `json:"-"`
1841 - NewName, Target string
1842 -}
1843 -
1844 -var _ = Request(&SymlinkRequest{})
1845 -
1846 -func (r *SymlinkRequest) String() string {
1847 - return fmt.Sprintf("Symlink [%s] from %q to target %q", &r.Header, r.NewName, r.Target)
1848 -}
1849 -
1850 -// Respond replies to the request, indicating that the symlink was created.
1851 -func (r *SymlinkRequest) Respond(resp *SymlinkResponse) {
1852 - out := &entryOut{
1853 - outHeader: outHeader{Unique: uint64(r.ID)},
1854 - Nodeid: uint64(resp.Node),
1855 - Generation: resp.Generation,
1856 - EntryValid: uint64(resp.EntryValid / time.Second),
1857 - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
1858 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1859 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1860 - Attr: resp.Attr.attr(),
1861 - }
1862 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1863 -}
1864 -
1865 -// A SymlinkResponse is the response to a SymlinkRequest.
1866 -type SymlinkResponse struct {
1867 - LookupResponse
1868 -}
1869 -
1870 -// A ReadlinkRequest is a request to read a symlink's target.
1871 -type ReadlinkRequest struct {
1872 - Header `json:"-"`
1873 -}
1874 -
1875 -var _ = Request(&ReadlinkRequest{})
1876 -
1877 -func (r *ReadlinkRequest) String() string {
1878 - return fmt.Sprintf("Readlink [%s]", &r.Header)
1879 -}
1880 -
1881 -func (r *ReadlinkRequest) Respond(target string) {
1882 - out := &outHeader{Unique: uint64(r.ID)}
1883 - r.respondData(out, unsafe.Sizeof(*out), []byte(target))
1884 -}
1885 -
1886 -// A LinkRequest is a request to create a hard link.
1887 -type LinkRequest struct {
1888 - Header `json:"-"`
1889 - OldNode NodeID
1890 - NewName string
1891 -}
1892 -
1893 -var _ = Request(&LinkRequest{})
1894 -
1895 -func (r *LinkRequest) String() string {
1896 - return fmt.Sprintf("Link [%s] node %d to %q", &r.Header, r.OldNode, r.NewName)
1897 -}
1898 -
1899 -func (r *LinkRequest) Respond(resp *LookupResponse) {
1900 - out := &entryOut{
1901 - outHeader: outHeader{Unique: uint64(r.ID)},
1902 - Nodeid: uint64(resp.Node),
1903 - Generation: resp.Generation,
1904 - EntryValid: uint64(resp.EntryValid / time.Second),
1905 - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
1906 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1907 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1908 - Attr: resp.Attr.attr(),
1909 - }
1910 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1911 -}
1912 -
1913 -// A RenameRequest is a request to rename a file.
1914 -type RenameRequest struct {
1915 - Header `json:"-"`
1916 - NewDir NodeID
1917 - OldName, NewName string
1918 -}
1919 -
1920 -var _ = Request(&RenameRequest{})
1921 -
1922 -func (r *RenameRequest) String() string {
1923 - return fmt.Sprintf("Rename [%s] from %q to dirnode %d %q", &r.Header, r.OldName, r.NewDir, r.NewName)
1924 -}
1925 -
1926 -func (r *RenameRequest) Respond() {
1927 - out := &outHeader{Unique: uint64(r.ID)}
1928 - r.respond(out, unsafe.Sizeof(*out))
1929 -}
1930 -
1931 -type MknodRequest struct {
1932 - Header `json:"-"`
1933 - Name string
1934 - Mode os.FileMode
1935 - Rdev uint32
1936 -}
1937 -
1938 -var _ = Request(&MknodRequest{})
1939 -
1940 -func (r *MknodRequest) String() string {
1941 - return fmt.Sprintf("Mknod [%s] Name %q mode %v rdev %d", &r.Header, r.Name, r.Mode, r.Rdev)
1942 -}
1943 -
1944 -func (r *MknodRequest) Respond(resp *LookupResponse) {
1945 - out := &entryOut{
1946 - outHeader: outHeader{Unique: uint64(r.ID)},
1947 - Nodeid: uint64(resp.Node),
1948 - Generation: resp.Generation,
1949 - EntryValid: uint64(resp.EntryValid / time.Second),
1950 - EntryValidNsec: uint32(resp.EntryValid % time.Second / time.Nanosecond),
1951 - AttrValid: uint64(resp.Attr.Valid / time.Second),
1952 - AttrValidNsec: uint32(resp.Attr.Valid % time.Second / time.Nanosecond),
1953 - Attr: resp.Attr.attr(),
1954 - }
1955 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
1956 -}
1957 -
1958 -type FsyncRequest struct {
1959 - Header `json:"-"`
1960 - Handle HandleID
1961 - // TODO bit 1 is datasync, not well documented upstream
1962 - Flags uint32
1963 - Dir bool
1964 -}
1965 -
1966 -var _ = Request(&FsyncRequest{})
1967 -
1968 -func (r *FsyncRequest) String() string {
1969 - return fmt.Sprintf("Fsync [%s] Handle %v Flags %v", &r.Header, r.Handle, r.Flags)
1970 -}
1971 -
1972 -func (r *FsyncRequest) Respond() {
1973 - out := &outHeader{Unique: uint64(r.ID)}
1974 - r.respond(out, unsafe.Sizeof(*out))
1975 -}
1976 -
1977 -// An InterruptRequest is a request to interrupt another pending request. The
1978 -// response to that request should return an error status of EINTR.
1979 -type InterruptRequest struct {
1980 - Header `json:"-"`
1981 - IntrID RequestID // ID of the request to be interrupt.
1982 -}
1983 -
1984 -var _ = Request(&InterruptRequest{})
1985 -
1986 -func (r *InterruptRequest) Respond() {
1987 - // nothing to do here
1988 - r.noResponse()
1989 -}
1990 -
1991 -func (r *InterruptRequest) String() string {
1992 - return fmt.Sprintf("Interrupt [%s] ID %v", &r.Header, r.IntrID)
1993 -}
1994 -
1995 -/*{
1996 -
1997 -// A XXXRequest xxx.
1998 -type XXXRequest struct {
1999 - Header `json:"-"`
2000 - xxx
2001 -}
2002 -
2003 -var _ = Request(&XXXRequest{})
2004 -
2005 -func (r *XXXRequest) String() string {
2006 - return fmt.Sprintf("XXX [%s] xxx", &r.Header)
2007 -}
2008 -
2009 -// Respond replies to the request with the given response.
2010 -func (r *XXXRequest) Respond(resp *XXXResponse) {
2011 - out := &xxxOut{
2012 - outHeader: outHeader{Unique: uint64(r.ID)},
2013 - xxx,
2014 - }
2015 - r.respond(&out.outHeader, unsafe.Sizeof(*out))
2016 -}
2017 -
2018 -// A XXXResponse is the response to a XXXRequest.
2019 -type XXXResponse struct {
2020 - xxx
2021 -}
2022 -
2023 -func (r *XXXResponse) String() string {
2024 - return fmt.Sprintf("XXX %+v", *r)
2025 -}
2026 -
2027 - }
2028 -*/
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel.go deleted
-639
@@ -1,639 +0,0 @@
1 -// See the file LICENSE for copyright and licensing information.
2 -
3 -// Derived from FUSE's fuse_kernel.h, which carries this notice:
4 -/*
5 - This file defines the kernel interface of FUSE
6 - Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
7 -
8 -
9 - This -- and only this -- header file may also be distributed under
10 - the terms of the BSD Licence as follows:
11 -
12 - Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
13 -
14 - Redistribution and use in source and binary forms, with or without
15 - modification, are permitted provided that the following conditions
16 - are met:
17 - 1. Redistributions of source code must retain the above copyright
18 - notice, this list of conditions and the following disclaimer.
19 - 2. Redistributions in binary form must reproduce the above copyright
20 - notice, this list of conditions and the following disclaimer in the
21 - documentation and/or other materials provided with the distribution.
22 -
23 - THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 - ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
27 - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 - SUCH DAMAGE.
34 -*/
35 -
36 -package fuse
37 -
38 -import (
39 - "fmt"
40 - "syscall"
41 - "unsafe"
42 -)
43 -
44 -// Version is the FUSE version implemented by the package.
45 -const Version = "7.8"
46 -
47 -const (
48 - kernelVersion = 7
49 - kernelMinorVersion = 8
50 - rootID = 1
51 -)
52 -
53 -type kstatfs struct {
54 - Blocks uint64
55 - Bfree uint64
56 - Bavail uint64
57 - Files uint64
58 - Ffree uint64
59 - Bsize uint32
60 - Namelen uint32
61 - Frsize uint32
62 - Padding uint32
63 - Spare [6]uint32
64 -}
65 -
66 -type fileLock struct {
67 - Start uint64
68 - End uint64
69 - Type uint32
70 - Pid uint32
71 -}
72 -
73 -// The SetattrValid are bit flags describing which fields in the SetattrRequest
74 -// are included in the change.
75 -type SetattrValid uint32
76 -
77 -const (
78 - SetattrMode SetattrValid = 1 << 0
79 - SetattrUid SetattrValid = 1 << 1
80 - SetattrGid SetattrValid = 1 << 2
81 - SetattrSize SetattrValid = 1 << 3
82 - SetattrAtime SetattrValid = 1 << 4
83 - SetattrMtime SetattrValid = 1 << 5
84 - SetattrHandle SetattrValid = 1 << 6
85 -
86 - // Linux only(?)
87 - SetattrAtimeNow SetattrValid = 1 << 7
88 - SetattrMtimeNow SetattrValid = 1 << 8
89 - SetattrLockOwner SetattrValid = 1 << 9 // http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg27852.html
90 -
91 - // OS X only
92 - SetattrCrtime SetattrValid = 1 << 28
93 - SetattrChgtime SetattrValid = 1 << 29
94 - SetattrBkuptime SetattrValid = 1 << 30
95 - SetattrFlags SetattrValid = 1 << 31
96 -)
97 -
98 -func (fl SetattrValid) Mode() bool { return fl&SetattrMode != 0 }
99 -func (fl SetattrValid) Uid() bool { return fl&SetattrUid != 0 }
100 -func (fl SetattrValid) Gid() bool { return fl&SetattrGid != 0 }
101 -func (fl SetattrValid) Size() bool { return fl&SetattrSize != 0 }
102 -func (fl SetattrValid) Atime() bool { return fl&SetattrAtime != 0 }
103 -func (fl SetattrValid) Mtime() bool { return fl&SetattrMtime != 0 }
104 -func (fl SetattrValid) Handle() bool { return fl&SetattrHandle != 0 }
105 -func (fl SetattrValid) AtimeNow() bool { return fl&SetattrAtimeNow != 0 }
106 -func (fl SetattrValid) MtimeNow() bool { return fl&SetattrMtimeNow != 0 }
107 -func (fl SetattrValid) LockOwner() bool { return fl&SetattrLockOwner != 0 }
108 -func (fl SetattrValid) Crtime() bool { return fl&SetattrCrtime != 0 }
109 -func (fl SetattrValid) Chgtime() bool { return fl&SetattrChgtime != 0 }
110 -func (fl SetattrValid) Bkuptime() bool { return fl&SetattrBkuptime != 0 }
111 -func (fl SetattrValid) Flags() bool { return fl&SetattrFlags != 0 }
112 -
113 -func (fl SetattrValid) String() string {
114 - return flagString(uint32(fl), setattrValidNames)
115 -}
116 -
117 -var setattrValidNames = []flagName{
118 - {uint32(SetattrMode), "SetattrMode"},
119 - {uint32(SetattrUid), "SetattrUid"},
120 - {uint32(SetattrGid), "SetattrGid"},
121 - {uint32(SetattrSize), "SetattrSize"},
122 - {uint32(SetattrAtime), "SetattrAtime"},
123 - {uint32(SetattrMtime), "SetattrMtime"},
124 - {uint32(SetattrHandle), "SetattrHandle"},
125 - {uint32(SetattrAtimeNow), "SetattrAtimeNow"},
126 - {uint32(SetattrMtimeNow), "SetattrMtimeNow"},
127 - {uint32(SetattrLockOwner), "SetattrLockOwner"},
128 - {uint32(SetattrCrtime), "SetattrCrtime"},
129 - {uint32(SetattrChgtime), "SetattrChgtime"},
130 - {uint32(SetattrBkuptime), "SetattrBkuptime"},
131 - {uint32(SetattrFlags), "SetattrFlags"},
132 -}
133 -
134 -// Flags that can be seen in OpenRequest.Flags.
135 -const (
136 - // Access modes. These are not 1-bit flags, but alternatives where
137 - // only one can be chosen. See the IsReadOnly etc convenience
138 - // methods.
139 - OpenReadOnly OpenFlags = syscall.O_RDONLY
140 - OpenWriteOnly OpenFlags = syscall.O_WRONLY
141 - OpenReadWrite OpenFlags = syscall.O_RDWR
142 -
143 - OpenAppend OpenFlags = syscall.O_APPEND
144 - OpenCreate OpenFlags = syscall.O_CREAT
145 - OpenExclusive OpenFlags = syscall.O_EXCL
146 - OpenSync OpenFlags = syscall.O_SYNC
147 - OpenTruncate OpenFlags = syscall.O_TRUNC
148 -)
149 -
150 -// OpenAccessModeMask is a bitmask that separates the access mode
151 -// from the other flags in OpenFlags.
152 -const OpenAccessModeMask OpenFlags = syscall.O_ACCMODE
153 -
154 -// OpenFlags are the O_FOO flags passed to open/create/etc calls. For
155 -// example, os.O_WRONLY | os.O_APPEND.
156 -type OpenFlags uint32
157 -
158 -func (fl OpenFlags) String() string {
159 - // O_RDONLY, O_RWONLY, O_RDWR are not flags
160 - s := accModeName(fl & OpenAccessModeMask)
161 - flags := uint32(fl &^ OpenAccessModeMask)
162 - if flags != 0 {
163 - s = s + "+" + flagString(flags, openFlagNames)
164 - }
165 - return s
166 -}
167 -
168 -// Return true if OpenReadOnly is set.
169 -func (fl OpenFlags) IsReadOnly() bool {
170 - return fl&OpenAccessModeMask == OpenReadOnly
171 -}
172 -
173 -// Return true if OpenWriteOnly is set.
174 -func (fl OpenFlags) IsWriteOnly() bool {
175 - return fl&OpenAccessModeMask == OpenWriteOnly
176 -}
177 -
178 -// Return true if OpenReadWrite is set.
179 -func (fl OpenFlags) IsReadWrite() bool {
180 - return fl&OpenAccessModeMask == OpenReadWrite
181 -}
182 -
183 -func accModeName(flags OpenFlags) string {
184 - switch flags {
185 - case OpenReadOnly:
186 - return "OpenReadOnly"
187 - case OpenWriteOnly:
188 - return "OpenWriteOnly"
189 - case OpenReadWrite:
190 - return "OpenReadWrite"
191 - default:
192 - return ""
193 - }
194 -}
195 -
196 -var openFlagNames = []flagName{
197 - {uint32(OpenCreate), "OpenCreate"},
198 - {uint32(OpenExclusive), "OpenExclusive"},
199 - {uint32(OpenTruncate), "OpenTruncate"},
200 - {uint32(OpenAppend), "OpenAppend"},
201 - {uint32(OpenSync), "OpenSync"},
202 -}
203 -
204 -// The OpenResponseFlags are returned in the OpenResponse.
205 -type OpenResponseFlags uint32
206 -
207 -const (
208 - OpenDirectIO OpenResponseFlags = 1 << 0 // bypass page cache for this open file
209 - OpenKeepCache OpenResponseFlags = 1 << 1 // don't invalidate the data cache on open
210 - OpenNonSeekable OpenResponseFlags = 1 << 2 // (Linux?)
211 -
212 - OpenPurgeAttr OpenResponseFlags = 1 << 30 // OS X
213 - OpenPurgeUBC OpenResponseFlags = 1 << 31 // OS X
214 -)
215 -
216 -func (fl OpenResponseFlags) String() string {
217 - return flagString(uint32(fl), openResponseFlagNames)
218 -}
219 -
220 -var openResponseFlagNames = []flagName{
221 - {uint32(OpenDirectIO), "OpenDirectIO"},
222 - {uint32(OpenKeepCache), "OpenKeepCache"},
223 - {uint32(OpenPurgeAttr), "OpenPurgeAttr"},
224 - {uint32(OpenPurgeUBC), "OpenPurgeUBC"},
225 -}
226 -
227 -// The InitFlags are used in the Init exchange.
228 -type InitFlags uint32
229 -
230 -const (
231 - InitAsyncRead InitFlags = 1 << 0
232 - InitPosixLocks InitFlags = 1 << 1
233 - InitFileOps InitFlags = 1 << 2
234 - InitAtomicTrunc InitFlags = 1 << 3
235 - InitExportSupport InitFlags = 1 << 4
236 - InitBigWrites InitFlags = 1 << 5
237 - InitDontMask InitFlags = 1 << 6
238 - InitSpliceWrite InitFlags = 1 << 7
239 - InitSpliceMove InitFlags = 1 << 8
240 - InitSpliceRead InitFlags = 1 << 9
241 - InitFlockLocks InitFlags = 1 << 10
242 - InitHasIoctlDir InitFlags = 1 << 11
243 - InitAutoInvalData InitFlags = 1 << 12
244 - InitDoReaddirplus InitFlags = 1 << 13
245 - InitReaddirplusAuto InitFlags = 1 << 14
246 - InitAsyncDIO InitFlags = 1 << 15
247 - InitWritebackCache InitFlags = 1 << 16
248 - InitNoOpenSupport InitFlags = 1 << 17
249 -
250 - InitCaseSensitive InitFlags = 1 << 29 // OS X only
251 - InitVolRename InitFlags = 1 << 30 // OS X only
252 - InitXtimes InitFlags = 1 << 31 // OS X only
253 -)
254 -
255 -type flagName struct {
256 - bit uint32
257 - name string
258 -}
259 -
260 -var initFlagNames = []flagName{
261 - {uint32(InitAsyncRead), "InitAsyncRead"},
262 - {uint32(InitPosixLocks), "InitPosixLocks"},
263 - {uint32(InitFileOps), "InitFileOps"},
264 - {uint32(InitAtomicTrunc), "InitAtomicTrunc"},
265 - {uint32(InitExportSupport), "InitExportSupport"},
266 - {uint32(InitBigWrites), "InitBigWrites"},
267 - {uint32(InitDontMask), "InitDontMask"},
268 - {uint32(InitSpliceWrite), "InitSpliceWrite"},
269 - {uint32(InitSpliceMove), "InitSpliceMove"},
270 - {uint32(InitSpliceRead), "InitSpliceRead"},
271 - {uint32(InitFlockLocks), "InitFlockLocks"},
272 - {uint32(InitHasIoctlDir), "InitHasIoctlDir"},
273 - {uint32(InitAutoInvalData), "InitAutoInvalData"},
274 - {uint32(InitDoReaddirplus), "InitDoReaddirplus"},
275 - {uint32(InitReaddirplusAuto), "InitReaddirplusAuto"},
276 - {uint32(InitAsyncDIO), "InitAsyncDIO"},
277 - {uint32(InitWritebackCache), "InitWritebackCache"},
278 - {uint32(InitNoOpenSupport), "InitNoOpenSupport"},
279 -
280 - {uint32(InitCaseSensitive), "InitCaseSensitive"},
281 - {uint32(InitVolRename), "InitVolRename"},
282 - {uint32(InitXtimes), "InitXtimes"},
283 -}
284 -
285 -func (fl InitFlags) String() string {
286 - return flagString(uint32(fl), initFlagNames)
287 -}
288 -
289 -func flagString(f uint32, names []flagName) string {
290 - var s string
291 -
292 - if f == 0 {
293 - return "0"
294 - }
295 -
296 - for _, n := range names {
297 - if f&n.bit != 0 {
298 - s += "+" + n.name
299 - f &^= n.bit
300 - }
301 - }
302 - if f != 0 {
303 - s += fmt.Sprintf("%+#x", f)
304 - }
305 - return s[1:]
306 -}
307 -
308 -// The ReleaseFlags are used in the Release exchange.
309 -type ReleaseFlags uint32
310 -
311 -const (
312 - ReleaseFlush ReleaseFlags = 1 << 0
313 -)
314 -
315 -func (fl ReleaseFlags) String() string {
316 - return flagString(uint32(fl), releaseFlagNames)
317 -}
318 -
319 -var releaseFlagNames = []flagName{
320 - {uint32(ReleaseFlush), "ReleaseFlush"},
321 -}
322 -
323 -// Opcodes
324 -const (
325 - opLookup = 1
326 - opForget = 2 // no reply
327 - opGetattr = 3
328 - opSetattr = 4
329 - opReadlink = 5
330 - opSymlink = 6
331 - opMknod = 8
332 - opMkdir = 9
333 - opUnlink = 10
334 - opRmdir = 11
335 - opRename = 12
336 - opLink = 13
337 - opOpen = 14
338 - opRead = 15
339 - opWrite = 16
340 - opStatfs = 17
341 - opRelease = 18
342 - opFsync = 20
343 - opSetxattr = 21
344 - opGetxattr = 22
345 - opListxattr = 23
346 - opRemovexattr = 24
347 - opFlush = 25
348 - opInit = 26
349 - opOpendir = 27
350 - opReaddir = 28
351 - opReleasedir = 29
352 - opFsyncdir = 30
353 - opGetlk = 31
354 - opSetlk = 32
355 - opSetlkw = 33
356 - opAccess = 34
357 - opCreate = 35
358 - opInterrupt = 36
359 - opBmap = 37
360 - opDestroy = 38
361 - opIoctl = 39 // Linux?
362 - opPoll = 40 // Linux?
363 -
364 - // OS X
365 - opSetvolname = 61
366 - opGetxtimes = 62
367 - opExchange = 63
368 -)
369 -
370 -type entryOut struct {
371 - outHeader
372 - Nodeid uint64 // Inode ID
373 - Generation uint64 // Inode generation
374 - EntryValid uint64 // Cache timeout for the name
375 - AttrValid uint64 // Cache timeout for the attributes
376 - EntryValidNsec uint32
377 - AttrValidNsec uint32
378 - Attr attr
379 -}
380 -
381 -type forgetIn struct {
382 - Nlookup uint64
383 -}
384 -
385 -type attrOut struct {
386 - outHeader
387 - AttrValid uint64 // Cache timeout for the attributes
388 - AttrValidNsec uint32
389 - Dummy uint32
390 - Attr attr
391 -}
392 -
393 -// OS X
394 -type getxtimesOut struct {
395 - outHeader
396 - Bkuptime uint64
397 - Crtime uint64
398 - BkuptimeNsec uint32
399 - CrtimeNsec uint32
400 -}
401 -
402 -type mknodIn struct {
403 - Mode uint32
404 - Rdev uint32
405 - // "filename\x00" follows.
406 -}
407 -
408 -type mkdirIn struct {
409 - Mode uint32
410 - Padding uint32
411 - // filename follows
412 -}
413 -
414 -type renameIn struct {
415 - Newdir uint64
416 - // "oldname\x00newname\x00" follows
417 -}
418 -
419 -// OS X
420 -type exchangeIn struct {
421 - Olddir uint64
422 - Newdir uint64
423 - Options uint64
424 -}
425 -
426 -type linkIn struct {
427 - Oldnodeid uint64
428 -}
429 -
430 -type setattrInCommon struct {
431 - Valid uint32
432 - Padding uint32
433 - Fh uint64
434 - Size uint64
435 - LockOwner uint64 // unused on OS X?
436 - Atime uint64
437 - Mtime uint64
438 - Unused2 uint64
439 - AtimeNsec uint32
440 - MtimeNsec uint32
441 - Unused3 uint32
442 - Mode uint32
443 - Unused4 uint32
444 - Uid uint32
445 - Gid uint32
446 - Unused5 uint32
447 -}
448 -
449 -type openIn struct {
450 - Flags uint32
451 - Unused uint32
452 -}
453 -
454 -type openOut struct {
455 - outHeader
456 - Fh uint64
457 - OpenFlags uint32
458 - Padding uint32
459 -}
460 -
461 -type createIn struct {
462 - Flags uint32
463 - Mode uint32
464 -}
465 -
466 -type createOut struct {
467 - outHeader
468 -
469 - Nodeid uint64 // Inode ID
470 - Generation uint64 // Inode generation
471 - EntryValid uint64 // Cache timeout for the name
472 - AttrValid uint64 // Cache timeout for the attributes
473 - EntryValidNsec uint32
474 - AttrValidNsec uint32
475 - Attr attr
476 -
477 - Fh uint64
478 - OpenFlags uint32
479 - Padding uint32
480 -}
481 -
482 -type releaseIn struct {
483 - Fh uint64
484 - Flags uint32
485 - ReleaseFlags uint32
486 - LockOwner uint32
487 -}
488 -
489 -type flushIn struct {
490 - Fh uint64
491 - FlushFlags uint32
492 - Padding uint32
493 - LockOwner uint64
494 -}
495 -
496 -type readIn struct {
497 - Fh uint64
498 - Offset uint64
499 - Size uint32
500 - Padding uint32
501 -}
502 -
503 -type writeIn struct {
504 - Fh uint64
505 - Offset uint64
506 - Size uint32
507 - WriteFlags uint32
508 -}
509 -
510 -type writeOut struct {
511 - outHeader
512 - Size uint32
513 - Padding uint32
514 -}
515 -
516 -// The WriteFlags are passed in WriteRequest.
517 -type WriteFlags uint32
518 -
519 -func (fl WriteFlags) String() string {
520 - return flagString(uint32(fl), writeFlagNames)
521 -}
522 -
523 -var writeFlagNames = []flagName{}
524 -
525 -const compatStatfsSize = 48
526 -
527 -type statfsOut struct {
528 - outHeader
529 - St kstatfs
530 -}
531 -
532 -type fsyncIn struct {
533 - Fh uint64
534 - FsyncFlags uint32
535 - Padding uint32
536 -}
537 -
538 -type setxattrInCommon struct {
539 - Size uint32
540 - Flags uint32
541 -}
542 -
543 -func (setxattrInCommon) position() uint32 {
544 - return 0
545 -}
546 -
547 -type getxattrInCommon struct {
548 - Size uint32
549 - Padding uint32
550 -}
551 -
552 -func (getxattrInCommon) position() uint32 {
553 - return 0
554 -}
555 -
556 -type getxattrOut struct {
557 - outHeader
558 - Size uint32
559 - Padding uint32
560 -}
561 -
562 -type lkIn struct {
563 - Fh uint64
564 - Owner uint64
565 - Lk fileLock
566 -}
567 -
568 -type lkOut struct {
569 - outHeader
570 - Lk fileLock
571 -}
572 -
573 -type accessIn struct {
574 - Mask uint32
575 - Padding uint32
576 -}
577 -
578 -type initIn struct {
579 - Major uint32
580 - Minor uint32
581 - MaxReadahead uint32
582 - Flags uint32
583 -}
584 -
585 -const initInSize = int(unsafe.Sizeof(initIn{}))
586 -
587 -type initOut struct {
588 - outHeader
589 - Major uint32
590 - Minor uint32
591 - MaxReadahead uint32
592 - Flags uint32
593 - Unused uint32
594 - MaxWrite uint32
595 -}
596 -
597 -type interruptIn struct {
598 - Unique uint64
599 -}
600 -
601 -type bmapIn struct {
602 - Block uint64
603 - BlockSize uint32
604 - Padding uint32
605 -}
606 -
607 -type bmapOut struct {
608 - outHeader
609 - Block uint64
610 -}
611 -
612 -type inHeader struct {
613 - Len uint32
614 - Opcode uint32
615 - Unique uint64
616 - Nodeid uint64
617 - Uid uint32
618 - Gid uint32
619 - Pid uint32
620 - Padding uint32
621 -}
622 -
623 -const inHeaderSize = int(unsafe.Sizeof(inHeader{}))
624 -
625 -type outHeader struct {
626 - Len uint32
627 - Error int32
628 - Unique uint64
629 -}
630 -
631 -type dirent struct {
632 - Ino uint64
633 - Off uint64
634 - Namelen uint32
635 - Type uint32
636 - Name [0]byte
637 -}
638 -
639 -const direntSize = 8 + 8 + 4 + 4
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel_darwin.go deleted
-86
@@ -1,86 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "time"
5 -)
6 -
7 -type attr struct {
8 - Ino uint64
9 - Size uint64
10 - Blocks uint64
11 - Atime uint64
12 - Mtime uint64
13 - Ctime uint64
14 - Crtime_ uint64 // OS X only
15 - AtimeNsec uint32
16 - MtimeNsec uint32
17 - CtimeNsec uint32
18 - CrtimeNsec uint32 // OS X only
19 - Mode uint32
20 - Nlink uint32
21 - Uid uint32
22 - Gid uint32
23 - Rdev uint32
24 - Flags_ uint32 // OS X only; see chflags(2)
25 -}
26 -
27 -func (a *attr) SetCrtime(s uint64, ns uint32) {
28 - a.Crtime_, a.CrtimeNsec = s, ns
29 -}
30 -
31 -func (a *attr) SetFlags(f uint32) {
32 - a.Flags_ = f
33 -}
34 -
35 -type setattrIn struct {
36 - setattrInCommon
37 -
38 - // OS X only
39 - Bkuptime_ uint64
40 - Chgtime_ uint64
41 - Crtime uint64
42 - BkuptimeNsec uint32
43 - ChgtimeNsec uint32
44 - CrtimeNsec uint32
45 - Flags_ uint32 // see chflags(2)
46 -}
47 -
48 -func (in *setattrIn) BkupTime() time.Time {
49 - return time.Unix(int64(in.Bkuptime_), int64(in.BkuptimeNsec))
50 -}
51 -
52 -func (in *setattrIn) Chgtime() time.Time {
53 - return time.Unix(int64(in.Chgtime_), int64(in.ChgtimeNsec))
54 -}
55 -
56 -func (in *setattrIn) Flags() uint32 {
57 - return in.Flags_
58 -}
59 -
60 -func openFlags(flags uint32) OpenFlags {
61 - return OpenFlags(flags)
62 -}
63 -
64 -type getxattrIn struct {
65 - getxattrInCommon
66 -
67 - // OS X only
68 - Position uint32
69 - Padding uint32
70 -}
71 -
72 -func (g *getxattrIn) position() uint32 {
73 - return g.Position
74 -}
75 -
76 -type setxattrIn struct {
77 - setxattrInCommon
78 -
79 - // OS X only
80 - Position uint32
81 - Padding uint32
82 -}
83 -
84 -func (s *setxattrIn) position() uint32 {
85 - return s.Position
86 -}
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel_freebsd.go deleted
-60
@@ -1,60 +0,0 @@
1 -package fuse
2 -
3 -import "time"
4 -
5 -type attr struct {
6 - Ino uint64
7 - Size uint64
8 - Blocks uint64
9 - Atime uint64
10 - Mtime uint64
11 - Ctime uint64
12 - AtimeNsec uint32
13 - MtimeNsec uint32
14 - CtimeNsec uint32
15 - Mode uint32
16 - Nlink uint32
17 - Uid uint32
18 - Gid uint32
19 - Rdev uint32
20 -}
21 -
22 -func (a *attr) Crtime() time.Time {
23 - return time.Time{}
24 -}
25 -
26 -func (a *attr) SetCrtime(s uint64, ns uint32) {
27 - // ignored on freebsd
28 -}
29 -
30 -func (a *attr) SetFlags(f uint32) {
31 - // ignored on freebsd
32 -}
33 -
34 -type setattrIn struct {
35 - setattrInCommon
36 -}
37 -
38 -func (in *setattrIn) BkupTime() time.Time {
39 - return time.Time{}
40 -}
41 -
42 -func (in *setattrIn) Chgtime() time.Time {
43 - return time.Time{}
44 -}
45 -
46 -func (in *setattrIn) Flags() uint32 {
47 - return 0
48 -}
49 -
50 -func openFlags(flags uint32) OpenFlags {
51 - return OpenFlags(flags)
52 -}
53 -
54 -type getxattrIn struct {
55 - getxattrInCommon
56 -}
57 -
58 -type setxattrIn struct {
59 - setxattrInCommon
60 -}
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel_linux.go deleted
-70
@@ -1,70 +0,0 @@
1 -package fuse
2 -
3 -import "time"
4 -
5 -type attr struct {
6 - Ino uint64
7 - Size uint64
8 - Blocks uint64
9 - Atime uint64
10 - Mtime uint64
11 - Ctime uint64
12 - AtimeNsec uint32
13 - MtimeNsec uint32
14 - CtimeNsec uint32
15 - Mode uint32
16 - Nlink uint32
17 - Uid uint32
18 - Gid uint32
19 - Rdev uint32
20 - // Blksize uint32 // Only in protocol 7.9
21 - // padding_ uint32 // Only in protocol 7.9
22 -}
23 -
24 -func (a *attr) Crtime() time.Time {
25 - return time.Time{}
26 -}
27 -
28 -func (a *attr) SetCrtime(s uint64, ns uint32) {
29 - // Ignored on Linux.
30 -}
31 -
32 -func (a *attr) SetFlags(f uint32) {
33 - // Ignored on Linux.
34 -}
35 -
36 -type setattrIn struct {
37 - setattrInCommon
38 -}
39 -
40 -func (in *setattrIn) BkupTime() time.Time {
41 - return time.Time{}
42 -}
43 -
44 -func (in *setattrIn) Chgtime() time.Time {
45 - return time.Time{}
46 -}
47 -
48 -func (in *setattrIn) Flags() uint32 {
49 - return 0
50 -}
51 -
52 -func openFlags(flags uint32) OpenFlags {
53 - // on amd64, the 32-bit O_LARGEFILE flag is always seen;
54 - // on i386, the flag probably depends on the app
55 - // requesting, but in any case should be utterly
56 - // uninteresting to us here; our kernel protocol messages
57 - // are not directly related to the client app's kernel
58 - // API/ABI
59 - flags &^= 0x8000
60 -
61 - return OpenFlags(flags)
62 -}
63 -
64 -type getxattrIn struct {
65 - getxattrInCommon
66 -}
67 -
68 -type setxattrIn struct {
69 - setxattrInCommon
70 -}
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel_std.go deleted
-1
@@ -1 +0,0 @@
1 -package fuse
Godeps/_workspace/src/bazil.org/fuse/fuse_kernel_test.go deleted
-31
@@ -1,31 +0,0 @@
1 -package fuse_test
2 -
3 -import (
4 - "os"
5 - "testing"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
8 -)
9 -
10 -func TestOpenFlagsAccmodeMask(t *testing.T) {
11 - var f = fuse.OpenFlags(os.O_RDWR | os.O_SYNC)
12 - if g, e := f&fuse.OpenAccessModeMask, fuse.OpenReadWrite; g != e {
13 - t.Fatalf("OpenAccessModeMask behaves wrong: %v: %o != %o", f, g, e)
14 - }
15 - if f.IsReadOnly() {
16 - t.Fatalf("IsReadOnly is wrong: %v", f)
17 - }
18 - if f.IsWriteOnly() {
19 - t.Fatalf("IsWriteOnly is wrong: %v", f)
20 - }
21 - if !f.IsReadWrite() {
22 - t.Fatalf("IsReadWrite is wrong: %v", f)
23 - }
24 -}
25 -
26 -func TestOpenFlagsString(t *testing.T) {
27 - var f = fuse.OpenFlags(os.O_RDWR | os.O_SYNC | os.O_APPEND)
28 - if g, e := f.String(), "OpenReadWrite+OpenAppend+OpenSync"; g != e {
29 - t.Fatalf("OpenFlags.String: %q != %q", g, e)
30 - }
31 -}
Godeps/_workspace/src/bazil.org/fuse/fuseutil/fuseutil.go deleted
-20
@@ -1,20 +0,0 @@
1 -package fuseutil
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
5 -)
6 -
7 -// HandleRead handles a read request assuming that data is the entire file content.
8 -// It adjusts the amount returned in resp according to req.Offset and req.Size.
9 -func HandleRead(req *fuse.ReadRequest, resp *fuse.ReadResponse, data []byte) {
10 - if req.Offset >= int64(len(data)) {
11 - data = nil
12 - } else {
13 - data = data[req.Offset:]
14 - }
15 - if len(data) > req.Size {
16 - data = data[:req.Size]
17 - }
18 - n := copy(resp.Data[:req.Size], data)
19 - resp.Data = resp.Data[:n]
20 -}
Godeps/_workspace/src/bazil.org/fuse/hellofs/hello.go deleted
-101
@@ -1,101 +0,0 @@
1 -// Hellofs implements a simple "hello world" file system.
2 -package main
3 -
4 -import (
5 - "context"
6 - "flag"
7 - "fmt"
8 - "log"
9 - "os"
10 -
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
13 - _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
14 -)
15 -
16 -var Usage = func() {
17 - fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
18 - fmt.Fprintf(os.Stderr, " %s MOUNTPOINT\n", os.Args[0])
19 - flag.PrintDefaults()
20 -}
21 -
22 -func main() {
23 - flag.Usage = Usage
24 - flag.Parse()
25 -
26 - if flag.NArg() != 1 {
27 - Usage()
28 - os.Exit(2)
29 - }
30 - mountpoint := flag.Arg(0)
31 -
32 - c, err := fuse.Mount(
33 - mountpoint,
34 - fuse.FSName("helloworld"),
35 - fuse.Subtype("hellofs"),
36 - fuse.LocalVolume(),
37 - fuse.VolumeName("Hello world!"),
38 - )
39 - if err != nil {
40 - log.Fatal(err)
41 - }
42 - defer c.Close()
43 -
44 - err = fs.Serve(c, FS{})
45 - if err != nil {
46 - log.Fatal(err)
47 - }
48 -
49 - // check if the mount process has an error to report
50 - <-c.Ready
51 - if err := c.MountError; err != nil {
52 - log.Fatal(err)
53 - }
54 -}
55 -
56 -// FS implements the hello world file system.
57 -type FS struct{}
58 -
59 -func (FS) Root() (fs.Node, error) {
60 - return Dir{}, nil
61 -}
62 -
63 -// Dir implements both Node and Handle for the root directory.
64 -type Dir struct{}
65 -
66 -func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
67 - a.Inode = 1
68 - a.Mode = os.ModeDir | 0555
69 - return nil
70 -}
71 -
72 -func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
73 - if name == "hello" {
74 - return File{}, nil
75 - }
76 - return nil, fuse.ENOENT
77 -}
78 -
79 -var dirDirs = []fuse.Dirent{
80 - {Inode: 2, Name: "hello", Type: fuse.DT_File},
81 -}
82 -
83 -func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
84 - return dirDirs, nil
85 -}
86 -
87 -// File implements both Node and Handle for the hello file.
88 -type File struct{}
89 -
90 -const greeting = "hello, world\n"
91 -
92 -func (File) Attr(ctx context.Context, a *fuse.Attr) error {
93 - a.Inode = 2
94 - a.Mode = 0444
95 - a.Size = uint64(len(greeting))
96 - return nil
97 -}
98 -
99 -func (File) ReadAll(ctx context.Context) ([]byte, error) {
100 - return []byte(greeting), nil
101 -}
Godeps/_workspace/src/bazil.org/fuse/mount_darwin.go deleted
-126
@@ -1,126 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "bytes"
5 - "errors"
6 - "fmt"
7 - "os"
8 - "os/exec"
9 - "strconv"
10 - "strings"
11 - "syscall"
12 -)
13 -
14 -var errNoAvail = errors.New("no available fuse devices")
15 -
16 -var errNotLoaded = errors.New("osxfusefs is not loaded")
17 -
18 -func loadOSXFUSE() error {
19 - cmd := exec.Command("/Library/Filesystems/osxfusefs.fs/Support/load_osxfusefs")
20 - cmd.Dir = "/"
21 - cmd.Stdout = os.Stdout
22 - cmd.Stderr = os.Stderr
23 - err := cmd.Run()
24 - return err
25 -}
26 -
27 -func openOSXFUSEDev() (*os.File, error) {
28 - var f *os.File
29 - var err error
30 - for i := uint64(0); ; i++ {
31 - path := "/dev/osxfuse" + strconv.FormatUint(i, 10)
32 - f, err = os.OpenFile(path, os.O_RDWR, 0000)
33 - if os.IsNotExist(err) {
34 - if i == 0 {
35 - // not even the first device was found -> fuse is not loaded
36 - return nil, errNotLoaded
37 - }
38 -
39 - // we've run out of kernel-provided devices
40 - return nil, errNoAvail
41 - }
42 -
43 - if err2, ok := err.(*os.PathError); ok && err2.Err == syscall.EBUSY {
44 - // try the next one
45 - continue
46 - }
47 -
48 - if err != nil {
49 - return nil, err
50 - }
51 - return f, nil
52 - }
53 -}
54 -
55 -func callMount(dir string, conf *MountConfig, f *os.File, ready chan<- struct{}, errp *error) error {
56 - bin := "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs"
57 -
58 - for k, v := range conf.options {
59 - if strings.Contains(k, ",") || strings.Contains(v, ",") {
60 - // Silly limitation but the mount helper does not
61 - // understand any escaping. See TestMountOptionCommaError.
62 - return fmt.Errorf("mount options cannot contain commas on darwin: %q=%q", k, v)
63 - }
64 - }
65 - cmd := exec.Command(
66 - bin,
67 - "-o", conf.getOptions(),
68 - // Tell osxfuse-kext how large our buffer is. It must split
69 - // writes larger than this into multiple writes.
70 - //
71 - // OSXFUSE seems to ignore InitResponse.MaxWrite, and uses
72 - // this instead.
73 - "-o", "iosize="+strconv.FormatUint(maxWrite, 10),
74 - // refers to fd passed in cmd.ExtraFiles
75 - "3",
76 - dir,
77 - )
78 - cmd.ExtraFiles = []*os.File{f}
79 - cmd.Env = os.Environ()
80 - cmd.Env = append(cmd.Env, "MOUNT_FUSEFS_CALL_BY_LIB=")
81 - // TODO this is used for fs typenames etc, let app influence it
82 - cmd.Env = append(cmd.Env, "MOUNT_FUSEFS_DAEMON_PATH="+bin)
83 - var buf bytes.Buffer
84 - cmd.Stdout = &buf
85 - cmd.Stderr = &buf
86 -
87 - err := cmd.Start()
88 - if err != nil {
89 - return err
90 - }
91 - go func() {
92 - err := cmd.Wait()
93 - if err != nil {
94 - if buf.Len() > 0 {
95 - output := buf.Bytes()
96 - output = bytes.TrimRight(output, "\n")
97 - msg := err.Error() + ": " + string(output)
98 - err = errors.New(msg)
99 - }
100 - }
101 - *errp = err
102 - close(ready)
103 - }()
104 - return err
105 -}
106 -
107 -func mount(dir string, conf *MountConfig, ready chan<- struct{}, errp *error) (*os.File, error) {
108 - f, err := openOSXFUSEDev()
109 - if err == errNotLoaded {
110 - err = loadOSXFUSE()
111 - if err != nil {
112 - return nil, err
113 - }
114 - // try again
115 - f, err = openOSXFUSEDev()
116 - }
117 - if err != nil {
118 - return nil, err
119 - }
120 - err = callMount(dir, conf, f, ready, errp)
121 - if err != nil {
122 - f.Close()
123 - return nil, err
124 - }
125 - return f, nil
126 -}
Godeps/_workspace/src/bazil.org/fuse/mount_freebsd.go deleted
-41
@@ -1,41 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "fmt"
5 - "os"
6 - "os/exec"
7 - "strings"
8 -)
9 -
10 -func mount(dir string, conf *MountConfig, ready chan<- struct{}, errp *error) (*os.File, error) {
11 - for k, v := range conf.options {
12 - if strings.Contains(k, ",") || strings.Contains(v, ",") {
13 - // Silly limitation but the mount helper does not
14 - // understand any escaping. See TestMountOptionCommaError.
15 - return nil, fmt.Errorf("mount options cannot contain commas on FreeBSD: %q=%q", k, v)
16 - }
17 - }
18 -
19 - f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0000)
20 - if err != nil {
21 - *errp = err
22 - return nil, err
23 - }
24 -
25 - cmd := exec.Command(
26 - "/sbin/mount_fusefs",
27 - "--safe",
28 - "-o", conf.getOptions(),
29 - "3",
30 - dir,
31 - )
32 - cmd.ExtraFiles = []*os.File{f}
33 -
34 - out, err := cmd.CombinedOutput()
35 - if err != nil {
36 - return nil, fmt.Errorf("mount_fusefs: %q, %v", out, err)
37 - }
38 -
39 - close(ready)
40 - return f, nil
41 -}
Godeps/_workspace/src/bazil.org/fuse/mount_linux.go deleted
-112
@@ -1,112 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "bufio"
5 - "fmt"
6 - "io"
7 - "log"
8 - "net"
9 - "os"
10 - "os/exec"
11 - "sync"
12 - "syscall"
13 -)
14 -
15 -func lineLogger(wg *sync.WaitGroup, prefix string, r io.ReadCloser) {
16 - defer wg.Done()
17 -
18 - scanner := bufio.NewScanner(r)
19 - for scanner.Scan() {
20 - switch line := scanner.Text(); line {
21 - case `fusermount: failed to open /etc/fuse.conf: Permission denied`:
22 - // Silence this particular message, it occurs way too
23 - // commonly and isn't very relevant to whether the mount
24 - // succeeds or not.
25 - continue
26 - default:
27 - log.Printf("%s: %s", prefix, line)
28 - }
29 - }
30 - if err := scanner.Err(); err != nil {
31 - log.Printf("%s, error reading: %v", prefix, err)
32 - }
33 -}
34 -
35 -func mount(dir string, conf *MountConfig, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) {
36 - // linux mount is never delayed
37 - close(ready)
38 -
39 - fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0)
40 - if err != nil {
41 - return nil, fmt.Errorf("socketpair error: %v", err)
42 - }
43 - defer syscall.Close(fds[0])
44 - defer syscall.Close(fds[1])
45 -
46 - cmd := exec.Command(
47 - "fusermount",
48 - "-o", conf.getOptions(),
49 - "--",
50 - dir,
51 - )
52 - cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3")
53 -
54 - writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes")
55 - defer writeFile.Close()
56 - cmd.ExtraFiles = []*os.File{writeFile}
57 -
58 - var wg sync.WaitGroup
59 - stdout, err := cmd.StdoutPipe()
60 - if err != nil {
61 - return nil, fmt.Errorf("setting up fusermount stderr: %v", err)
62 - }
63 - stderr, err := cmd.StderrPipe()
64 - if err != nil {
65 - return nil, fmt.Errorf("setting up fusermount stderr: %v", err)
66 - }
67 -
68 - if err := cmd.Start(); err != nil {
69 - return nil, fmt.Errorf("fusermount: %v", err)
70 - }
71 - wg.Add(2)
72 - go lineLogger(&wg, "mount helper output", stdout)
73 - go lineLogger(&wg, "mount helper error", stderr)
74 - wg.Wait()
75 - if err := cmd.Wait(); err != nil {
76 - return nil, fmt.Errorf("fusermount: %v", err)
77 - }
78 -
79 - readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
80 - defer readFile.Close()
81 - c, err := net.FileConn(readFile)
82 - if err != nil {
83 - return nil, fmt.Errorf("FileConn from fusermount socket: %v", err)
84 - }
85 - defer c.Close()
86 -
87 - uc, ok := c.(*net.UnixConn)
88 - if !ok {
89 - return nil, fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c)
90 - }
91 -
92 - buf := make([]byte, 32) // expect 1 byte
93 - oob := make([]byte, 32) // expect 24 bytes
94 - _, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
95 - scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
96 - if err != nil {
97 - return nil, fmt.Errorf("ParseSocketControlMessage: %v", err)
98 - }
99 - if len(scms) != 1 {
100 - return nil, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms)
101 - }
102 - scm := scms[0]
103 - gotFds, err := syscall.ParseUnixRights(&scm)
104 - if err != nil {
105 - return nil, fmt.Errorf("syscall.ParseUnixRights: %v", err)
106 - }
107 - if len(gotFds) != 1 {
108 - return nil, fmt.Errorf("wanted 1 fd; got %#v", gotFds)
109 - }
110 - f := os.NewFile(uintptr(gotFds[0]), "/dev/fuse")
111 - return f, nil
112 -}
Godeps/_workspace/src/bazil.org/fuse/options.go deleted
-132
@@ -1,132 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "errors"
5 - "strings"
6 -)
7 -
8 -func dummyOption(conf *MountConfig) error {
9 - return nil
10 -}
11 -
12 -// MountConfig holds the configuration for a mount operation.
13 -// Use it by passing MountOption values to Mount.
14 -type MountConfig struct {
15 - options map[string]string
16 -}
17 -
18 -func escapeComma(s string) string {
19 - s = strings.Replace(s, `\`, `\\`, -1)
20 - s = strings.Replace(s, `,`, `\,`, -1)
21 - return s
22 -}
23 -
24 -// getOptions makes a string of options suitable for passing to FUSE
25 -// mount flag `-o`. Returns an empty string if no options were set.
26 -// Any platform specific adjustments should happen before the call.
27 -func (m *MountConfig) getOptions() string {
28 - var opts []string
29 - for k, v := range m.options {
30 - k = escapeComma(k)
31 - if v != "" {
32 - k += "=" + escapeComma(v)
33 - }
34 - opts = append(opts, k)
35 - }
36 - return strings.Join(opts, ",")
37 -}
38 -
39 -// MountOption is passed to Mount to change the behavior of the mount.
40 -type MountOption func(*MountConfig) error
41 -
42 -// FSName sets the file system name (also called source) that is
43 -// visible in the list of mounted file systems.
44 -//
45 -// FreeBSD ignores this option.
46 -func FSName(name string) MountOption {
47 - return func(conf *MountConfig) error {
48 - conf.options["fsname"] = name
49 - return nil
50 - }
51 -}
52 -
53 -// Subtype sets the subtype of the mount. The main type is always
54 -// `fuse`. The type in a list of mounted file systems will look like
55 -// `fuse.foo`.
56 -//
57 -// OS X ignores this option.
58 -// FreeBSD ignores this option.
59 -func Subtype(fstype string) MountOption {
60 - return func(conf *MountConfig) error {
61 - conf.options["subtype"] = fstype
62 - return nil
63 - }
64 -}
65 -
66 -// LocalVolume sets the volume to be local (instead of network),
67 -// changing the behavior of Finder, Spotlight, and such.
68 -//
69 -// OS X only. Others ignore this option.
70 -func LocalVolume() MountOption {
71 - return localVolume
72 -}
73 -
74 -// VolumeName sets the volume name shown in Finder.
75 -//
76 -// OS X only. Others ignore this option.
77 -func VolumeName(name string) MountOption {
78 - return volumeName(name)
79 -}
80 -
81 -var ErrCannotCombineAllowOtherAndAllowRoot = errors.New("cannot combine AllowOther and AllowRoot")
82 -
83 -// AllowOther allows other users to access the file system.
84 -//
85 -// Only one of AllowOther or AllowRoot can be used.
86 -func AllowOther() MountOption {
87 - return func(conf *MountConfig) error {
88 - if _, ok := conf.options["allow_root"]; ok {
89 - return ErrCannotCombineAllowOtherAndAllowRoot
90 - }
91 - conf.options["allow_other"] = ""
92 - return nil
93 - }
94 -}
95 -
96 -// AllowRoot allows other users to access the file system.
97 -//
98 -// Only one of AllowOther or AllowRoot can be used.
99 -//
100 -// FreeBSD ignores this option.
101 -func AllowRoot() MountOption {
102 - return func(conf *MountConfig) error {
103 - if _, ok := conf.options["allow_other"]; ok {
104 - return ErrCannotCombineAllowOtherAndAllowRoot
105 - }
106 - conf.options["allow_root"] = ""
107 - return nil
108 - }
109 -}
110 -
111 -// DefaultPermissions makes the kernel enforce access control based on
112 -// the file mode (as in chmod).
113 -//
114 -// Without this option, the Node itself decides what is and is not
115 -// allowed. This is normally ok because FUSE file systems cannot be
116 -// accessed by other users without AllowOther/AllowRoot.
117 -//
118 -// FreeBSD ignores this option.
119 -func DefaultPermissions() MountOption {
120 - return func(conf *MountConfig) error {
121 - conf.options["default_permissions"] = ""
122 - return nil
123 - }
124 -}
125 -
126 -// ReadOnly makes the mount read-only.
127 -func ReadOnly() MountOption {
128 - return func(conf *MountConfig) error {
129 - conf.options["ro"] = ""
130 - return nil
131 - }
132 -}
Godeps/_workspace/src/bazil.org/fuse/options_darwin.go deleted
-13
@@ -1,13 +0,0 @@
1 -package fuse
2 -
3 -func localVolume(conf *MountConfig) error {
4 - conf.options["local"] = ""
5 - return nil
6 -}
7 -
8 -func volumeName(name string) MountOption {
9 - return func(conf *MountConfig) error {
10 - conf.options["volname"] = name
11 - return nil
12 - }
13 -}
Godeps/_workspace/src/bazil.org/fuse/options_freebsd.go deleted
-9
@@ -1,9 +0,0 @@
1 -package fuse
2 -
3 -func localVolume(conf *MountConfig) error {
4 - return nil
5 -}
6 -
7 -func volumeName(name string) MountOption {
8 - return dummyOption
9 -}
Godeps/_workspace/src/bazil.org/fuse/options_helper_test.go deleted
-6
@@ -1,6 +0,0 @@
1 -package fuse
2 -
3 -// for TestMountOptionCommaError
4 -func ForTestSetMountOption(conf *MountConfig, k, v string) {
5 - conf.options[k] = v
6 -}
Godeps/_workspace/src/bazil.org/fuse/options_linux.go deleted
-9
@@ -1,9 +0,0 @@
1 -package fuse
2 -
3 -func localVolume(conf *MountConfig) error {
4 - return nil
5 -}
6 -
7 -func volumeName(name string) MountOption {
8 - return dummyOption
9 -}
Godeps/_workspace/src/bazil.org/fuse/options_nocomma_test.go deleted
-34
@@ -1,34 +0,0 @@
1 -// This file contains tests for platforms that have no escape
2 -// mechanism for including commas in mount options.
3 -//
4 -// +build darwin
5 -
6 -package fuse_test
7 -
8 -import (
9 - "runtime"
10 - "testing"
11 -
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
13 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
14 -)
15 -
16 -func TestMountOptionCommaError(t *testing.T) {
17 - t.Parallel()
18 - // this test is not tied to any specific option, it just needs
19 - // some string content
20 - var evil = "FuseTest,Marker"
21 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
22 - func(conf *fuse.MountConfig) error {
23 - fuse.ForTestSetMountOption(conf, "fusetest", evil)
24 - return nil
25 - },
26 - )
27 - if err == nil {
28 - mnt.Close()
29 - t.Fatal("expected an error about commas")
30 - }
31 - if g, e := err.Error(), `mount options cannot contain commas on `+runtime.GOOS+`: "fusetest"="FuseTest,Marker"`; g != e {
32 - t.Fatalf("wrong error: %q != %q", g, e)
33 - }
34 -}
Godeps/_workspace/src/bazil.org/fuse/options_test.go deleted
-229
@@ -1,229 +0,0 @@
1 -package fuse_test
2 -
3 -import (
4 - "context"
5 - "os"
6 - "runtime"
7 - "syscall"
8 - "testing"
9 -
10 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
13 -)
14 -
15 -func init() {
16 - fstestutil.DebugByDefault()
17 -}
18 -
19 -func TestMountOptionFSName(t *testing.T) {
20 - if runtime.GOOS == "freebsd" {
21 - t.Skip("FreeBSD does not support FSName")
22 - }
23 - t.Parallel()
24 - const name = "FuseTestMarker"
25 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
26 - fuse.FSName(name),
27 - )
28 - if err != nil {
29 - t.Fatal(err)
30 - }
31 - defer mnt.Close()
32 -
33 - info, err := fstestutil.GetMountInfo(mnt.Dir)
34 - if err != nil {
35 - t.Fatal(err)
36 - }
37 - if g, e := info.FSName, name; g != e {
38 - t.Errorf("wrong FSName: %q != %q", g, e)
39 - }
40 -}
41 -
42 -func testMountOptionFSNameEvil(t *testing.T, evil string) {
43 - if runtime.GOOS == "freebsd" {
44 - t.Skip("FreeBSD does not support FSName")
45 - }
46 - t.Parallel()
47 - var name = "FuseTest" + evil + "Marker"
48 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
49 - fuse.FSName(name),
50 - )
51 - if err != nil {
52 - t.Fatal(err)
53 - }
54 - defer mnt.Close()
55 -
56 - info, err := fstestutil.GetMountInfo(mnt.Dir)
57 - if err != nil {
58 - t.Fatal(err)
59 - }
60 - if g, e := info.FSName, name; g != e {
61 - t.Errorf("wrong FSName: %q != %q", g, e)
62 - }
63 -}
64 -
65 -func TestMountOptionFSNameEvilComma(t *testing.T) {
66 - if runtime.GOOS == "darwin" {
67 - // see TestMountOptionCommaError for a test that enforces we
68 - // at least give a nice error, instead of corrupting the mount
69 - // options
70 - t.Skip("TODO: OS X gets this wrong, commas in mount options cannot be escaped at all")
71 - }
72 - testMountOptionFSNameEvil(t, ",")
73 -}
74 -
75 -func TestMountOptionFSNameEvilSpace(t *testing.T) {
76 - testMountOptionFSNameEvil(t, " ")
77 -}
78 -
79 -func TestMountOptionFSNameEvilTab(t *testing.T) {
80 - testMountOptionFSNameEvil(t, "\t")
81 -}
82 -
83 -func TestMountOptionFSNameEvilNewline(t *testing.T) {
84 - testMountOptionFSNameEvil(t, "\n")
85 -}
86 -
87 -func TestMountOptionFSNameEvilBackslash(t *testing.T) {
88 - testMountOptionFSNameEvil(t, `\`)
89 -}
90 -
91 -func TestMountOptionFSNameEvilBackslashDouble(t *testing.T) {
92 - // catch double-unescaping, if it were to happen
93 - testMountOptionFSNameEvil(t, `\\`)
94 -}
95 -
96 -func TestMountOptionSubtype(t *testing.T) {
97 - if runtime.GOOS == "darwin" {
98 - t.Skip("OS X does not support Subtype")
99 - }
100 - if runtime.GOOS == "freebsd" {
101 - t.Skip("FreeBSD does not support Subtype")
102 - }
103 - t.Parallel()
104 - const name = "FuseTestMarker"
105 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
106 - fuse.Subtype(name),
107 - )
108 - if err != nil {
109 - t.Fatal(err)
110 - }
111 - defer mnt.Close()
112 -
113 - info, err := fstestutil.GetMountInfo(mnt.Dir)
114 - if err != nil {
115 - t.Fatal(err)
116 - }
117 - if g, e := info.Type, "fuse."+name; g != e {
118 - t.Errorf("wrong Subtype: %q != %q", g, e)
119 - }
120 -}
121 -
122 -// TODO test LocalVolume
123 -
124 -// TODO test AllowOther; hard because needs system-level authorization
125 -
126 -func TestMountOptionAllowOtherThenAllowRoot(t *testing.T) {
127 - t.Parallel()
128 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
129 - fuse.AllowOther(),
130 - fuse.AllowRoot(),
131 - )
132 - if err == nil {
133 - mnt.Close()
134 - }
135 - if g, e := err, fuse.ErrCannotCombineAllowOtherAndAllowRoot; g != e {
136 - t.Fatalf("wrong error: %v != %v", g, e)
137 - }
138 -}
139 -
140 -// TODO test AllowRoot; hard because needs system-level authorization
141 -
142 -func TestMountOptionAllowRootThenAllowOther(t *testing.T) {
143 - t.Parallel()
144 - mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
145 - fuse.AllowRoot(),
146 - fuse.AllowOther(),
147 - )
148 - if err == nil {
149 - mnt.Close()
150 - }
151 - if g, e := err, fuse.ErrCannotCombineAllowOtherAndAllowRoot; g != e {
152 - t.Fatalf("wrong error: %v != %v", g, e)
153 - }
154 -}
155 -
156 -type unwritableFile struct{}
157 -
158 -func (f unwritableFile) Attr(ctx context.Context, a *fuse.Attr) error {
159 - a.Mode = 0000
160 - return nil
161 -}
162 -
163 -func TestMountOptionDefaultPermissions(t *testing.T) {
164 - if runtime.GOOS == "freebsd" {
165 - t.Skip("FreeBSD does not support DefaultPermissions")
166 - }
167 - t.Parallel()
168 - mnt, err := fstestutil.MountedT(t,
169 - fstestutil.SimpleFS{
170 - fstestutil.ChildMap{"child": unwritableFile{}},
171 - },
172 - fuse.DefaultPermissions(),
173 - )
174 -
175 - if err != nil {
176 - t.Fatal(err)
177 - }
178 - defer mnt.Close()
179 -
180 - // This will be prevented by kernel-level access checking when
181 - // DefaultPermissions is used.
182 - f, err := os.OpenFile(mnt.Dir+"/child", os.O_WRONLY, 0000)
183 - if err == nil {
184 - f.Close()
185 - t.Fatal("expected an error")
186 - }
187 - if !os.IsPermission(err) {
188 - t.Fatalf("expected a permission error, got %T: %v", err, err)
189 - }
190 -}
191 -
192 -type createrDir struct {
193 - fstestutil.Dir
194 -}
195 -
196 -var _ fs.NodeCreater = createrDir{}
197 -
198 -func (createrDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
199 - // pick a really distinct error, to identify it later
200 - return nil, nil, fuse.Errno(syscall.ENAMETOOLONG)
201 -}
202 -
203 -func TestMountOptionReadOnly(t *testing.T) {
204 - t.Parallel()
205 - mnt, err := fstestutil.MountedT(t,
206 - fstestutil.SimpleFS{createrDir{}},
207 - fuse.ReadOnly(),
208 - )
209 -
210 - if err != nil {
211 - t.Fatal(err)
212 - }
213 - defer mnt.Close()
214 -
215 - // This will be prevented by kernel-level access checking when
216 - // ReadOnly is used.
217 - f, err := os.Create(mnt.Dir + "/child")
218 - if err == nil {
219 - f.Close()
220 - t.Fatal("expected an error")
221 - }
222 - perr, ok := err.(*os.PathError)
223 - if !ok {
224 - t.Fatalf("expected PathError, got %T: %v", err, err)
225 - }
226 - if perr.Err != syscall.EROFS {
227 - t.Fatalf("expected EROFS, got %T: %v", err, err)
228 - }
229 -}
Godeps/_workspace/src/bazil.org/fuse/syscallx/doc.go deleted
-13
@@ -1,13 +0,0 @@
1 -// Package syscallx provides wrappers that make syscalls on various
2 -// platforms more interoperable.
3 -//
4 -// The API intentionally omits the OS X-specific position and option
5 -// arguments for extended attribute calls.
6 -//
7 -// Not having position means it might not be useful for accessing the
8 -// resource fork. If that's needed by code inside fuse, a function
9 -// with a different name may be added on the side.
10 -//
11 -// Options can be implemented with separate wrappers, in the style of
12 -// Linux getxattr/lgetxattr/fgetxattr.
13 -package syscallx
Godeps/_workspace/src/bazil.org/fuse/syscallx/generate deleted
-34
@@ -1,34 +0,0 @@
1 -#!/bin/sh
2 -set -e
3 -
4 -mksys="$(go env GOROOT)/src/pkg/syscall/mksyscall.pl"
5 -
6 -fix() {
7 - sed 's,^package syscall$,&x\nimport "syscall",' \
8 - | gofmt -r='BytePtrFromString -> syscall.BytePtrFromString' \
9 - | gofmt -r='Syscall6 -> syscall.Syscall6' \
10 - | gofmt -r='Syscall -> syscall.Syscall' \
11 - | gofmt -r='SYS_GETXATTR -> syscall.SYS_GETXATTR' \
12 - | gofmt -r='SYS_LISTXATTR -> syscall.SYS_LISTXATTR' \
13 - | gofmt -r='SYS_SETXATTR -> syscall.SYS_SETXATTR' \
14 - | gofmt -r='SYS_REMOVEXATTR -> syscall.SYS_REMOVEXATTR' \
15 - | gofmt -r='SYS_MSYNC -> syscall.SYS_MSYNC'
16 -}
17 -
18 -cd "$(dirname "$0")"
19 -
20 -$mksys xattr_darwin.go \
21 - | fix \
22 - >xattr_darwin_amd64.go
23 -
24 -$mksys -l32 xattr_darwin.go \
25 - | fix \
26 - >xattr_darwin_386.go
27 -
28 -$mksys msync.go \
29 - | fix \
30 - >msync_amd64.go
31 -
32 -$mksys -l32 msync.go \
33 - | fix \
34 - >msync_386.go
Godeps/_workspace/src/bazil.org/fuse/syscallx/msync.go deleted
-9
@@ -1,9 +0,0 @@
1 -package syscallx
2 -
3 -/* This is the source file for msync_*.go, to regenerate run
4 -
5 - ./generate
6 -
7 -*/
8 -
9 -//sys Msync(b []byte, flags int) (err error)
Godeps/_workspace/src/bazil.org/fuse/syscallx/msync_386.go deleted
-24
@@ -1,24 +0,0 @@
1 -// mksyscall.pl -l32 msync.go
2 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
3 -
4 -package syscallx
5 -
6 -import "syscall"
7 -
8 -import "unsafe"
9 -
10 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
11 -
12 -func Msync(b []byte, flags int) (err error) {
13 - var _p0 unsafe.Pointer
14 - if len(b) > 0 {
15 - _p0 = unsafe.Pointer(&b[0])
16 - } else {
17 - _p0 = unsafe.Pointer(&_zero)
18 - }
19 - _, _, e1 := syscall.Syscall(syscall.SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
20 - if e1 != 0 {
21 - err = e1
22 - }
23 - return
24 -}
Godeps/_workspace/src/bazil.org/fuse/syscallx/msync_amd64.go deleted
-24
@@ -1,24 +0,0 @@
1 -// mksyscall.pl msync.go
2 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
3 -
4 -package syscallx
5 -
6 -import "syscall"
7 -
8 -import "unsafe"
9 -
10 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
11 -
12 -func Msync(b []byte, flags int) (err error) {
13 - var _p0 unsafe.Pointer
14 - if len(b) > 0 {
15 - _p0 = unsafe.Pointer(&b[0])
16 - } else {
17 - _p0 = unsafe.Pointer(&_zero)
18 - }
19 - _, _, e1 := syscall.Syscall(syscall.SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
20 - if e1 != 0 {
21 - err = e1
22 - }
23 - return
24 -}
Godeps/_workspace/src/bazil.org/fuse/syscallx/syscallx.go deleted
-4
@@ -1,4 +0,0 @@
1 -package syscallx
2 -
3 -// make us look more like package syscall, so mksyscall.pl output works
4 -var _zero uintptr
Godeps/_workspace/src/bazil.org/fuse/syscallx/syscallx_std.go deleted
-26
@@ -1,26 +0,0 @@
1 -// +build !darwin
2 -
3 -package syscallx
4 -
5 -// This file just contains wrappers for platforms that already have
6 -// the right stuff in golang.org/x/sys/unix.
7 -
8 -import (
9 - "gx/ipfs/QmXPKMT5cT8ajqamSD1YaeEpfeaHvs9AU4MQzte4Bkr6V4/sys/unix"
10 -)
11 -
12 -func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
13 - return unix.Getxattr(path, attr, dest)
14 -}
15 -
16 -func Listxattr(path string, dest []byte) (sz int, err error) {
17 - return unix.Listxattr(path, dest)
18 -}
19 -
20 -func Setxattr(path string, attr string, data []byte, flags int) (err error) {
21 - return unix.Setxattr(path, attr, data, flags)
22 -}
23 -
24 -func Removexattr(path string, attr string) (err error) {
25 - return unix.Removexattr(path, attr)
26 -}
Godeps/_workspace/src/bazil.org/fuse/syscallx/xattr_darwin.go deleted
-38
@@ -1,38 +0,0 @@
1 -package syscallx
2 -
3 -/* This is the source file for syscallx_darwin_*.go, to regenerate run
4 -
5 - ./generate
6 -
7 -*/
8 -
9 -// cannot use dest []byte here because OS X getxattr really wants a
10 -// NULL to trigger size probing, size==0 is not enough
11 -//
12 -//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
13 -
14 -func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
15 - var destp *byte
16 - if len(dest) > 0 {
17 - destp = &dest[0]
18 - }
19 - return getxattr(path, attr, destp, len(dest), 0, 0)
20 -}
21 -
22 -//sys listxattr(path string, dest []byte, options int) (sz int, err error)
23 -
24 -func Listxattr(path string, dest []byte) (sz int, err error) {
25 - return listxattr(path, dest, 0)
26 -}
27 -
28 -//sys setxattr(path string, attr string, data []byte, position uint32, flags int) (err error)
29 -
30 -func Setxattr(path string, attr string, data []byte, flags int) (err error) {
31 - return setxattr(path, attr, data, 0, flags)
32 -}
33 -
34 -//sys removexattr(path string, attr string, options int) (err error)
35 -
36 -func Removexattr(path string, attr string) (err error) {
37 - return removexattr(path, attr, 0)
38 -}
Godeps/_workspace/src/bazil.org/fuse/syscallx/xattr_darwin_386.go deleted
-97
@@ -1,97 +0,0 @@
1 -// mksyscall.pl -l32 xattr_darwin.go
2 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
3 -
4 -package syscallx
5 -
6 -import "syscall"
7 -
8 -import "unsafe"
9 -
10 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
11 -
12 -func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) {
13 - var _p0 *byte
14 - _p0, err = syscall.BytePtrFromString(path)
15 - if err != nil {
16 - return
17 - }
18 - var _p1 *byte
19 - _p1, err = syscall.BytePtrFromString(attr)
20 - if err != nil {
21 - return
22 - }
23 - r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
24 - sz = int(r0)
25 - if e1 != 0 {
26 - err = e1
27 - }
28 - return
29 -}
30 -
31 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
32 -
33 -func listxattr(path string, dest []byte, options int) (sz int, err error) {
34 - var _p0 *byte
35 - _p0, err = syscall.BytePtrFromString(path)
36 - if err != nil {
37 - return
38 - }
39 - var _p1 unsafe.Pointer
40 - if len(dest) > 0 {
41 - _p1 = unsafe.Pointer(&dest[0])
42 - } else {
43 - _p1 = unsafe.Pointer(&_zero)
44 - }
45 - r0, _, e1 := syscall.Syscall6(syscall.SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(options), 0, 0)
46 - sz = int(r0)
47 - if e1 != 0 {
48 - err = e1
49 - }
50 - return
51 -}
52 -
53 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
54 -
55 -func setxattr(path string, attr string, data []byte, position uint32, flags int) (err error) {
56 - var _p0 *byte
57 - _p0, err = syscall.BytePtrFromString(path)
58 - if err != nil {
59 - return
60 - }
61 - var _p1 *byte
62 - _p1, err = syscall.BytePtrFromString(attr)
63 - if err != nil {
64 - return
65 - }
66 - var _p2 unsafe.Pointer
67 - if len(data) > 0 {
68 - _p2 = unsafe.Pointer(&data[0])
69 - } else {
70 - _p2 = unsafe.Pointer(&_zero)
71 - }
72 - _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(position), uintptr(flags))
73 - if e1 != 0 {
74 - err = e1
75 - }
76 - return
77 -}
78 -
79 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
80 -
81 -func removexattr(path string, attr string, options int) (err error) {
82 - var _p0 *byte
83 - _p0, err = syscall.BytePtrFromString(path)
84 - if err != nil {
85 - return
86 - }
87 - var _p1 *byte
88 - _p1, err = syscall.BytePtrFromString(attr)
89 - if err != nil {
90 - return
91 - }
92 - _, _, e1 := syscall.Syscall(syscall.SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
93 - if e1 != 0 {
94 - err = e1
95 - }
96 - return
97 -}
Godeps/_workspace/src/bazil.org/fuse/syscallx/xattr_darwin_amd64.go deleted
-97
@@ -1,97 +0,0 @@
1 -// mksyscall.pl xattr_darwin.go
2 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
3 -
4 -package syscallx
5 -
6 -import "syscall"
7 -
8 -import "unsafe"
9 -
10 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
11 -
12 -func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) {
13 - var _p0 *byte
14 - _p0, err = syscall.BytePtrFromString(path)
15 - if err != nil {
16 - return
17 - }
18 - var _p1 *byte
19 - _p1, err = syscall.BytePtrFromString(attr)
20 - if err != nil {
21 - return
22 - }
23 - r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options))
24 - sz = int(r0)
25 - if e1 != 0 {
26 - err = e1
27 - }
28 - return
29 -}
30 -
31 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
32 -
33 -func listxattr(path string, dest []byte, options int) (sz int, err error) {
34 - var _p0 *byte
35 - _p0, err = syscall.BytePtrFromString(path)
36 - if err != nil {
37 - return
38 - }
39 - var _p1 unsafe.Pointer
40 - if len(dest) > 0 {
41 - _p1 = unsafe.Pointer(&dest[0])
42 - } else {
43 - _p1 = unsafe.Pointer(&_zero)
44 - }
45 - r0, _, e1 := syscall.Syscall6(syscall.SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(options), 0, 0)
46 - sz = int(r0)
47 - if e1 != 0 {
48 - err = e1
49 - }
50 - return
51 -}
52 -
53 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
54 -
55 -func setxattr(path string, attr string, data []byte, position uint32, flags int) (err error) {
56 - var _p0 *byte
57 - _p0, err = syscall.BytePtrFromString(path)
58 - if err != nil {
59 - return
60 - }
61 - var _p1 *byte
62 - _p1, err = syscall.BytePtrFromString(attr)
63 - if err != nil {
64 - return
65 - }
66 - var _p2 unsafe.Pointer
67 - if len(data) > 0 {
68 - _p2 = unsafe.Pointer(&data[0])
69 - } else {
70 - _p2 = unsafe.Pointer(&_zero)
71 - }
72 - _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(position), uintptr(flags))
73 - if e1 != 0 {
74 - err = e1
75 - }
76 - return
77 -}
78 -
79 -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
80 -
81 -func removexattr(path string, attr string, options int) (err error) {
82 - var _p0 *byte
83 - _p0, err = syscall.BytePtrFromString(path)
84 - if err != nil {
85 - return
86 - }
87 - var _p1 *byte
88 - _p1, err = syscall.BytePtrFromString(attr)
89 - if err != nil {
90 - return
91 - }
92 - _, _, e1 := syscall.Syscall(syscall.SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
93 - if e1 != 0 {
94 - err = e1
95 - }
96 - return
97 -}
Godeps/_workspace/src/bazil.org/fuse/unmount.go deleted
-6
@@ -1,6 +0,0 @@
1 -package fuse
2 -
3 -// Unmount tries to unmount the filesystem mounted at dir.
4 -func Unmount(dir string) error {
5 - return unmount(dir)
6 -}
Godeps/_workspace/src/bazil.org/fuse/unmount_linux.go deleted
-21
@@ -1,21 +0,0 @@
1 -package fuse
2 -
3 -import (
4 - "bytes"
5 - "errors"
6 - "os/exec"
7 -)
8 -
9 -func unmount(dir string) error {
10 - cmd := exec.Command("fusermount", "-u", dir)
11 - output, err := cmd.CombinedOutput()
12 - if err != nil {
13 - if len(output) > 0 {
14 - output = bytes.TrimRight(output, "\n")
15 - msg := err.Error() + ": " + string(output)
16 - err = errors.New(msg)
17 - }
18 - return err
19 - }
20 - return nil
21 -}
Godeps/_workspace/src/bazil.org/fuse/unmount_std.go deleted
-17
@@ -1,17 +0,0 @@
1 -// +build !linux
2 -
3 -package fuse
4 -
5 -import (
6 - "os"
7 - "syscall"
8 -)
9 -
10 -func unmount(dir string) error {
11 - err := syscall.Unmount(dir, 0)
12 - if err != nil {
13 - err = &os.PathError{Op: "unmount", Path: dir, Err: err}
14 - return err
15 - }
16 - return nil
17 -}