.\" $NetBSD: puffs.3,v 1.19 2007/04/16 19:16:02 pooka Exp $ .\" .\" Copyright (c) 2006, 2007 Antti Kantee. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .Dd April 16, 2007 .Dt PUFFS 3 .Os .Sh NAME .Nm puffs .Nd Pass-to-Userspace Framework File System development interface .Sh LIBRARY .Lb libpuffs .Sh SYNOPSIS .In puffs.h .Ft struct puffs_usermount * .Fo puffs_init .Fa "struct puffs_ops *pops" "const char *puffsname" "void *private" .Fa "uint32_t flags" .Fc .Ft int .Fn puffs_domount "struct puffs_usermount *pu" "const char *dir" "int mntflags" .Ft struct puffs_usermount * .Fo puffs_mount .Fa "struct puffs_ops *pops" "const char *dir" "int mntflags" .Fa "const char *puffsname" "void *private" .Fa "uint32_t pflags" .Fc .Ft int .Fo puffs_start .Fa "struct puffs_usermount *pu" "void *rootcookie" "struct statvfs *svfsb" .Fc .Ft int .Fn puffs_mainloop "struct puffs_usermount *pu" "int flags" .Ft int .Fn puffs_getselectable "struct puffs_usermount *pu" .Ft int .Fn puffs_setblockingmode "struct puffs_usermount *pu" "int mode" .Ft int .Fn puffs_getstate "struct puffs_usermount *pu" .Ft int .Fn puffs_setstacksize "struct puffs_usermount *pu" "size_t stacksize" .Ft void .Fn puffs_setroot "struct puffs_usermount *pu" "struct puffs_node *node" .Ft struct puffs_node * .Fn puffs_getroot "struct puffs_usermount *pu" .Ft void * .Fn puffs_getspecific "struct puffs_usermount *pu" .Ft void .Fn puffs_setmaxreqlen "struct puffs_usermount *pu" "size_t maxreqlen" .Ft size_t .Fn puffs_getmaxreqlen "struct puffs_usermount *pu" .Ft void .Fn puffs_setfhsize "struct puffs_usermount *pu" "size_t fhsize" "int flags" .Ft void .Fn puffs_setncookiehash "struct puffs_usermount *pu" "int nhashes" .Sh DESCRIPTION .Em IMPORTANT NOTE! This document describes interfaces which are not yet guaranteed to be stable. In case you update your system sources, please recompile everything and fix complation errors. If your sources are out-of-sync, incorrect operation may result. The interfaces in this document will most likely be hugely simplified in later versions or made transparent to the implementation. .Pp .Nm provides a framework for creating file systems as userspace servers. Operations are transported from the kernel virtual file system layer to the concrete implementation behind .Nm , where they are processed and results are sent back to the kernel. .Pp It is possible to use .Nm in two different ways. Calling .Fn puffs_mainloop takes execution context away from the caller and automatically handles all requests by using the callbacks. Alternatively, control can be kept with the caller and operations handled manually. .Ss Library operation Operations on the library always require a poiter to the opaque context identifier, .Va struct puffs_usermount . There are two ways of acquiring this context: .Fn puffs_init and .Fn puffs_mount . They are equivalent except in the sense that the latter also proceeds to mount the file system. The former can be used when special parameters need to be set and only then proceed with mounting by calling .Fn puffs_domount . .Pp The callbacks are passed as the fields in the structure .Fa pops . They can be initialized using the macro .Fn PUFFSOP_SET pops fsname type opname , which will initialize the operation .Fn puffs_type_opname in .Fa pops to .Fn fsname_type_opname . All operations are initialized to a default state with the call .Fn PUFFSOP_INIT pops . All of the VFS routines are mandatory, but all of the node operations with the exception of .Fn puffs_fs_lookup are optional. However, leaving operations blank will naturally have an effect on the features available from the file system implementation. The argument .Fa dir signifies the mount point, .Fa mntflags is the flagset given to .Xr mount 2 , and .Fa puffsname is the name of the file system implementation. The parameter .Fa private is stored within the context structure and can be retrieved by calling .Fn puffs_getspecific . Flags for .Nm can be given via .Fa pflags . Currently the following flags are supported: .Bl -tag -width "XPUFFS_KFLAG_BUILDPATHX" .It Dv PUFFS_KFLAG_NOCACHE Do not cache anything in the kernel. Currently this means not using the page cache for regular files or the name cache (directory entry cache) for all files. This is useful if the file system does not want to include flushing and invalidation logic in case it is possible to modify the backend from "under" our view of the file system (a distributed file system, for example). .It Dv PUFFS_KFLAG_ALLOPS This flag requests that all operations are sent to userspace. Normally the kernel shortcircuits unimplemented operations. This flag is mostly useful for debugging purposes. .It Dv PUFFS_FLAG_BUILDPATH The framework will build a complete path name, which is supplied with each operation and can be found from the .Va pn_po.po_full_pcn field in a .Vt struct puffs_node . The option assumes that the framework can map a cookie to a .Vt struct puffs_node . See .Sx Cookies for more information on cookie mapping. See .Xr puffs_path 3 for more information on library calls involving paths. .It Dv PUFFS_FLAG_OPDUMP This option makes the framework dump a textual representation of each operation before executing it. It is useful for debugging purposes. .El .Pp The following functions can be used to query or modify the global state of the file system. Note, that all calls are not available at all times. .Bl -tag -width xxxx .It Fn puffs_getselectable "pu" Returns a handle to do I/O multiplexing with: .Xr select 2 , .Xr poll 2 , and .Xr kqueue 2 are all examples of acceptable operations. .It Fn puffs_setblockingmode "pu" "mode" Sets the library to blocking or non-blocking mode. Acceptable values for the argument are .Dv PUFFSDEV_BLOCK and .Dv PUFFSDEV_NONBLOCK . .It Fn puffs_getstate "pu" Returns the state of the file system. It is maintained by the framework and is mostly useful for the framework itself. Possible values are .Dv PUFFS_STATE_MOUNTING , .Dv PUFFS_STATE_RUNNING , .Dv PUFFS_STATE_UNMOUNTING and .Dv PUFFS_STATE_UNMOUNTED . .It Fn puffs_setstacksize "stacksize" Sets the stack size used when running callbacks. The default is one megabyte of stack space per request. See .Xr puffs_cc 3 . .It Fn puffs_setroot "pu" "node" Sets the root node of mount .Fa pu to .Fa "node" . Setting the root node is currently required only if the path framework is used, see .Xr puffs_path 3 . .Pp This, if desired, should be done before the file system is activated with .Fn puffs_start . .It Fn puffs_getroot "pu" Returns the root node set earlier. .It Fn puffs_getspecific "pu" Returns the .Fa private argument of .Fn puffs_mount . .It Fn puffs_setmaxreqlen "pu" "maxreqlen" In case the file system desires a maximum buffer length different from the default, the amount .Fa maxreqlen will be requested from the kernel when the file system is mounted. .Pp It is legal to call this function only between .Fn puffs_init and .Fn puffs_domount . .It Fn puffs_getmaxreqlen "pu" Returns the maximum request length the kernel will need for a single request. This information can be used to allocate the request buffer and .B must be passed as the parameter to .Fn puffs_req_makeget . .It Fn puffs_setfhsize "pu" "fhsize" "flags" Sets the desired file handle size. This must be called if the file system wishes to support nfs exporting file systems of the .Fn fh* family of function calls. .Pp In case all nodes in the file system produce the same length file handle, it must be supplied as .Fa fhsize . In this case, the file system may ignore the length parameters in the file handle callback routines, as the kernel will always pass the correct length buffer. However, if the file handle size varies according to file, the argument .Fa fhsize defines the maximum size of a file handle for the file system. In this case the file system must take care of the handle lengths by itself in the file handle callbacks, see .Xr puffs_ops 3 for more information. Also, the flag .Dv PUFFS_FHFLAG_DYNAMIC must be provided in the argument .Fa flags . .Pp In case the file system wants to sanity check its file handle lengths for the limits of NFS, it can supply .Dv PUFFS_FHFLAG_NFSV2 and .Dv PUFFS_FHFLAG_NFSV3 in the .Fa flags parameter. It is especially important to note that these are not directly the limits specified by the protocols, as the kernel uses some bytes from the buffer space. In case the file handles are too large, mount will return an error. .Pp It is legal to call this function only between .Fn puffs_init and .Fn puffs_domount . .It Fn puffs_setncookiehash "pu" "ncookiehash" The parameter .Fa ncookiehash controls the amount of hash buckets the kernel has for reverse lookups from cookie to vnode. Technically the default is enough, but a memory/time tradeoff can be made by increasing this for file systems which know they will have very many active files. .Pp It is legal to call this function only between .Fn puffs_init and .Fn puffs_domount . .El .Pp After the correct setup for the library has been established and the backend has been initialized (and the file system has been mounted if .Fn puffs_init was used to acquire the usermount context!), the file system is made operational by calling .Fn puffs_start . Immediately after the return of this function the file system must be ready to process requests. .Pp To handle all requests automatically until the file system is unmounted, .Fn puffs_mainloop should be used. It returns 0 if the file system was succesfully unmounted or \-1 if it was killed in action. Unless .Fa flags is used to pass .Dv PUFFSLOOP_NODAEMON , .Fn puffs_mainloop will also detach from the terminal. .Ss Cookies Every file (regular file, directory, device node, ...) instance is attached to the kernel using a cookie. A cookie should uniquely map to a file during its lifetime. If file instances are kept in memory, a simple strategy is to use the virtual address of the structure describing the file. The cookie can be recycled when .Fn puffs_node_reclaim is called for a node. .Pp For some operations (such as building paths) the framework needs to map the cookie to the framework-level structure describing a file, .Vt struct puffs_node . It is advisable to simply use the .Vt struct puffs_node address as a cookie and store file system specific data in the private portion of .Vt struct puffs_node . The library assumes this by default. If it is not desireable, the file system implementation can call .Fn puffs_set_cookiemap to provide an alternative cookie-to-node mapping function. .Sh SEE ALSO .Xr puffs_cc 3 , .Xr puffs_cred 3 , .Xr puffs_flush 3 , .Xr puffs_node 3 , .Xr puffs_ops 3 , .Xr puffs_path 3 , .Xr puffs_req 3 , .Xr puffs_suspend 3 , .Xr puffs 4 .Rs .%A Antti Kantee .%D March 2007 .%J Proceedings of AsiaBSDCon 2007 .%P pp. 29-42 .%T puffs - Pass-to-Userspace Framework File System .Re .Sh HISTORY An unsupported experimental version of .Nm first appeared in .Nx 4.0 . .Sh AUTHORS .An Antti Kantee Aq pooka@iki.fi .Sh BUGS Under construction.