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
-
14
-
15
-On OS X, the mount becomes visible only after `InitRequest` (and maybe
16
-more) have been served.
17
-
18
-
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
-
27
-
28
-On OS X, the mount never happened:
29
-
30
-
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
-}