The nodefs package offers a high level API that resembles the 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 the data to represent fits in memory: you can construct the complete file system tree at mount time



    View Source
    const (
    	F_OFD_GETLK  = 36
    	F_OFD_SETLK  = 37
    	F_OFD_SETLKW = 38


    This section is empty.


    This section is empty.


    type File

    type File interface {
    	// Called upon registering the filehandle in the inode. This
    	// is useful in that PathFS API, where Create/Open have no
    	// access to the Inode at hand.
    	// The String method is for debug printing.
    	String() string
    	// Wrappers around other File implementations, should return
    	// the inner file here.
    	InnerFile() File
    	Read(dest []byte, off int64) (fuse.ReadResult, fuse.Status)
    	Write(data []byte, off int64) (written uint32, code fuse.Status)
    	// File locking
    	GetLk(owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (code fuse.Status)
    	SetLk(owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status)
    	SetLkw(owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status)
    	// Flush is called for close() call on a file descriptor. In
    	// case of duplicated descriptor, it may be called more than
    	// once for a file.
    	Flush() fuse.Status
    	// This is called to before the file handle is forgotten. This
    	// method has no return value, so nothing can synchronizes on
    	// the call. Any cleanup that requires specific synchronization or
    	// could fail with I/O errors should happen in Flush instead.
    	Fsync(flags int) (code fuse.Status)
    	// The methods below may be called on closed files, due to
    	// concurrency.  In that case, you should return EBADF.
    	Truncate(size uint64) fuse.Status
    	GetAttr(out *fuse.Attr) fuse.Status
    	Chown(uid uint32, gid uint32) fuse.Status
    	Chmod(perms uint32) fuse.Status
    	Utimens(atime *time.Time, mtime *time.Time) fuse.Status
    	Allocate(off uint64, size uint64, mode uint32) (code fuse.Status)

      A File object is returned from FileSystem.Open and FileSystem.Create. Include the NewDefaultFile return value into the struct to inherit a null implementation.

      func NewDataFile

      func NewDataFile(data []byte) File

      func NewDefaultFile

      func NewDefaultFile() File

        NewDefaultFile returns a File instance that returns ENOSYS for every operation.

        func NewDevNullFile

        func NewDevNullFile() File

          NewDevNullFile returns a file that accepts any write, and always returns EOF for reads.

          func NewLockingFile

          func NewLockingFile(mu *sync.Mutex, f File) File

            NewLockingFile serializes operations an existing File.

            func NewLoopbackFile

            func NewLoopbackFile(f *os.File) File

              LoopbackFile delegates all operations back to an underlying os.File.

              func NewReadOnlyFile

              func NewReadOnlyFile(f File) File

                NewReadOnlyFile wraps a File so all write operations are denied.

                type FileSystemConnector

                type FileSystemConnector struct {
                	// contains filtered or unexported fields

                  FileSystemConnector translates the raw FUSE protocol (serialized structs of uint32/uint64) to operations on Go objects representing files and directories.

                  func MountRoot

                  func MountRoot(mountpoint string, root Node, opts *Options) (*fuse.Server, *FileSystemConnector, error)

                    MountRoot mounts a filesystem with the given root node on the given directory. Convenience wrapper around fuse.NewServer

                    func NewFileSystemConnector

                    func NewFileSystemConnector(root Node, opts *Options) (c *FileSystemConnector)

                      NewFileSystemConnector creates a FileSystemConnector with the given options.

                      func (*FileSystemConnector) DeleteNotify

                      func (c *FileSystemConnector) DeleteNotify(dir *Inode, child *Inode, name string) fuse.Status

                        DeleteNotify signals to the kernel that the named entry in dir for the child disappeared. No filesystem related locks should be held when calling this.

                        func (*FileSystemConnector) EntryNotify

                        func (c *FileSystemConnector) EntryNotify(node *Inode, name string) fuse.Status

                          EntryNotify makes the kernel forget the entry data from the given name from a directory. After this call, the kernel will issue a new lookup request for the given name when necessary. No filesystem related locks should be held when calling this.

                          func (*FileSystemConnector) FileNotify

                          func (c *FileSystemConnector) FileNotify(node *Inode, off int64, length int64) fuse.Status

                            FileNotify notifies the kernel that data and metadata of this inode has changed. After this call completes, the kernel will issue a new GetAttr requests for metadata and new Read calls for content. Use negative offset for metadata-only invalidation, and zero-length for invalidating all content.

                            func (*FileSystemConnector) FileNotifyStoreCache

                            func (c *FileSystemConnector) FileNotifyStoreCache(node *Inode, off int64, data []byte) fuse.Status

                              FileNotifyStoreCache notifies the kernel about changed data of the inode.

                              This call is similar to FileNotify, but instead of only invalidating a data region, it puts updated data directly to the kernel cache:

                              After this call completes, the kernel has put updated data into the inode's cache, and will use data from that cache for non direct-IO reads from the inode in corresponding data region. After kernel's cache data is evicted, the kernel will have to issue new Read calls on user request to get data content.

                              ENOENT is returned if the kernel does not currently have entry for this inode in its dentry cache.

                              func (*FileSystemConnector) FileRetrieveCache

                              func (c *FileSystemConnector) FileRetrieveCache(node *Inode, off int64, dest []byte) (n int, st fuse.Status)

                                FileRetrieveCache retrieves data from kernel's inode cache.

                                This call retrieves data from kernel's inode cache @ offset and up to len(dest) bytes. If kernel cache has fewer consecutive data starting at offset, that fewer amount is returned. In particular if inode data at offset is not cached (0, OK) is returned.

                                If the kernel does not currently have entry for this inode in its dentry cache (0, OK) is still returned, pretending that the inode could be known to the kernel, but kernel's inode cache is empty.

                                func (*FileSystemConnector) InodeHandleCount

                                func (c *FileSystemConnector) InodeHandleCount() int

                                  InodeCount returns the number of inodes registered with the kernel.

                                  func (*FileSystemConnector) LookupNode

                                  func (c *FileSystemConnector) LookupNode(parent *Inode, path string) *Inode

                                    Follows the path from the given parent, doing lookups as necessary. The path should be '/' separated without leading slash.

                                    func (*FileSystemConnector) Mount

                                    func (c *FileSystemConnector) Mount(parent *Inode, name string, root Node, opts *Options) fuse.Status

                                      Mount() generates a synthetic directory node, and mounts the file system there. If opts is nil, the mount options of the root file system are inherited. The encompassing filesystem should pretend the mount point does not exist.

                                      It returns ENOENT if the directory containing the mount point does not exist, and EBUSY if the intended mount point already exists.

                                      func (*FileSystemConnector) Node

                                      func (c *FileSystemConnector) Node(parent *Inode, fullPath string) (*Inode, []string)

                                        Finds a node within the currently known inodes, returns the last known node and the remaining unknown path components. If parent is nil, start from FUSE mountpoint.

                                        func (*FileSystemConnector) RawFS

                                          Returns the RawFileSystem so it can be mounted.

                                          func (*FileSystemConnector) Server

                                          func (c *FileSystemConnector) Server() *fuse.Server

                                            Server returns the fuse.Server that talking to the kernel.

                                            func (*FileSystemConnector) SetDebug

                                            func (c *FileSystemConnector) SetDebug(debug bool)

                                              SetDebug toggles printing of debug information. This function is deprecated. Set the Debug option in the Options struct instead.

                                              func (*FileSystemConnector) Unmount

                                              func (c *FileSystemConnector) Unmount(node *Inode) fuse.Status

                                                Unmount() tries to unmount the given inode. It returns EINVAL if the path does not exist, or is not a mount point, and EBUSY if there are open files or submounts below this node.

                                                type Inode

                                                type Inode struct {
                                                	// contains filtered or unexported fields

                                                  An Inode reflects the kernel's idea of the inode. Inodes have IDs that are communicated to the kernel, and they have a tree structure: a directory Inode may contain named children. Each Inode object is paired with a Node object, which file system implementers should supply.

                                                  func (*Inode) AddChild

                                                  func (n *Inode) AddChild(name string, child *Inode)

                                                    AddChild adds a child inode. The parent inode must be a directory node.

                                                    func (*Inode) AnyFile

                                                    func (n *Inode) AnyFile() (file File)

                                                      Returns any open file, preferably a r/w one.

                                                      func (*Inode) Children

                                                      func (n *Inode) Children() (out map[string]*Inode)

                                                        Children returns all children of this inode.

                                                        func (*Inode) Files

                                                        func (n *Inode) Files(mask uint32) (files []WithFlags)

                                                          Files() returns an opens file that have bits in common with the give mask. Use mask==0 to return all files.

                                                          func (*Inode) FsChildren

                                                          func (n *Inode) FsChildren() (out map[string]*Inode)

                                                            FsChildren returns all the children from the same filesystem. It will skip mountpoints.

                                                            func (*Inode) GetChild

                                                            func (n *Inode) GetChild(name string) (child *Inode)

                                                              GetChild returns a child inode with the given name, or nil if it does not exist.

                                                              func (*Inode) IsDir

                                                              func (n *Inode) IsDir() bool

                                                                IsDir returns true if this is a directory.

                                                                func (*Inode) NewChild

                                                                func (n *Inode) NewChild(name string, isDir bool, fsi Node) *Inode

                                                                  NewChild adds a new child inode to this inode.

                                                                  func (*Inode) Node

                                                                  func (n *Inode) Node() Node

                                                                    Node returns the file-system specific node.

                                                                    func (*Inode) Parent

                                                                    func (n *Inode) Parent() (parent *Inode, name string)

                                                                      Parent returns a random parent and the name this inode has under this parent. This function can be used to walk up the directory tree. It will not cross sub-mounts.

                                                                      func (*Inode) RmChild

                                                                      func (n *Inode) RmChild(name string) (ch *Inode)

                                                                        RmChild removes an inode by name, and returns it. It returns nil if child does not exist.

                                                                        func (*Inode) String

                                                                        func (n *Inode) String() string

                                                                          Print the inode. The default print method may not be used for debugging, as dumping the map requires synchronization.

                                                                          type Node

                                                                          type Node interface {
                                                                          	// Inode and SetInode are basic getter/setters.  They are
                                                                          	// called by the FileSystemConnector. You get them for free by
                                                                          	// embedding the result of NewDefaultNode() in your node
                                                                          	// struct.
                                                                          	Inode() *Inode
                                                                          	SetInode(node *Inode)
                                                                          	// OnMount is called on the root node just after a mount is
                                                                          	// executed, either when the actual root is mounted, or when a
                                                                          	// filesystem is mounted in-process. The passed-in
                                                                          	// FileSystemConnector gives access to Notify methods and
                                                                          	// Debug settings.
                                                                          	OnMount(conn *FileSystemConnector)
                                                                          	// OnUnmount is executed just before a submount is removed,
                                                                          	// and when the process receives a forget for the FUSE root
                                                                          	// node.
                                                                          	// Lookup finds a child node to this node; it is only called
                                                                          	// for directory Nodes. Lookup may be called on nodes that are
                                                                          	// already known.
                                                                          	Lookup(out *fuse.Attr, name string, context *fuse.Context) (*Inode, fuse.Status)
                                                                          	// Deletable() should return true if this node may be discarded once
                                                                          	// the kernel forgets its reference.
                                                                          	// If it returns false, OnForget will never get called for this node. This
                                                                          	// is appropriate if the filesystem has no persistent backing store
                                                                          	// (in-memory filesystems) where discarding the node loses the stored data.
                                                                          	// Deletable will be called from within the treeLock critical section, so you
                                                                          	// cannot look at other nodes.
                                                                          	Deletable() bool
                                                                          	// OnForget is called when the kernel forgets its reference to this node and
                                                                          	// sends a FORGET request. It should perform cleanup and free memory as
                                                                          	// appropriate for the filesystem.
                                                                          	// OnForget is not called if the node is a directory and has children.
                                                                          	// This is called from within a treeLock critical section.
                                                                          	// Misc.
                                                                          	Access(mode uint32, context *fuse.Context) (code fuse.Status)
                                                                          	Readlink(c *fuse.Context) ([]byte, fuse.Status)
                                                                          	// Mknod should create the node, add it to the receiver's
                                                                          	// inode, and return it
                                                                          	Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (newNode *Inode, code fuse.Status)
                                                                          	// Mkdir should create the directory Inode, add it to the
                                                                          	// receiver's Inode, and return it
                                                                          	Mkdir(name string, mode uint32, context *fuse.Context) (newNode *Inode, code fuse.Status)
                                                                          	Unlink(name string, context *fuse.Context) (code fuse.Status)
                                                                          	Rmdir(name string, context *fuse.Context) (code fuse.Status)
                                                                          	// Symlink should create a child inode to the receiver, and
                                                                          	// return it.
                                                                          	Symlink(name string, content string, context *fuse.Context) (*Inode, fuse.Status)
                                                                          	Rename(oldName string, newParent Node, newName string, context *fuse.Context) (code fuse.Status)
                                                                          	// Link should return the Inode of the resulting link. In
                                                                          	// a POSIX conformant file system, this should add 'existing'
                                                                          	// to the receiver, and return the Inode corresponding to
                                                                          	// 'existing'.
                                                                          	Link(name string, existing Node, context *fuse.Context) (newNode *Inode, code fuse.Status)
                                                                          	// Create should return an open file, and the Inode for that file.
                                                                          	Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, child *Inode, code fuse.Status)
                                                                          	// Open opens a file, and returns a File which is associated
                                                                          	// with a file handle. It is OK to return (nil, OK) here. In
                                                                          	// that case, the Node should implement Read or Write
                                                                          	// directly.
                                                                          	Open(flags uint32, context *fuse.Context) (file File, code fuse.Status)
                                                                          	OpenDir(context *fuse.Context) ([]fuse.DirEntry, fuse.Status)
                                                                          	Read(file File, dest []byte, off int64, context *fuse.Context) (fuse.ReadResult, fuse.Status)
                                                                          	Write(file File, data []byte, off int64, context *fuse.Context) (written uint32, code fuse.Status)
                                                                          	// XAttrs
                                                                          	GetXAttr(attribute string, context *fuse.Context) (data []byte, code fuse.Status)
                                                                          	RemoveXAttr(attr string, context *fuse.Context) fuse.Status
                                                                          	SetXAttr(attr string, data []byte, flags int, context *fuse.Context) fuse.Status
                                                                          	ListXAttr(context *fuse.Context) (attrs []string, code fuse.Status)
                                                                          	// File locking
                                                                          	// GetLk returns existing lock information for file.
                                                                          	GetLk(file File, owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock, context *fuse.Context) (code fuse.Status)
                                                                          	// Sets or clears the lock described by lk on file.
                                                                          	SetLk(file File, owner uint64, lk *fuse.FileLock, flags uint32, context *fuse.Context) (code fuse.Status)
                                                                          	// Sets or clears the lock described by lk. This call blocks until the operation can be completed.
                                                                          	SetLkw(file File, owner uint64, lk *fuse.FileLock, flags uint32, context *fuse.Context) (code fuse.Status)
                                                                          	// Attributes
                                                                          	GetAttr(out *fuse.Attr, file File, context *fuse.Context) (code fuse.Status)
                                                                          	Chmod(file File, perms uint32, context *fuse.Context) (code fuse.Status)
                                                                          	Chown(file File, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status)
                                                                          	Truncate(file File, size uint64, context *fuse.Context) (code fuse.Status)
                                                                          	Utimens(file File, atime *time.Time, mtime *time.Time, context *fuse.Context) (code fuse.Status)
                                                                          	Fallocate(file File, off uint64, size uint64, mode uint32, context *fuse.Context) (code fuse.Status)
                                                                          	StatFs() *fuse.StatfsOut

                                                                            The Node interface implements the user-defined file system functionality

                                                                            func NewDefaultNode

                                                                            func NewDefaultNode() Node

                                                                              NewDefaultNode returns an implementation of Node that returns ENOSYS for all operations.

                                                                              func NewMemNodeFSRoot

                                                                              func NewMemNodeFSRoot(prefix string) Node

                                                                                NewMemNodeFSRoot creates an in-memory node-based filesystem. Files are written into a backing store under the given prefix.

                                                                                type Options

                                                                                type Options struct {
                                                                                	EntryTimeout    time.Duration
                                                                                	AttrTimeout     time.Duration
                                                                                	NegativeTimeout time.Duration
                                                                                	// If set, replace all uids with given UID.
                                                                                	// NewOptions() will set this to the daemon's
                                                                                	// uid/gid.
                                                                                	// This option exists for compatibility and is ignored.
                                                                                	PortableInodes bool
                                                                                	// If set, print debug information.
                                                                                	Debug bool
                                                                                	// If set, issue Lookup rather than GetAttr calls for known
                                                                                	// children. This allows the filesystem to update its inode
                                                                                	// hierarchy in response to kernel calls.
                                                                                	LookupKnownChildren bool

                                                                                  Options contains time out options for a node FileSystem. The default copied from libfuse and set in NewMountOptions() is (1s,1s,0s).

                                                                                  func NewOptions

                                                                                  func NewOptions() *Options

                                                                                    NewOptions generates FUSE options that correspond to libfuse's defaults.

                                                                                    type TreeWatcher

                                                                                    type TreeWatcher interface {
                                                                                    	OnAdd(parent *Inode, name string)
                                                                                    	OnRemove(parent *Inode, name string)

                                                                                      TreeWatcher is an additional interface that Nodes can implement. If they do, the OnAdd and OnRemove are called for operations on the file system tree. These functions run under a lock, so they should not do blocking operations.

                                                                                      type WithFlags

                                                                                      type WithFlags struct {
                                                                                      	// For debugging.
                                                                                      	Description string
                                                                                      	// Put FOPEN_* flags here.
                                                                                      	FuseFlags uint32
                                                                                      	// O_RDWR, O_TRUNCATE, etc.
                                                                                      	OpenFlags uint32

                                                                                        Wrap a File return in this to set FUSE flags. Also used internally to store open file data.

                                                                                        func (*WithFlags) String

                                                                                        func (f *WithFlags) String() string

                                                                                          String provides a debug string for the given file.