Commit 1e564b6a authored by Kirill Smelkov's avatar Kirill Smelkov

Merge remote-tracking branch 'origin/master' into t

* origin/master:
  zipfs: godoc comments for tarfs
  fs: more godoc
  pathfs: mark nodefs, pathfs as deprecated
  example: add doc comments to main programs
  Reinstate "gerrithub usage instructions."
  fuse/nodefs: return OK for OOB readdir(plus)
parents c51dede3 aedffc58
...@@ -2,3 +2,21 @@ ...@@ -2,3 +2,21 @@
Before sending a patch or Pull request, please fill out a Google CLA, using the following form: Before sending a patch or Pull request, please fill out a Google CLA, using the following form:
https://cla.developers.google.com/clas https://cla.developers.google.com/clas
For complex changes, please use Gerrit:
* Connect your github account with gerrithub, at
https://review.gerrithub.io/static/intro.html
* The signup will setup your SSH keys from Github.
* Create your change as a commit
* Add an ID to the commit message:
echo "Change-Id: I"$(head -c 20 /dev/urandom | sha1sum | awk '{print $1}')
* Push the change for review,
git push ssh://$USER@review.gerrithub.io:29418/hanwen/go-fuse HEAD:refs/for/master
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// A Go mirror of libfuse's hello.c // This program is the analogon of libfuse's hello.c, a a program that
// exposes a single file "file.txt" in the root directory.
package main package main
import ( import (
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Mounts another directory as loopback for testing and benchmarking // This is main program driver for the loopback filesystem from
// purposes. // github.com/hanwen/go-fuse/fs/, a filesystem that shunts operations
// to an underlying file system.
package main package main
import ( import (
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This is main program driver for MultiZipFs from
// github.com/hanwen/go-fuse/zipfs, a filesystem for mounting multiple
// read-only archives. It can be used by symlinking to an archive file
// from the config/ subdirectory.
package main package main
import ( import (
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// statfs is a main driver for the file system from
// github.com/hanwen/go-fuse/benchmark, intended for benchmarking FUSE
// libraries.
package main package main
import ( import (
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This is main program driver for github.com/hanwen/go-fuse/zipfs, a
// filesystem for mounting read-only archives.
package main package main
import ( import (
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
// initialized by calling NewInode or NewPersistentInode before being // initialized by calling NewInode or NewPersistentInode before being
// manipulated further, eg. // manipulated further, eg.
// //
//
// type myNode struct { // type myNode struct {
// Inode // Inode
// } // }
...@@ -83,6 +82,9 @@ import ( ...@@ -83,6 +82,9 @@ import (
// InodeEmbedder is an interface for structs that embed Inode. // InodeEmbedder is an interface for structs that embed Inode.
// //
// InodeEmbedder objects usually should implement some of the NodeXxxx
// interfaces, to provide user-defined file system behaviors.
//
// In general, if an InodeEmbedder does not implement specific // In general, if an InodeEmbedder does not implement specific
// filesystem methods, the filesystem will react as if it is a // filesystem methods, the filesystem will react as if it is a
// read-only filesystem with a predefined tree structure. See // read-only filesystem with a predefined tree structure. See
...@@ -358,10 +360,17 @@ type NodeRenamer interface { ...@@ -358,10 +360,17 @@ type NodeRenamer interface {
Rename(ctx context.Context, name string, newParent InodeEmbedder, newName string, flags uint32) syscall.Errno Rename(ctx context.Context, name string, newParent InodeEmbedder, newName string, flags uint32) syscall.Errno
} }
// FileHandle is a resource identifier for opened files. FileHandles // FileHandle is a resource identifier for opened files. Usually, a
// are useful in two cases: First, if the underlying storage systems // FileHandle should implement some of the FileXxxx interfaces.
// needs a handle for reading/writing. See the function //
// `NewLoopbackFile` for an example. Second, it is useful for // All of the FileXxxx operations can also be implemented at the
// InodeEmbedder level, for example, one can implement NodeReader
// instead of FileReader.
//
// FileHandles are useful in two cases: First, if the underlying
// storage systems needs a handle for reading/writing. This is the
// case with Unix system calls, which need a file descriptor (See also
// the function `NewLoopbackFile`). Second, it is useful for
// implementing files whose contents are not tied to an inode. For // implementing files whose contents are not tied to an inode. For
// example, a file like `/proc/interrupts` has no fixed content, but // example, a file like `/proc/interrupts` has no fixed content, but
// changes on each open call. This means that each file handle must // changes on each open call. This means that each file handle must
......
...@@ -55,19 +55,24 @@ func (root *inMemoryFS) OnAdd(ctx context.Context) { ...@@ -55,19 +55,24 @@ func (root *inMemoryFS) OnAdd(ctx context.Context) {
p = ch p = ch
} }
// Make a file out of the content bytes. This type
// provides the open/read/flush methods.
embedder := &fs.MemRegularFile{
Data: []byte(content),
}
// Create the file. The Inode must be persistent, // Create the file. The Inode must be persistent,
// because its life time is not under control of the // because its life time is not under control of the
// kernel. // kernel.
child := p.NewPersistentInode(ctx, &fs.MemRegularFile{ child := p.NewPersistentInode(ctx, embedder, fs.StableAttr{})
Data: []byte(content),
}, fs.StableAttr{})
// And add it // And add it
p.AddChild(base, child, true) p.AddChild(base, child, true)
} }
} }
// This demonstrates how to build a file system in memory. // This demonstrates how to build a file system in memory. The
// read/write logic for the file is provided by the MemRegularFile type.
func Example() { func Example() {
// This is where we'll mount the FS // This is where we'll mount the FS
mntDir, _ := ioutil.TempDir("", "") mntDir, _ := ioutil.TempDir("", "")
......
...@@ -372,7 +372,8 @@ func (n *loopbackNode) Setattr(ctx context.Context, f FileHandle, in *fuse.SetAt ...@@ -372,7 +372,8 @@ func (n *loopbackNode) Setattr(ctx context.Context, f FileHandle, in *fuse.SetAt
} }
// NewLoopback returns a root node for a loopback file system whose // NewLoopback returns a root node for a loopback file system whose
// root is at the given root. // root is at the given root. This node implements all NodeXxxxer
// operations available.
func NewLoopbackRoot(root string) (InodeEmbedder, error) { func NewLoopbackRoot(root string) (InodeEmbedder, error) {
var st syscall.Stat_t var st syscall.Stat_t
err := syscall.Stat(root, &st) err := syscall.Stat(root, &st)
......
...@@ -13,7 +13,6 @@ import ( ...@@ -13,7 +13,6 @@ import (
// MemRegularFile is a filesystem node that holds a read-only data // MemRegularFile is a filesystem node that holds a read-only data
// slice in memory. // slice in memory.
type MemRegularFile struct { type MemRegularFile struct {
Inode Inode
Data []byte Data []byte
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This package is deprecated. New projects should use the package
// "github.com/hanwen/go-fuse/fs" instead.
//
// The nodefs package offers a high level API that resembles the // The nodefs package offers a high level API that resembles the
// kernel's idea of what an FS looks like. File systems can have // kernel's idea of what an FS looks like. File systems can have
// multiple hard-links to one file, for example. It is also suited if // multiple hard-links to one file, for example. It is also suited if
......
...@@ -40,8 +40,12 @@ func (d *connectorDir) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out * ...@@ -40,8 +40,12 @@ func (d *connectorDir) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *
} }
if input.Offset > uint64(len(d.stream)) { // XXX ">" -> ">=" if input.Offset > uint64(len(d.stream)) { // XXX ">" -> ">="
// This shouldn't happen, but let's not crash. // See https://github.com/hanwen/go-fuse/issues/297
return fuse.EINVAL // This can happen for FUSE exported over NFS. This
// seems incorrect, (maybe the kernel is using offsets
// from other opendir/readdir calls), it is harmless to reinforce that
// we have reached EOF.
return fuse.OK
} }
todo := d.stream[input.Offset:] todo := d.stream[input.Offset:]
...@@ -75,8 +79,8 @@ func (d *connectorDir) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, o ...@@ -75,8 +79,8 @@ func (d *connectorDir) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, o
} }
if input.Offset > uint64(len(d.stream)) { // XXX >= if input.Offset > uint64(len(d.stream)) { // XXX >=
// This shouldn't happen, but let's not crash. // See comment in Readdir
return fuse.EINVAL return fuse.OK
} }
todo := d.stream[input.Offset:] todo := d.stream[input.Offset:]
for _, e := range todo { for _, e := range todo {
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This package is deprecated. New projects should use the package
// "github.com/hanwen/go-fuse/fs" instead.
//
// Package pathfs provides a file system API expressed in filenames.
package pathfs package pathfs
import ( import (
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
// TODO - handle symlinks. // TODO - handle symlinks.
// HeaderToFileInfo fills a fuse.Attr struct from a tar.Header.
func HeaderToFileInfo(out *fuse.Attr, h *tar.Header) { func HeaderToFileInfo(out *fuse.Attr, h *tar.Header) {
out.Mode = uint32(h.Mode) out.Mode = uint32(h.Mode)
out.Size = uint64(h.Size) out.Size = uint64(h.Size)
...@@ -36,6 +37,9 @@ type tarRoot struct { ...@@ -36,6 +37,9 @@ type tarRoot struct {
rc io.ReadCloser rc io.ReadCloser
} }
// tarRoot implements NodeOnAdder
var _ = (fs.NodeOnAdder)((*tarRoot)(nil))
func (r *tarRoot) OnAdd(ctx context.Context) { func (r *tarRoot) OnAdd(ctx context.Context) {
tr := tar.NewReader(r.rc) tr := tar.NewReader(r.rc)
defer r.rc.Close() defer r.rc.Close()
...@@ -134,6 +138,9 @@ func (rc *readCloser) Close() error { ...@@ -134,6 +138,9 @@ func (rc *readCloser) Close() error {
return rc.close() return rc.close()
} }
// NewTarCompressedTree creates the tree of a tar file as a FUSE
// InodeEmbedder. The inode can either be mounted as the root of a
// FUSE mount, or added as a child to some other FUSE tree.
func NewTarCompressedTree(name string, format string) (fs.InodeEmbedder, error) { func NewTarCompressedTree(name string, format string) (fs.InodeEmbedder, error) {
f, err := os.Open(name) f, err := os.Open(name)
if err != nil { if err != nil {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment