Updated: 2022/Sep/29

Please read Privacy Policy. It's for your privacy.

PUFFS(3)                   Library Functions Manual                   PUFFS(3)

     puffs - Pass-to-Userspace Framework File System development interface

     puffs Convenience Library (libpuffs, -lpuffs)

     #include <puffs.h>

     struct puffs_usermount *
     puffs_init(struct puffs_ops *pops, const char *mntfromname,
         const char *puffsname, void *private, uint32_t flags);

     puffs_mount(struct puffs_usermount *pu, const char *dir, int mntflags,
         puffs_cookie_t root_cookie);

     puffs_getselectable(struct puffs_usermount *pu);

     puffs_setblockingmode(struct puffs_usermount *pu, int mode);

     puffs_getstate(struct puffs_usermount *pu);

     puffs_setstacksize(struct puffs_usermount *pu, size_t stacksize);

     puffs_setroot(struct puffs_usermount *pu, struct puffs_node *node);

     puffs_setrootinfo(struct puffs_usermount *pu, enum vtype vt,
         size_t vsize, dev_t rdev);

     struct puffs_node *
     puffs_getroot(struct puffs_usermount *pu);

     void *
     puffs_getspecific(struct puffs_usermount *pu);

     puffs_setspecific(struct puffs_usermount *pu, void *private);

     puffs_setmaxreqlen(struct puffs_usermount *pu, size_t maxreqlen);

     puffs_getmaxreqlen(struct puffs_usermount *pu);

     puffs_setfhsize(struct puffs_usermount *pu, size_t fhsize, int flags);

     puffs_setncookiehash(struct puffs_usermount *pu, int nhashes);

     puffs_ml_loop_fn(struct puffs_usermount *pu);

     puffs_ml_setloopfn(struct puffs_usermount *pu, puffs_ml_loop_fn lfn);

     puffs_ml_settimeout(struct puffs_usermount *pu, struct timespec *ts);

     puffs_daemon(struct puffs_usermount *pu, int nochdir, int noclose);

     puffs_mainloop(struct puffs_usermount *pu);

     puffs_unmountonsignal(int sig, bool ignoresig);

     puffs_dispatch_create(struct puffs_usermount *pu,
         struct puffs_framebuf *pb, struct puffs_cc **pccp);

     puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp);

     puffs 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 puffs, where they are
     processed and results are sent back to the kernel.

     It is possible to use puffs in two different ways.  Calling
     puffs_mainloop() takes execution context away from the caller and
     automatically handles all requests by using the callbacks.  By using
     puffs_framebuf(3) in conjunction with puffs_mainloop(), it is possible to
     handle I/O to and from file descriptors.  This is suited e.g. for
     distributed file servers.

   Library operation
     Operations on the library always require a pointer to the opaque context
     identifier, struct puffs_usermount.  It is obtained by calling

     puffs operates using operation callbacks.  They can be initialized using
     the macro PUFFSOP_SET(pops, fsname, type, opname), which will initialize
     the operation puffs_type_opname() in pops to fsname_type_opname().  All
     operations are initialized to a default state with the call
     PUFFSOP_INIT(pops).  All of the VFS routines are mandatory, but all of
     the node operations with the exception of puffs_node_lookup() are
     optional.  However, leaving operations blank will naturally have an
     effect on the features available from the file system implementation.

     puffs_init(pops, mntfromname, puffsname, private, flags)
           Initializes the library context.  pops specifies the callback
           operations vector.  mntfromname is device the file system is
           mounted from.  This can be for example a block device such as
           /dev/wd0a or, if the file system is pseudo file system, the puffs
           device name can be given by _PATH_PUFFS.  This value is used for
           example in the first column of the output of mount(8) and df(1).
           puffsname is the file system type.  It will always be prepended
           with the string "puffs|".  If possible, file server binaries should
           be named using the format "mount_myfsnamehere" and this value
           should equal "myfsnamehere".  A file system specific context
           pointer can optionally be given in private.  This can be retrieved
           by puffs_getspecific().  Flags for puffs can be given via flags.
           Currently the following flags are supported:

           PUFFS_KFLAG_NOCACHE_NAME       Do not enter pathname components
                                          into the name cache.  This means
                                          that every time the kernel does a
                                          lookup for a componentname, the file
                                          server will be consulted.

           PUFFS_KFLAG_NOCACHE_PAGE       Do not use the page cache.  This
                                          means that all reads and writes to
                                          regular file are propagated to the
                                          file server for handling.  This
                                          option makes a difference only for
                                          regular files.

           PUFFS_KFLAG_NOCACHE            An alias for both
                                          PUFFS_KFLAG_NOCACHE_NAME and

           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

           PUFFS_KFLAG_WTCACHE            Set the file system cache behavior
                                          as write-through.  This means that
                                          all writes are immediately issued to
                                          the file server instead of being
                                          flushed in file system sync.  This
                                          is useful especially for distributed
                                          file systems.

           PUFFS_KFLAG_IAONDEMAND         Issue inactive only on demand.  If a
                                          file server defines the inactive
                                          method, call it only if the file
                                          server has explicitly requested that
                                          inactive be called for the node in
                                          question.  Once inactive has been
                                          called for a node, it will not be
                                          called again unless the request to
                                          call inactive is reissued by the
                                          file server.  See puffs_setback() in
                                          puffs_ops(3) for more information.

           PUFFS_KFLAG_LOOKUP_FULLPNBUF   This flag affects only the parameter
                                          pcn to puffs_node_lookup().  If this
                                          flag is not given, only the next
                                          pathname component under lookup is
                                          found from pcn->pcn_name.  If this
                                          flag is given, the full path the
                                          kernel was asked to resolve can be
                                          found from there.

           PUFFS_FLAG_BUILDPATH           The framework will build a complete
                                          path name, which is supplied with
                                          each operation and can be found from
                                          the pcn_po_full.po_path field in a
                                          struct puffs_cn.  The option assumes
                                          that the framework can map a cookie
                                          to a struct puffs_node.  See Cookies
                                          for more information on cookie
                                          mapping.  See puffs_path(3) for more
                                          information on library calls
                                          involving paths.

           PUFFS_FLAG_HASHPATH            Calculate a hash of the path into
                                          the path object field po_hash.  This
                                          hash value is used by
                                          puffs_path_walkcmp() to avoid doing
                                          a full comparison for every path
                                          equal in length to the one searched
                                          for.  Especially if the file system
                                          uses the abovementioned function, it
                                          is a good idea to define this flag.

           PUFFS_FLAG_PNCOOKIE            Tell puffs that cookies map to
                                          struct pnode.  This is automagically
                                          set if puffs_pn_new() is called.

           PUFFS_KFLAG_CACHE_FS_TTL       Enforce name and attribute caches
                                          based on file system-supplied TTL.
                                          In lookup, create, mknod, mkdir, and
                                          symlink, the file system must update
                                          the node attributes, their TTL, and
                                          the node name TTL through
                                          puffs_newinfo_setvattl(), and

                                          puffs_node_getattr_ttl() and
                                          puffs_node_setattr_ttl() will be
                                          called instead of
                                          puffs_node_getattr() and

           PUFFS_KFLAG_CACHE_DOTDOT       Never send lookups for ".." to the
                                          file system.  Parent vnodes are all
                                          kept active until their children are

           PUFFS_KFLAG_NOFLUSH_META       Do not send metadata cache flushes
                                          for time and size to the file
                                          system, which should take care of
                                          updating the values on its own.

           PUFFS_FLAG_OPDUMP              This option makes the framework dump
                                          a textual representation of each
                                          operation before executing it.  It
                                          is useful for debugging purposes.

     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.

           Returns a handle to do I/O multiplexing with: select(2), poll(2),
           and kqueue(2) are all examples of acceptable operations.

     puffs_setblockingmode(pu, mode)
           Sets the file system upstream access to blocking or non-blocking
           mode.  Acceptable values for the argument are PUFFSDEV_BLOCK and

           This routine can be called only after calling puffs_mount().

           Returns the state of the file system.  It is maintained by the
           framework and is mostly useful for the framework itself.  Possible

     puffs_setstacksize(pu, stacksize)
           Sets the stack size used when running callbacks.  The default is
           PUFFS_STACKSIZE_DEFAULT bytes of stack space per request.  The
           minimum stacksize is architecture-dependent and can be specified by
           using the opaque constant PUFFS_STACKSIZE_MIN.

     puffs_setroot(pu, node)
           Sets the root node of mount pu to node.  Setting the root node is
           currently required only if the path framework is used, see

     puffs_setrootinfo(pu, vt, vsize, rdev)
           The default root node is a directory.  In case the file system
           wants something different, it can call this function and set the
           type, size and possible device type to whatever it wants.  This
           routine is independent of puffs_setroot().

           Returns the root node set earlier.

           Returns the private argument of puffs_init().

     puffs_setspecific(pu, private)
           Can be used to set the specific data after the call to

     puffs_setmaxreqlen(pu, maxreqlen)
           In case the file system desires a maximum buffer length different
           from the default, the amount maxreqlen will be requested from the
           kernel when the file system is mounted.

           It is legal to call this function only between puffs_init() and

           NOTE This does not currently work.

           Returns the maximum request length the kernel will need for a
           single request.

           NOTE This does not currently work.

     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 fh*()
           family of function calls.

           In case all nodes in the file system produce the same length file
           handle, it must be supplied as 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 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
           puffs_ops(3) for more information.  Also, the flag
           PUFFS_FHFLAG_DYNAMIC must be provided in the argument flags.

           In case the file system wants to sanity check its file handle
           lengths for the limits of NFS, it can supply PUFFS_FHFLAG_NFSV2 and
           PUFFS_FHFLAG_NFSV3 in the 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.

           It is legal to call this function only between puffs_init() and

     puffs_setncookiehash(pu, ncookiehash)
           The parameter 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.

           It is legal to call this function only between puffs_init() and

     After the correct setup for the library has been established and the
     backend has been initialized the file system is made operational by
     calling puffs_mount().  After this function returns the file system
     should start processing requests.

     puffs_mount(pu, dir, mntflags, root_cookie)
           pu is the library context pointer from puffs_init().  The argument
           dir signifies the mount point and mntflags is the flagset given to
           mount(2).  The value root_cookie will be used as the cookie for the
           file system root node.

   Using the built-in eventloop
           Loop function signature.

     puffs_ml_setloopfn(pu, lfn)
           Set loop function to lfn.  This function is called once each time
           the event loop loops.  It is not a well-defined interval, but it
           can be made fairly regular by setting the loop timeout by

     puffs_ml_settimeout(pu, ts)
           Sets the loop timeout to ts or disables it if ts is NULL.  This can
           be used to roughly control how often the loop callback lfn() is

     puffs_daemon(pu, nochdir, noclose)
           Detach from the console like daemon(3).  If it is called before
           puffs_mount(), this call synchronizes with puffs_mount() and the
           foreground process does not exit before the file system mount call
           has returned from the kernel.  Since this routine internally calls
           fork, it is highly recommended to call it before puffs_mount().

     puffs_mainloop(pu, flags)
           Handle all requests automatically until the file system is
           unmounted.  It returns 0 if the file system was successfully
           unmounted or -1 if it was killed in action.

           In case puffs_framebuf(3) has been initialized, I/O from the
           relevant descriptors is processed automatically by the eventloop.

     puffs_unmountonsignal(signum, ignoresig)
           Cause all file servers within the process to initiate unmount upon
           receipt of signal signum.  This works only for servers which call
           puffs_mainloop() and must be called before any server within the
           process enters the mainloop.  The process signal handler is still
           called before starting the unmount procedure.  The parameter
           ignoresig is provided as a convenience and tells if to install a
           signal handler to ignore sig so that the process will not e.g.
           terminate based on the default action before the file system
           unmount can be initiated.

     puffs_dispatch_create(pu, pb, pccp)

     puffs_dispatch_exec(pcc, pbp)
           In case the use of puffs_mainloop() is not possible, requests may
           be dispatched manually.  However, as this is less efficient than
           using the mainloop, it should never be the first preference.

           Calling puffs_dispatch_create() creates a dispatch request.  The
           argument pb should contains a valid request and upon success pccp
           will contain a valid request context.  This context is passed to
           puffs_dispatch_exec() to execute the request.  If the request
           yielded before completing, the routine returns 0, otherwise 1.
           When the routine completes, pcc is made invalid and a pointer to
           the processed buffer is placed in pbp.  It is the responsibility of
           the caller to send the response (if necessary) and destroy the

           See puffs_cc(3) and puffs_framebuf(3) for further information.

     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 puffs_node_reclaim() is called for
     a node.

     For some operations (such as building paths) the framework needs to map
     the cookie to the framework-level structure describing a file, struct
     puffs_node.  It is advisable to simply use the struct puffs_node address
     as a cookie and store file system specific data in the private portion of
     struct puffs_node.  The library assumes this by default.  If it is not
     desirable, the file system implementation can call puffs_set_cookiemap()
     to provide an alternative cookie-to-node mapping function.

     mount(2), puffs_cc(3), puffs_cred(3), puffs_flush(3), puffs_framebuf(3),
     puffs_node(3), puffs_ops(3), puffs_path(3), refuse(3), puffs(4)

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

     Antti Kantee, Using puffs for Implementing Client-Server Distributed File
     Systems, Helsinki University of Technology, Tech Report TKK-TKO-B157,
     September 2007.

     Antti Kantee and Alistair Crooks, "ReFUSE: Userspace FUSE
     Reimplementation Using puffs", EuroBSDCon 2007, September 2007.

     Antti Kantee, "Send and Receive of File System Protocols: Userspace
     Approach With puffs", Proceedings of AsiaBSDCon 2008, pp. 55-70, March

     An unsupported experimental version of puffs first appeared in
     NetBSD 4.0.  A stable version appeared in NetBSD 5.0.

     Antti Kantee <pooka@iki.fi>

NetBSD 10.99                    April 10, 2016                    NetBSD 10.99