| PUFFS(3) | Library Functions Manual | PUFFS(3) | 
puffs —
#include <puffs.h>
struct puffs_usermount *
  
  puffs_init(struct puffs_ops
    *pops, const char *mntfromname,
    const char *puffsname, void
    *private, uint32_t flags);
int
  
  puffs_mount(struct puffs_usermount
    *pu, const char *dir, int
    mntflags, puffs_cookie_t root_cookie);
int
  
  puffs_getselectable(struct
    puffs_usermount *pu);
int
  
  puffs_setblockingmode(struct
    puffs_usermount *pu, int
    mode);
int
  
  puffs_getstate(struct
    puffs_usermount *pu);
int
  
  puffs_setstacksize(struct
    puffs_usermount *pu,
    size_t stacksize);
void
  
  puffs_setroot(struct
    puffs_usermount *pu,
    struct puffs_node
  *node);
void
  
  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);
void
  
  puffs_setspecific(struct
    puffs_usermount *pu, void
    *private);
void
  
  puffs_setmaxreqlen(struct
    puffs_usermount *pu,
    size_t maxreqlen);
size_t
  
  puffs_getmaxreqlen(struct
    puffs_usermount *pu);
void
  
  puffs_setfhsize(struct
    puffs_usermount *pu,
    size_t fhsize,
    int flags);
void
  
  puffs_setncookiehash(struct
    puffs_usermount *pu, int
    nhashes);
void
  
  puffs_ml_loop_fn(struct
    puffs_usermount *pu);
void
  
  puffs_ml_setloopfn(struct
    puffs_usermount *pu,
    puffs_ml_loop_fn
  lfn);
void
  
  puffs_ml_settimeout(struct
    puffs_usermount *pu,
    struct timespec *ts);
int
  
  puffs_daemon(struct
    puffs_usermount *pu, int
    nochdir, int
    noclose);
int
  
  puffs_mainloop(struct
    puffs_usermount *pu);
int
  
  puffs_unmountonsignal(int
    sig, bool
    ignoresig);
int
  
  puffs_dispatch_create(struct
    puffs_usermount *pu, struct puffs_framebuf *pb,
    struct puffs_cc **pccp);
int
  
  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.
puffs_init().
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)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_NAMEPUFFS_KFLAG_NOCACHE_PAGEPUFFS_KFLAG_NOCACHEPUFFS_KFLAG_NOCACHE_NAME and
          PUFFS_KFLAG_NOCACHE_PAGE.PUFFS_KFLAG_ALLOPSPUFFS_KFLAG_WTCACHEPUFFS_KFLAG_IAONDEMANDpuffs_setback() in
          puffs_ops(3) for more
          information.PUFFS_KFLAG_LOOKUP_FULLPNBUFpuffs_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_BUILDPATHPUFFS_FLAG_HASHPATHpuffs_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_PNCOOKIEpuffs_pn_new() is
          called.PUFFS_KFLAG_CACHE_FS_TTLpuffs_newinfo_setva(),
          puffs_newinfo_setvattl(), and
          puffs_newinfo_setcnttl().
        Additionally,
            puffs_node_getattr_ttl() and
            puffs_node_setattr_ttl() will be called
            instead of puffs_node_getattr() and
            puffs_node_setattr().
PUFFS_KFLAG_CACHE_DOTDOTPUFFS_KFLAG_NOFLUSH_METAPUFFS_FLAG_OPDUMPThe 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.
puffs_getselectable(pu)puffs_setblockingmode(pu,
    mode)PUFFSDEV_BLOCK and
      PUFFSDEV_NONBLOCK.
    This routine can be called only after calling
        puffs_mount().
puffs_getstate(pu)PUFFS_STATE_BEFOREMOUNT,
      PUFFS_STATE_RUNNING,
      PUFFS_STATE_UNMOUNTING and
      PUFFS_STATE_UNMOUNTED.puffs_setstacksize(pu,
    stacksize)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)puffs_setrootinfo(pu,
    vt, vsize,
    rdev)puffs_setroot().puffs_getroot(pu)puffs_getspecific(pu)puffs_init().puffs_setspecific(pu,
    private)puffs_init().puffs_setmaxreqlen(pu,
    maxreqlen)It is legal to call this function only between
        puffs_init() and
        puffs_mount().
NOTE This does not currently work.
puffs_getmaxreqlen(pu)NOTE This does not currently work.
puffs_setfhsize(pu,
    fhsize, flags)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_mount().
puffs_setncookiehash(pu,
    ncookiehash)It is legal to call this function only between
        puffs_init() and
        puffs_mount().
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)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.puffs_ml_loop_fn(pu)puffs_ml_setloopfn(pu,
    lfn)puffs_ml_settimeout().puffs_ml_settimeout(pu,
    ts)NULL. This can be used
      to roughly control how often the loop callback
      lfn() is calledpuffs_daemon(pu,
    nochdir, noclose)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)In case puffs_framebuf(3) has been initialized, I/O from the relevant descriptors is processed automatically by the eventloop.
puffs_unmountonsignal(signum,
    ignoresig)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)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 buffer.
See puffs_cc(3) and puffs_framebuf(3) for further information.
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.
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 2008.
puffs first
  appeared in NetBSD 4.0. A stable version appeared in
  NetBSD 5.0.
| April 10, 2016 | NetBSD 10.0 |