| PUFFS_OPS(3) | Library Functions Manual | PUFFS_OPS(3) | 
puffs_ops —
#include <puffs.h>
int
  
  puffs_fs_statvfs(struct
    puffs_usermount *pu, struct statvfs *sbp);
int
  
  puffs_fs_sync(struct puffs_usermount
    *pu, int waitfor, const struct
    puffs_cred *pcr);
int
  
  puffs_fs_fhtonode(struct
    puffs_usermount *pu, void *fid,
    size_t fidsize, struct puffs_newinfo
    *pni);
int
  
  puffs_fs_nodetofh(struct
    puffs_usermount *pu, puffs_cookie_t cookie,
    void *fid, size_t *fidsize);
int
  
  puffs_fs_extattrctl(struct
    puffs_usermount *pu, int cmd,
    puffs_cookie_t cookie, int
    flags, int attrnamespace, const
    char *attrname);
int
  
  puffs_fs_unmount(struct
    puffs_usermount *pu, int flags);
int
  
  puffs_node_lookup(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct puffs_newinfo *pni, const
    struct puffs_cn *pcn);
int
  
  puffs_node_create(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct puffs_newinfo *pni, const
    struct puffs_cn *pcn, const struct vattr
  *vap);
int
  
  puffs_node_mknod(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct puffs_newinfo *pni, const
    struct puffs_cn *pcn, const struct vattr
  *vap);
int
  
  puffs_node_open(struct puffs_usermount
    *pu, puffs_cookie_t opc, int
    mode, const struct puffs_cred *pcr);
int
  
  puffs_node_open2(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int modep, const struct puffs_cred
    *pcr, int *oflags);
int
  
  puffs_node_close(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int flags, const struct puffs_cred
    *pcr);
int
  
  puffs_node_access(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int mode, const struct puffs_cred
    *pcr);
int
  
  puffs_node_getattr(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct vattr *vap, const struct
    puffs_cred *pcr);
int
  
  puffs_node_setattr(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    const struct vattr *vap, const struct
    puffs_cred *pcr);
int
  
  puffs_node_getattr_ttl(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct vattr *vap, const struct
    puffs_cred *pcr, struct timespec *va_ttl);
int
  
  puffs_node_setattr_ttl(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct vattr *vap, const struct
    puffs_cred *pcr, struct timespec *va_ttl,
    int xflag);
int
  
  puffs_node_pathconf(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int name, register_t
  *retval);
int
  
  puffs_node_advlock(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    void *id, int op,
    struct flock *fl, int
  flags);
int
  
  puffs_node_poll(struct puffs_usermount
    *pu, puffs_cookie_t opc, int
    *events);
int
  
  puffs_node_mmap(struct puffs_usermount
    *pu, puffs_cookie_t opc, int
    flags, const struct puffs_cred *pcr);
int
  
  puffs_node_fsync(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    const struct puffs_cred *pcr, int
    flags, off_t offlo, off_t
    offhi);
int
  
  puffs_node_seek(struct puffs_usermount
    *pu, puffs_cookie_t opc, off_t
    oldoff, off_t newoff, const
    struct puffs_cred *pcr);
int
  
  puffs_node_remove(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    puffs_cookie_t targ, const struct
    puffs_cn *pcn);
int
  
  puffs_node_link(struct puffs_usermount
    *pu, puffs_cookie_t opc,
    puffs_cookie_t targ, const struct
    puffs_cn *pcn);
int
  
  puffs_node_rename(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    puffs_cookie_t src, const struct
    puffs_cn *pcn_src, puffs_cookie_t targ_dir,
    puffs_cookie_t targ, const struct
    puffs_cn *pcn_targ);
int
  
  puffs_node_mkdir(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct puffs_newinfo *pni, const
    struct puffs_cn *pcn, const struct vattr
  *vap);
int
  
  puffs_node_rmdir(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    puffs_cookie_t targ, const struct
    puffs_cn *pcn);
int
  
  puffs_node_readdir(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct dirent *dent, off_t
    *readoff, size_t *reslen, const
    struct puffs_cred *pcr, int *eofflag,
    off_t *cookies, size_t
    *ncookies);
int
  
  puffs_node_symlink(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    struct puffs_newinfo *pni, const
    struct puffs_cn *pcn_src, const struct vattr
    *vap, const char *link_target);
int
  
  puffs_node_readlink(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    const struct puffs_cred *pcr, char
    *link, size_t *linklen);
int
  
  puffs_node_read(struct puffs_usermount
    *pu, puffs_cookie_t opc, uint8_t
    *buf, off_t offset, size_t
    *resid, const struct puffs_cred *pcr,
    int ioflag);
int
  
  puffs_node_write(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    uint8_t *buf, off_t offset,
    size_t *resid, const struct puffs_cred
    *pcr, int ioflag);
int
  
  puffs_node_write2(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    uint8_t *buf, off_t offset,
    size_t *resid, const struct puffs_cred
    *pcr, int ioflag, int
    xflag);
int
  
  puffs_node_abortop(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    const struct puffs_cn *pcn);
int
  
  puffs_node_getextattr(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int attrnamespace, const char
    *attrname, size_t *attrsize,
    uint8_t *attr, size_t *resid,
    const struct puffs_cred *pcr);
int
  
  puffs_node_setextattr(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int attrnamespace, const char
    *attrname, uint8_t *attr, size_t
    *resid, const struct puffs_cred *pcr);
int
  
  puffs_node_listextattr(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int attrnamespace, size_t
    *attrssize, uint8_t *attrs,
    size_t *resid, int flag,
    const struct puffs_cred *pcr);
int
  
  puffs_node_deleteextattr(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int attrnamespace, const char
    *attrname, const struct puffs_cred *pcr);
int
  
  puffs_node_fallocate(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    off_t pos, off_t len);
int
  
  puffs_node_fdiscard(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    off_t pos, off_t len);
int
  
  puffs_node_print(struct
    puffs_usermount *pu, puffs_cookie_t opc);
int
  
  puffs_node_reclaim(struct
    puffs_usermount *pu, puffs_cookie_t opc);
int
  
  puffs_node_reclaim2(struct
    puffs_usermount *pu, puffs_cookie_t opc,
    int nlookup);
int
  
  puffs_node_inactive(struct
    puffs_usermount *pu, puffs_cookie_t opc);
void
  
  puffs_setback(struct
    puffs_cc *pcc, int
    op);
void
  
  puffs_newinfo_setcookie(struct
    puffs_newinfo *pni,
    puffs_cookie_t
  cookie);
void
  
  puffs_newinfo_setvtype(struct
    puffs_newinfo *pni, enum
    vtype vtype);
void
  
  puffs_newinfo_setsize(struct
    puffs_newinfo *pni,
    voff_t size);
void
  
  puffs_newinfo_setrdev(struct
    puffs_newinfo *pni, dev_t
    rdev);
void
  
  puffs_newinfo_setva(struct
    puffs_newinfo *pni,
    struct vattr *vap);
void
  
  puffs_newinfo_setvattl(struct
    puffs_newinfo *pni,
    struct timespec
  *va_ttl);
void
  
  puffs_newinfo_setcnttl(struct
    puffs_newinfo *pni,
    struct timespec
  *cn_ttl);
puffs requires to function can be divided
  into two categories: file system callbacks and node callbacks. The former
  affect the entire file system while the latter are targeted at a file or a
  directory and a file. They are roughly equivalent to the vfs and vnode
  operations in the kernel.
All callbacks can be prototyped with the file system name and
    operation name using the macro
    PUFFSOP_PROTOS(fsname).
puffs_fs_statvfs(pu,
    sbp)
 * unsigned long  f_bsize;     file system block size
 * unsigned long  f_frsize;    fundamental file system block size
 * fsblkcnt_t     f_blocks;    number of blocks in file system,
 *                                      (in units of f_frsize)
 *
 * fsblkcnt_t     f_bfree;     free blocks avail in file system
 * fsblkcnt_t     f_bavail;    free blocks avail to non-root
 * fsblkcnt_t     f_bresvd;    blocks reserved for root
 * fsfilcnt_t     f_files;     total file nodes in file system
 * fsfilcnt_t     f_ffree;     free file nodes in file system
 * fsfilcnt_t     f_favail;    free file nodes avail to non-root
 * fsfilcnt_t     f_fresvd;    file nodes reserved for root
    
    puffs_fs_sync(pu,
    waitfor, pcr)MNT_WAITMNT_NOWAITMNT_LAZYnode_fsync() is called
          with FSYNC_LAZY.The credentials for the initiator of the sync operation are present in pcr and will usually be either file system or kernel credentials, but might also be user credentials. However, most of the time it is advisable to sync regardless of the credentials of the caller.
puffs_fs_fhtonode(pu,
    fid, fidsize,
    pni)EINVAL returned in
      case the file handle length is not correct.
    This function provides essentially the same information to the
        kernel as puffs_node_lookup(). The information
        is necessary for creating a new vnode corresponding to the file
      handle.
puffs_fs_nodetofh(pu,
    cookie, fid,
    fidsize)For file systems which want dynamic length file handles, this
        function must check if the file handle space indicated by
        fidsize is large enough to accommodate the file
        handle for the node. If not, it must fill in the correct size and return
        E2BIG. In either case, the handle length should
        be supplied to the kernel in fidsize. File systems
        with static length handles can ignore the size parameter as the kernel
        always supplies the correct size buffer.
puffs_fs_unmount(pu,
    flags)MNT_FORCE is not honored by the file server, the
      kernel will forcibly unmount the file system.puffs_node_lookup(pu,
    opc, pni,
    pcn)puffs_newinfo_setcookie(). Additionally, the vnode
      type and size (latter applicable to regular files only) should be set
      using puffs_newinfo_setvtype() and
      puffs_newinfo_setsize(), respectively. If the
      located entry is a block device or character device file, the dev_t for
      the entry should be set using
      puffs_newinfo_setrdev().
    If puffs_init() was called with
        PUFFS_KFLAG_CACHE_FS_TTL then
        puffs_newinfo_setva(),
        puffs_newinfo_setvattl(), and
        puffs_newinfo_setcnttl() can be called to
        specify the new node attributes, cached attributes time to live, and
        cached name time to live.
The type of operation is found from pcn->pcn_nameiop:
NAMEI_LOOKUPNAMEI_CREATENAMEI_DELETENAMEI_RENAMENAMEI_DELETE).The final component from a pathname lookup usually requires
        special treatment. It can be identified by looking at the
        pcn->pcn_flags fields for the flag
        PUFFSLOOKUP_ISLASTCN. For example, in most cases
        the lookup operation will want to check if a delete, rename or create
        operation has enough credentials to perform the operation.
The return value 0 signals a found node and a nonzero value
        signals an errno. As a special case, ENOENT
        signals "success" for cases where the lookup operation is
        NAMEI_CREATE or
        NAMEI_RENAME. Failure in these cases can be
        signalled by returning another appropriate error code, for example
        EACCESS.
Usually a null-terminated string for the next pathname
        component is provided in pcn->pcn_name. In case
        the file system is using the option
        PUFFS_KFLAG_LOOKUP_FULLPNBUF, the remainder of
        the complete pathname under lookup is found in the same location.
        pcn->pcn_namelen always specifies the length of
        the next component. If operating with a full path, the file system is
        allowed to consume more than the next component's length in node lookup.
        This is done by setting pcn->pcn_consume to
        indicate the amount of extra characters in addition to
        pcn->pcn_namelen processed.
puffs_node_create(pu,
    opc, pni,
    pcn, va)puffs_node_mkdir(pu,
    opc, pni,
    pcn, va)puffs_node_mknod(pu,
    opc, pni,
    pcn, va)In case of mknod, the device identifier can be found in va->va_rdev.
puffs_node_open(pu,
    opc, mode,
    pcr)puffs_node_open2(pu,
    opc, mode,
    pcr, oflags)O_APPEND and O_NONBLOCK.
      puffs_node_open2() allows the file system to pass
      back information for the file in oflags. The only
      implemented flag for now is PUFFS_OPEN_IO_DIRECT
      that cause file read/write to bypass the page cache.puffs_node_close(pu,
    opc, flags,
    pcr)puffs_node_access(pu,
    opc, mode,
    pcr)PUFFS_VREAD,
      PUFFS_VWRITE, and
      PUFFS_VEXEC, respectively.puffs_node_getattr(pu,
    opc, va,
    pcr)puffs_node_getattr_ttl(pu,
    opc, va,
    pcr, va_ttl)puffs_node_getattr() with cached attribute
      time to live specified in va_ttlpuffs_node_setattr(pu,
    opc, va,
    pcr)PUFFS_VNOVAL (typecast to the field's type!)
      contain a valid value.puffs_node_setattr_ttl(pu,
    opc, va,
    pcr, va_ttl,
    xflag)puffs_node_setattr() with cached attribute
      time to live specified in va_ttl.
      PUFFS_SETATTR_FAF will be set in
      xflag for Fire-And-Forget operations.puffs_node_pathconf(pu,
    opc, name,
    retval)puffs_node_advlock(po,
    opc, id,
    op, fl,
    flags)puffs_node_poll(pu,
    opc, events)In case this function returns an error,
        POLLERR (or its
        select(2) equivalent) will
        be delivered to the calling process.
NOTE! The system call interface for
        poll() contains a timeout parameter. At this
        level, however, the timeout is not supplied. In case input does not
        arrive, the file system should periodically unblock and return 0 new
        events to avoid hanging forever. This will hopefully be better supported
        by libpuffs in the future.
puffs_node_mmap(pu,
    opc, flags,
    pcr)puffs_node_fsync(pu,
    opc, pcr,
    flags, offlo,
    offhi)puffs_node_seek(pu,
    opc, oldoff,
    newoff, pcr)puffs_node_remove(pu,
    opc, targ,
    pcn)puffs_node_rmdir(pu,
    opc, targ,
    pcn)It is paramount to note that the file system may not remove
        the node data structures at this point, only the directory entry and
        prevent lookups from finding the node again. This is to retain the
        UNIX open file semantics. The data may be
        removed only when puffs_node_reclaim() or
        puffs_node_reclaim2() is called for the node, as
        this assures there are no further users.
puffs_node_link(pu,
    opc, targ,
    pcn)puffs_node_rename(pu,
    src_dir, src,
    pcn_src, targ_dir,
    targ, pcn_targ)NULL.
    It is legal to replace a directory node by another directory
        node with the means of rename if the target directory is empty,
        otherwise ENOTEMPTY should be returned. All
        other types can replace all other types. In case a rename between
        incompatible types is attempted, the errors
        ENOTDIR or EISDIR should
        be returned, depending on the target type.
puffs_node_readdir(pu,
    opc, dent,
    readoff, reslen,
    pcr, eofflag,
    cookies, ncookies)puffs_node_readdir() is
      called. It should store directories as struct dirent
      in the space pointed to by dent. The amount of space
      available is given by reslen and before returning it
      should be set to the amount of space remaining in the
      buffer. The argument offset is used to specify the
      offset to the directory. Its intepretation is up to the file system and it
      should be set to signal the continuation point when there is no more room
      for the next entry in dent. It is most performant to
      return the maximal amount of directory entries each call. It is easiest to
      generate directory entries by using
      puffs_nextdent(), which also automatically
      advances the necessary pointers.
    In case end-of-directory is reached, eofflag should be set to one. Note that even a new call to readdir may start where readoff points to end-of-directory.
If the file system supports file handles, the arguments
        cookies and ncookies must be
        filled out. cookies is a vector for offsets
        corresponding to read offsets. One cookie should be filled out for each
        directory entry. The value of the cookie should equal the offset of the
        next directory entry, i.e., which offset should be
        passed to readdir for the first entry read to be the entry following the
        current one. ncookies is the number of slots for
        cookies in the cookie vector upon entry to the function and must be set
        to the amount of cookies stored in the vector (i.e., amount of directory
        entries read) upon exit. There is always enough space in the cookie
        vector for the maximal number of entries that will fit into the
        directory entry buffer. For filling out the vector, the helper function
        PUFFS_STORE_DCOOKIE(cookies,
        ncookies, offset) can be
        used. This properly checks against cookies being
        NULL. Note that ncookies
        must be initialized to zero before the first call to
        PUFFS_STORE_DCOOKIE().
puffs_node_symlink(pu,
    opc, pni,
    pcn_src, va,
    link_target)puffs_node_readlink(pu,
    opc, pcr,
    link, linklen)puffs_node_read(pu,
    opc, buf,
    offset, resid,
    pcr, ioflag)puffs_node_write(pu,
    opc, buf,
    offset, resid,
    pcr, ioflag)puffs_node_write2(pu,
    opc, buf,
    offset, resid,
    pcr, ioflag,
    xflag)puffs_node_write() writes data to a file
      opc at offset and extend the
      file if necessary. The number of octets written is indicated by
      resid; everything must be written or an error will
      be generated. The parameter must be set to indicate the amount of data NOT
      written. In case the ioflag PUFFS_IO_APPEND is
      specified, the data should be appended to the end of the file.
      puffs_node_write2() serves the same purpose as
      puffs_node_write() with an additional
      xflag in which
      PUFFS_WRITE_FAF is set for Fire-And-Forget
      operations.puffs_node_fallocate(pu,
    opc, pos,
    len)puffs_node_fdiscard(pu,
    opc, pos,
    len)puffs_node_print(pu,
    opc)puffs_node_reclaim(pu,
    opc)puffs_node_reclaim2(pu,
    opc, nlookup)puffs_node_reclaim() with an addditional
      argument for the number of lookups that have been done on the node (Node
      creation is counted as a lookup). This can be used by the file system to
      avoid a race condition, where the kernel sends a reclaim while it does not
      have received the reply for a lookup. If the file system tracks lookup
      count, and compares to nlookup it can detect this
      situation and ignore the reclaim.
    If the file system maps cookies to struct
        puffs_node then the framework will do that work, and
        puffs_node_reclaim() can be reliabily used
        without the race condition.
puffs_node_abortop(pu,
    opc, pcn)puffs_node_inactive(pu,
    opc)puffs_node_reclaim() or
      puffs_node_reclaim2() is called.puffs_setback(pcc,
    op)PUFFS_SETBACK_INACT_N1 and
      PUFFS_SETBACK_INACT_N2. These signal that a file
      system mounted with PUFFS_KFLAG_IAONDEMAND should
      call the file system inactive method for the specified node. The node
      number 1 always means the operation cookie opc,
      while the node number 2 can be used to specify the second node argument
      present in some methods, e.g., remove.puffs_newinfo_setcookie(pni,
    cookie)puffs_newinfo_setvtype(pni,
    vtype)lookup() and
      fhtonode().puffs_newinfo_setsize(pni,
    size)lookup() and
    fhtovp().puffs_newinfo_setrdev(pni,
    rdev)lookup() and
      fhtovp() producing device type nodes.puffs_newinfo_setva(pni,
    vap)lookup(), create(),
      mkdir(), mknod(), and
      symlink(), if puffs_init()
      was called with PUFFS_KFLAG_CACHE_FS_TTL flag
    set.puffs_newinfo_setvattl(pni,
    va_ttl)lookup(),
      create(), mkdir(),
      mknod(), and symlink(), if
      puffs_init() was called with
      PUFFS_KFLAG_CACHE_FS_TTL flag set.puffs_newinfo_setcnttl(pni,
    cn_ttl)lookup(), create(),
      mkdir(), mknod(), and
      symlink(), if puffs_init()
      was called with PUFFS_KFLAG_CACHE_FS_TTL flag
    set.| August 29, 2016 | NetBSD 9.4 |