PUFFS(4)                NetBSD Kernel Interfaces Manual               PUFFS(4)

NAME
     puffs -- Pass-to-Userspace Framework File System

SYNOPSIS
     file-system PUFFS
     pseudo-device putter

DESCRIPTION
     THIS DOCUMENT IS HOPELESSLY OUT OF DATE.  While some parts are still
     valid, please refer to the source code for current reality.

     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 compilation errors.  If your sources are
     out-of-sync, incorrect operation may result.

     puffs provides a framework for creating file systems as userspace
     servers.  The in-kernel VFS attachment is controlled through a special
     device node, /dev/puffs.  This document describes the operations on the
     device.  People looking to implement file systems should prefer using the
     system through the convenience library described in puffs(3).  Users
     wanting to access the device node directly should include the header
     sys/fs/puffs/puffs_msgif.h for relevant definitions.

   Mounting
     The puffs device node should be opened once per file system instance
     (i.e. mount).  The device itself is a cloning node, so the same node can
     be opened a practically unlimited number of times.  Once the device is
     open, the file system can be mounted the normal way using the mount(2)
     system call and using the argument structure to control mount options:

           struct puffs_args {
                   int             pa_vers;
                   int             pa_fd;
                   unsigned int    pa_flags;
                   size_t          pa_maxreqlen;
                   char            pa_name[PUFFSNAMESIZE];
                   uint8_t         pa_vnopmask[PUFFS_VN_MAX];
           };

     The member pa_vers is currently always 0 and ignored.  The pa_fd member
     is the file descriptor number from opening the device node.  pa_flags
     controls some operations specific to puffs:

     PUFFS_KFLAG_ALLOWCTL  Allow file system fcntl and ioctl operations.
                           Allowing these has security implications as the
                           file system can technically read anything out of a
                           calling processes address space.  This flag may
                           additionally be enforced by the kernel security
                           policy.

     PUFFS_KFLAG_NOCACHE   Do not store data in the page cache.  This causes
                           operations to always consult the user server
                           instead of consulting the page cache.  This makes
                           sense in situations where there is relatively lit-
                           tle bulk data to be transferred and the user server
                           does not want to take part in complex cache manage-
                           ment routines in case the file system data can be
                           modified through routes other than the file system
                           interface.

     PUFFS_KFLAG_ALLOPS    Transport all vnode operations to the file system
                           server instead of just the ones specified by
                           pa_vnopmask.

     The pa_maxreqlen member signifies the length of the incoming data buffer
     in userspace.  A good value is PUFFS_REQ_MAXSIZE, which is the maximum
     the kernel will use.  A minimum value is also enforced, so the value of
     this field should be checked after the mount operation to determine the
     correct buffer size.  During operation, in case request fetch is
     attempted with a buffer too short, the error E2BIG will be returned.  The
     file system type is give in pa_name.  It will always be prepended by
     "puffs:" by the kernel.  Finally, the array pa_vnopmask specifies which
     operations are supported by the file system server.  The array is indexed
     with PUFFS_VN_FOO and 0 means vnode operation FOO is unimplemented while
     non-zero means an implemented operation.  This array is ignored if
     PUFFS_KFLAG_ALLOPS is given.

     After a successful mount system call, the the ioctl PUFFSSTARTOP must be
     issued through the open device node.  The parameter for this ioctl is the
     following structure:

           struct puffs_startreq {
                   void            *psr_cookie;
                   struct statvfs  psr_sb;
           };

     The member psr_cookie should be set before calling.  This signals the
     cookie value of the root node of the file system (see puffs(3) for more
     details on cookie strategies).  The value of psr_sb should be filled with
     the same results as for a regular statvfs call.  After successfully exe-
     cuting this operation the file system is active.

   Operation
     Operations must be queried from the kernel using the ioctl PUFFSGETOP,
     processed, and the results pushed back to the kernel using PUFFSPUTOP.
     Normally the system will block until an event is available for
     PUFFSGETOP, but it is possible to set the file descriptor into non-block-
     ing mode, in which case EWOULDBLOCK is returned if no event is available.
     Asynchronous I/O calls (i.e., select(2), poll(2), and kevent(2)) can be
     issued to be notified of events.

     As the argument both get and push use the following structure:

           struct puffs_req {
                   uint64_t        preq_id;
                   uint8_t         preq_opclass;
                   uint8_t         preq_optype;
                   void            *preq_cookie;

                   int             preq_rv;

                   void            *preq_aux;
                   size_t          preq_auxlen;
           };

     The member preq_id is used as an identifier in the reply.  It should not
     be modified during the processing of a PUFFSGETOP - PUFFSPUTOP sequence.
     The members preq_opclass and preq_optype identify the request; they also
     are used for typing the data pointed to by preq_aux.  Currently the map-
     ping between these two is only documented in code in
     src/lib/libpuffs/puff.c:puffcall().  The handling of this will very
     likely change in the future towards a more automatic direction.  The
     length of the buffer given to PUFFSGETOP is described by preq_auxlen and
     will be modified by the kernel to indicate how much data actually was
     transmitted.  This is for the benefit of calls such as write, which
     transmit a variable amount of data.  Similarly, the user server should
     fill in the amount of data the kernel must copy for PUFFSPUTOP; most of
     the time this will be constant for a given operation, but operations such
     as read want to adjust it dynamically.  Finally, preq_rv is used by the
     userspace server to fill in the success value of the operation in ques-
     tion.

     In case the macro PUFFSOP_WANTREPLY() returns false for preq_opclass, a
     return value is not wanted and PUFFSPUTOP should not be issued.

     Additionally, an operation of type PUFFSSIZEOP is supported, but it is
     only used by the ioctl and fcntl operations and will likely go away in
     the future.  It is not described here.

   Termination
     The file system can be unmounted regularly using umount(8).  It will
     automatically be unmounted in case the userspace server is killed or the
     control file descriptor closed, but in this case the userspace server
     will not be separately requested to unmount itself and this may result in
     data loss.

SEE ALSO
     ioctl(2), mount(2), puffs(3), umount(8)

     Antti Kantee, "puffs - Pass-to-Userspace Framework File System",
     Proceedings of AsiaBSDCon 2007, pp. 29-42, March 2007.

HISTORY
     An unsupported experimental version of puffs first appeared in
     NetBSD 4.0.

AUTHORS
     Antti Kantee <pooka@iki.fi>

BUGS
     puffs is currently more like a souffle than puff pastry.

NetBSD 5.0_STABLE              December 1, 2006              NetBSD 5.0_STABLE
