\"      $NetBSD: puffs_ops.3,v 1.48 2021/12/03 14:00:59 pho Exp $
\"
\" Copyright (c) 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 August 29, 2016
Dt PUFFS_OPS 3
Os
Sh NAME
Nm puffs_ops
Nd puffs callback operations
Sh LIBRARY
Lb libpuffs
Sh SYNOPSIS
In puffs.h
Ft int
Fo puffs_fs_statvfs
Fa "struct puffs_usermount *pu" "struct statvfs *sbp"
Fc
Ft int
Fo puffs_fs_sync
Fa "struct puffs_usermount *pu" "int waitfor" "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_fs_fhtonode
Fa "struct puffs_usermount *pu" "void *fid" "size_t fidsize"
Fa "struct puffs_newinfo *pni"
Fc
Ft int
Fo puffs_fs_nodetofh
Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "void *fid"
Fa "size_t *fidsize"
Fc
Ft int
Fo puffs_fs_extattrctl
Fa "struct puffs_usermount *pu" "int cmd" "puffs_cookie_t cookie" "int flags"
Fa "int attrnamespace" "const char *attrname"
Fc
Ft int
Fo puffs_fs_unmount
Fa "struct puffs_usermount *pu" "int flags"
Fc
Ft int
Fo puffs_node_lookup
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
Fc
Ft int
Fo puffs_node_create
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
Fa "const struct vattr *vap"
Fc
Ft int
Fo puffs_node_mknod
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
Fa "const struct vattr *vap"
Fc
Ft int
Fo puffs_node_open
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_open2
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int modep"
Fa "const struct puffs_cred *pcr" "int *oflags"
Fc
Ft int
Fo puffs_node_close
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_access
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_getattr
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_setattr
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "const struct vattr *vap"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_getattr_ttl
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl"
Fc
Ft int
Fo puffs_node_setattr_ttl
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl" "int xflag"
Fc
Ft int
Fo puffs_node_pathconf
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int name"
Fa "__register_t *retval"
Fc
Ft int
Fo puffs_node_advlock
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "void *id" "int op"
Fa "struct flock *fl" "int flags"
Fc
Ft int
Fo puffs_node_poll
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int *events"
Fc
Ft int
Fo puffs_node_mmap
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_fsync
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "const struct puffs_cred *pcr" "int flags" "off_t offlo" "off_t offhi"
Fc
Ft int
Fo puffs_node_seek
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t oldoff"
Fa "off_t newoff" "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_remove
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
Fa "const struct puffs_cn *pcn"
Fc
Ft int
Fo puffs_node_link
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
Fa "const struct puffs_cn *pcn"
Fc
Ft int
Fo puffs_node_rename
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t src"
Fa "const struct puffs_cn *pcn_src" "puffs_cookie_t targ_dir"
Fa "puffs_cookie_t targ" "const struct puffs_cn *pcn_targ"
Fc
Ft int
Fo puffs_node_mkdir
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
Fa "const struct vattr *vap"
Fc
Ft int
Fo puffs_node_rmdir
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
Fa "const struct puffs_cn *pcn"
Fc
Ft int
Fo puffs_node_readdir
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct dirent *dent"
Fa "off_t *readoff" "size_t *reslen" "const struct puffs_cred *pcr"
Fa "int *eofflag" "off_t *cookies" "size_t *ncookies"
Fc
Ft int
Fo puffs_node_symlink
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "struct puffs_newinfo *pni"
Fa "const struct puffs_cn *pcn_src" "const struct vattr *vap"
Fa "const char *link_target"
Fc
Ft int
Fo puffs_node_readlink
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "const struct puffs_cred *pcr" "char *link" "size_t *linklen"
Fc
Ft int
Fo puffs_node_read
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
Fc
Ft int
Fo puffs_node_write
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
Fc
Ft int
Fo puffs_node_write2
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
Fa "int xflag"
Fc
Ft int
Fo puffs_node_abortop
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fa "const struct puffs_cn *pcn"
Fc
Ft int
Fo puffs_node_getextattr
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
Fa "const char *attrname" "size_t *attrsize" "uint8_t *attr" "size_t *resid"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_setextattr
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
Fa "const char *attrname" "uint8_t *attr" "size_t *resid"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_listextattr
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
Fa "size_t *attrssize" "uint8_t *attrs" "size_t *resid" "int flag"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_deleteextattr
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
Fa "const char *attrname"
Fa "const struct puffs_cred *pcr"
Fc
Ft int
Fo puffs_node_fallocate
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t pos" "off_t len"
Fc
Ft int
Fo puffs_node_fdiscard
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t pos" "off_t len"
Fc
Ft int
Fo puffs_node_print
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fc
Ft int
Fo puffs_node_reclaim
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fc
Ft int
Fo puffs_node_reclaim2
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int nlookup"
Fc
Ft int
Fo puffs_node_inactive
Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
Fc
Ft void
Fn puffs_setback "struct puffs_cc *pcc" "int op"
Ft void
Fn puffs_newinfo_setcookie "struct puffs_newinfo *pni" "puffs_cookie_t cookie"
Ft void
Fn puffs_newinfo_setvtype "struct puffs_newinfo *pni" "enum vtype vtype"
Ft void
Fn puffs_newinfo_setsize "struct puffs_newinfo *pni" "voff_t size"
Ft void
Fn puffs_newinfo_setrdev "struct puffs_newinfo *pni" "dev_t rdev"
Ft void
Fn puffs_newinfo_setva "struct puffs_newinfo *pni" "struct vattr *vap"
Ft void
Fn puffs_newinfo_setvattl "struct puffs_newinfo *pni" "struct timespec *va_ttl"
Ft void
Fn puffs_newinfo_setcnttl "struct puffs_newinfo *pni" "struct timespec *cn_ttl"
Sh DESCRIPTION
The operations
Nm 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.
Pp
All callbacks can be prototyped with the file system name and operation
name using the macro
Fn PUFFSOP_PROTOS fsname .
Ss File system callbacks (puffs_fs)
Bl -tag -width xxxx
It Fn puffs_fs_statvfs "pu" "sbp"
The following fields of the argument
Fa sbp
need to be filled:
Bd -literal
* 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

Ed
It Fn puffs_fs_sync "pu" "waitfor" "pcr"
All the dirty buffers that have been cached at the file server
level including metadata should be committed to stable storage.
The
Fa waitfor
parameter affects the operation.
Possible values are:
Bl -tag -width XMNT_NOWAITX
It Dv MNT_WAIT
Wait for all I/O for complete until returning.
It Dv MNT_NOWAIT
Initiate I/O, but do not wait for completion.
It Dv MNT_LAZY
Synchronize data not synchronized by the file system syncer,
i.e., data not written when
Fn node_fsync
is called with
Dv FSYNC_LAZY .
El
Pp
The credentials for the initiator of the sync operation are present in
Fa 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.
It Fn puffs_fs_fhtonode "pu" "fid" "fidsize" "pni"
Translates a file handle
Fa fid
to a node.
The parameter
Fa fidsize
indicates how large the file handle is.
In case the file system's handles are static length, this parameter can
be ignored as the kernel guarantees all file handles passed to the file
server are of correct length.
For dynamic length handles the field should be examined and
Er EINVAL
returned in case the file handle length is not correct.
Pp
This function provides essentially the same information to the kernel as
Fn puffs_node_lookup .
The information is necessary for creating a new vnode corresponding to
the file handle.
It Fn puffs_fs_nodetofh "pu" "cookie" "fid" "fidsize"
Create a file handle from the node described by
Fa cookie .
The file handle should contain enough information to reliably identify
the node even after reboots and the pathname/inode being replaced by
another file.
If this is not possible, it is up to the author of the file system to
act responsibly and decide if the file system can support file handles
at all.
Pp
For file systems which want dynamic length file handles, this function
must check if the file handle space indicated by
Fa fidsize
is large enough to accommodate the file handle for the node.
If not, it must fill in the correct size and return
Er E2BIG .
In either case, the handle length should be supplied to the kernel in
Fa fidsize .
File systems with static length handles can ignore the size parameter as
the kernel always supplies the correct size buffer.
It Fn puffs_fs_unmount "pu" "flags"
Unmount the file system.
The kernel has assumedly flushed all cached data when this callback
is executed.
If the file system cannot currently be safely be unmounted, for whatever
reason, the kernel will honor an error value and not forcibly unmount.
However, if the flag
Dv MNT_FORCE
is not honored by the file server, the kernel will forcibly unmount
the file system.
El
Ss Node callbacks
These operations operate in the level of individual files.
The file cookie is always provided as the second argument
Fa opc .
If the operation is for a file, it will be the cookie of the file.
The case the operation involves a directory (such as
Dq create file in directory ) ,
the cookie will be for the directory.
Some operations take additional cookies to describe the rest of
the operands.
The return value 0 signals success, else an appropriate errno value
should be returned.
Please note that neither this list nor the descriptions are complete.
Bl -tag -width xxxx
It Fn puffs_node_lookup "pu" "opc" "pni" "pcn"
This function is used to locate nodes, or in other words translate
pathname components to file system data structures.
The implementation should match the name in
Fa pcn
against the existing entries in the directory provided by the cookie
Fa opc .
If found, the cookie for the located node should be set in
Fa pni
using
Fn puffs_newinfo_setcookie .
Additionally, the vnode type and size (latter applicable to regular files only)
should be set using
Fn puffs_newinfo_setvtype
and
Fn 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
Fn puffs_newinfo_setrdev .
Pp
If
Fn puffs_init
was called with
Dv PUFFS_KFLAG_CACHE_FS_TTL
then
Fn puffs_newinfo_setva ,
Fn puffs_newinfo_setvattl ,
and
Fn puffs_newinfo_setcnttl
can be called to specify the new node attributes, cached attributes
time to live, and cached name time to live.
Pp
The type of operation is found from
Va pcn->pcn_nameiop :
Bl -tag -width XNAMEI_LOOKUPX
It Dv NAMEI_LOOKUP
Normal lookup operation.
It Dv NAMEI_CREATE
Lookup to create a node.
It Dv NAMEI_DELETE
Lookup for node deletion.
It Dv NAMEI_RENAME
Lookup for the target of a rename operation (source will be looked
up using
Dv NAMEI_DELETE ) .
El
Pp
The final component from a pathname lookup usually requires special
treatment.
It can be identified by looking at the
Va pcn->pcn_flags
fields for the flag
Dv 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.
Pp
The return value 0 signals a found node and a nonzero value signals
an errno.
As a special case,
Er ENOENT
signals "success" for cases where the lookup operation is
Dv NAMEI_CREATE
or
Dv NAMEI_RENAME .
Failure in these cases can be signalled by returning another appropriate
error code, for example
Er EACCESS .
Pp
Usually a null-terminated string for the next pathname component is
provided in
Ar pcn->pcn_name .
In case the file system is using the option
Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF ,
the remainder of the complete pathname under lookup is found in
the same location.
Ar 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
Ar pcn->pcn_consume
to indicate the amount of
Em extra
characters in addition to
Ar pcn->pcn_namelen
processed.
It Fn puffs_node_create "pu" "opc" "pni" "pcn" "va"
It Fn puffs_node_mkdir "pu" "opc" "pni" "pcn" "va"
It Fn puffs_node_mknod "pu" "opc" "pni" "pcn" "va"
A file node is created in the directory denoted by the cookie
Fa opc
by any of the above callbacks.
The name of the new file can be found from
Fa pcn
and the attributes are specified by
Fa va
and the cookie for the newly created node should be set in
Fa pni .
The only difference between these three is that they create a regular
file, directory and device special file, respectively.
Pp
In case of mknod, the device identifier can be found in
Fa va->va_rdev .
It Fn puffs_node_open "pu" "opc" "mode" "pcr"
It Fn puffs_node_open2 "pu" "opc" "mode" "pcr" "oflags"
Open the node denoted by the cookie
Fa opc .
The parameter
Fa mode
specifies the flags that
Xr open 2
was called with, e.g.
Dv O_APPEND
and
Dv O_NONBLOCK .
Fn puffs_node_open2
allows the file system to pass back information for the file in
Fa oflags .
The only implemented flag for now is
Dv PUFFS_OPEN_IO_DIRECT
that cause file read/write to bypass the page cache.
It Fn puffs_node_close "pu" "opc" "flags" "pcr"
Close a node.
The parameter
Fa flags
parameter describes the flags that the file was opened with.
It Fn puffs_node_access "pu" "opc" "mode" "pcr"
Check if the credentials of
Fa pcr
have the right to perform the operation specified by
Fa mode
onto the node
Fa opc .
The argument
Fa mode
can specify read, write or execute by
Dv PUFFS_VREAD ,
Dv PUFFS_VWRITE ,
and
Dv PUFFS_VEXEC ,
respectively.
It Fn puffs_node_getattr "pu" "opc" "va" "pcr"
The attributes of the node specified by
Fa opc
must be copied to the space pointed by
Fa va .
It Fn puffs_node_getattr_ttl "pu" "opc" "va" "pcr" "va_ttl"
Same as
Fn puffs_node_getattr
with cached attribute time to live specified in
Fa va_ttl
It Fn puffs_node_setattr "pu" "opc" "va" "pcr"
The attributes for the node specified by
Fa opc
must be set to those contained in
Fa va .
Only fields of
Fa va
which contain a value different from
Dv PUFFS_VNOVAL
(typecast to the field's type!) contain a valid value.
It Fn puffs_node_setattr_ttl "pu" "opc" "va" "pcr" "va_ttl" "xflag"
Same as
Fn puffs_node_setattr
with cached attribute time to live specified in
Fa va_ttl .
Dv PUFFS_SETATTR_FAF
will be set in
Fa xflag
for Fire-And-Forget operations.
It Fn puffs_node_pathconf "pu" "opc" "name" "retval"
The value of the
Xr pathconf 2
filesystem limit specified in
Ar name
for the node
Ar opc
should be copied to the space pointed to by
Ar retval .
It Fn puffs_node_advlock "po" "opc" "id" "op" "fl" "flags"
Manipulate advisory record locks on the node
Ar opc .
The argument
Ar id
is the id token which is changing the lock,
Ar op
is the
Xr fcntl 2
operation to perform,
Ar fl
is the lock descriptor structure and
Ar flags
are the flags as defined in
Xr VOP_ADVLOCK 9 .
It Fn puffs_node_poll "pu" "opc" "events"
Poll for events on node
Ar opc .
If
Xr poll 2
events specified in
Ar events
are available, the function should set the bitmask to match available
events and return immediately.
Otherwise, the function should block (yield) until some events in
Ar events
become available and only then set the
Ar events
bitmask and return.
Pp
In case this function returns an error,
Dv POLLERR
(or its
Xr select 2
equivalent) will be delivered to the calling process.
Pp
Em NOTE!
The system call interface for
Fn 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.
It Fn puffs_node_mmap "pu" "opc" "flags" "pcr"
Called when a regular file is being memory mapped by
Xr mmap 2 .
Fa flags
is currently always 0.
It Fn puffs_node_fsync "pu" "opc" "pcr" "flags" "offlo" "offhi"
Synchronize a node's contents onto stable storage.
This is necessary only if the file server caches some information
before committing it.
The parameter
Fa flags
specifies the minimum level of synchronization required (XXX: they are
not yet available).
The parameters
Fa offlo
and
Fa offhi
specify the data offsets requiring to be synced.
A high offset of 0 means sync from
Fa offlo
to the end of the file.
It Fn puffs_node_seek "pu" "opc" "oldoff" "newoff" "pcr"
Test if the node
Ar opc
is seekable to the location
Ar newoff .
The argument
Ar oldoff
specifies the offset we are starting the seek from.
Most file systems dealing only with regular will choose to not
implement this.
However, it is useful for example in cases where files are
unseekable streams.
It Fn puffs_node_remove "pu" "opc" "targ" "pcn"
It Fn puffs_node_rmdir "pu" "opc" "targ" "pcn"
Remove the node
Fa targ
from the directory indicated by
Fa opc .
The directory entry name to be removed is provided by
Fa pcn .
The rmdir operation removes only directories, while the remove
operation removes all other types except directories.
Pp
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
Ux
open file semantics.
The data may be removed only when
Fn puffs_node_reclaim
or
Fn puffs_node_reclaim2
is called for the node, as this assures there are no further users.
It Fn puffs_node_link "pu" "opc" "targ" "pcn"
Create a hard link for the node
Fa targ
into the directory
Fa opc .
The argument
Fa pcn
provides the directory entry name for the new link.
It Fn puffs_node_rename "pu" "src_dir" "src" "pcn_src" "targ_dir" "targ" "pcn_targ"
Rename the node
Fa src
with the name specified by
Fa pcn_src
from the directory
Fa src_dir .
The target directory and target name are given by
Fa targ_dir
and
Fa pcn_targ ,
respectively.
Em If
the target node already exists, it is specified by
Fa targ
and must be replaced atomically.
Otherwise
Fa targ
is gives as
Dv NULL .
Pp
It is legal to replace a directory node by another directory node with
the means of rename if the target directory is empty, otherwise
Er ENOTEMPTY
should be returned.
All other types can replace all other types.
In case a rename between incompatible types is attempted, the errors
Er ENOTDIR
or
Er EISDIR
should be returned, depending on the target type.
It Fn puffs_node_readdir "pu" "opc" "dent" "readoff" "reslen" "pcr" "eofflag" "cookies" "ncookies"
To read directory entries,
Fn puffs_node_readdir
is called.
It should store directories as
Va struct dirent
in the space pointed to by
Fa dent .
The amount of space available is given by
Fa reslen
and before returning it should be set to the amount of space
Em remaining
in the buffer.
The argument
Fa offset
is used to specify the offset to the directory.
Its interpretation 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
Fa dent .
It is most performant to return the maximal amount of directory
entries each call.
It is easiest to generate directory entries by using
Fn puffs_nextdent ,
which also automatically advances the necessary pointers.
Pp
In case end-of-directory is reached,
Fa eofflag
should be set to one.
Note that even a new call to readdir may start where
Fa readoff
points to end-of-directory.
Pp
If the file system supports file handles, the arguments
Fa cookies
and
Fa ncookies
must be filled out.
Fa 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
Em 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.
Fa 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
Fn PUFFS_STORE_DCOOKIE cookies ncookies offset
can be used.
This properly checks against
Fa cookies
being
Dv NULL .
Note that
Fa ncookies
must be initialized to zero before the first call to
Fn PUFFS_STORE_DCOOKIE .
It Fn puffs_node_symlink "pu" "opc" "pni" "pcn_src" "va" "link_target"
Create a symbolic link into the directory
Fa opc
with the name in
Fa pcn_src
and the initial attributes in
Fa va .
The argument
Ar link_target
contains a null-terminated string for the link target.
The created node cookie should be set in
Fa pni .
It Fn puffs_node_readlink "pu" "opc" "pcr" "link" "linklen"
Read the target of a symbolic link
Fa opc .
The result is placed in the buffer pointed to by
Fa link .
This buffer's length is given in
Fa linklen
and it must be updated to reflect the real link length.
A terminating nul character should not be put into the buffer and
Em "must not"
be included in the link length.
It Fn puffs_node_read "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
Read the contents of a file
Fa opc .
It will gather the data from
Fa offset
in the file and read the number
Fa resid
octets.
The buffer is guaranteed to have this much space.
The amount of data requested by
Fa resid
should be read, except in the case of eof-of-file or an error.
The parameter
Fa resid
should be set to indicate the amount of request NOT completed.
In the normal case this should be 0.
It Fn puffs_node_write "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
It Fn puffs_node_write2 "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag" \
"xflag"
Fn puffs_node_write
writes data to a file
Fa opc
at
Fa offset
and extend the file if necessary.
The number of octets written is indicated by
Fa 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
Dv PUFFS_IO_APPEND
is specified, the data should be appended to the end of the file.
Fn puffs_node_write2
serves the same purpose as
Fn puffs_node_write
with an additional
Fa xflag
in which
Dv PUFFS_WRITE_FAF
is set for Fire-And-Forget operations.
It Fn puffs_node_fallocate "pu" "opc" "pos" "len"
Allocate
Fa len
bytes of backing store at offset
Fa pos
for the node referenced by the cookie
Fa opc .
It Fn puffs_node_fdiscard "pu" "opc" "pos" "len"
Free
Fa len
bytes of backing store (creating a hole) at offset
Fa pos
for the node referenced by the cookie
Fa opc .
It Fn puffs_node_print "pu" "opc"
Print information about node.
This is used only for kernel-initiated diagnostic purposes.
It Fn puffs_node_reclaim "pu" "opc"
The kernel will no longer reference the cookie and resources associated
with it may be freed.
In case the file
Fa opc
has a link count of zero, it may be safely removed now.
It Fn puffs_node_reclaim2 "pu" "opc" "nlookup"
Same as
Fn puffs_node_reclaim
with an additional 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
Fa nlookup
it can detect this situation and ignore the reclaim.
Pp
If the file system maps cookies to
Vt struct puffs_node
then the framework will do that work, and
Fn puffs_node_reclaim
can be reliably used without the race condition.
It Fn puffs_node_abortop "pu" "opc" "pcn"
In case the operation following lookup (e.g., mkdir or remove) is not
executed for some reason, abortop will be issued.
This is useful only for servers which cache state between lookup
and a directory operation and is generally left unimplemented.
It Fn puffs_node_inactive "pu" "opc"
The node
Fa opc
has lost its last reference in the kernel.
However, the cookie must still remain valid until
Fn puffs_node_reclaim
or
Fn puffs_node_reclaim2
is called.
It Fn puffs_setback "pcc" "op"
Issue a "setback" operation which will be handled when the request response
is returned to the kernel.
Currently this can be only called from mmap, open, remove and rmdir.
The valid parameters for
Ar op
are
Dv PUFFS_SETBACK_INACT_N1
and
Dv PUFFS_SETBACK_INACT_N2 .
These signal that a file system mounted with
Dv PUFFS_KFLAG_IAONDEMAND
should call the file system inactive method for the specified node.
The node number 1 always means the operation cookie
Ar opc ,
while the node number 2 can be used to specify the second node argument
present in some methods, e.g., remove.
It Fn puffs_newinfo_setcookie pni cookie
Set cookie for node provided by this method to
Ar cookie .
It Fn puffs_newinfo_setvtype pni vtype
Set the type of the newly located node to
Ar vtype .
This call is valid only for
Fn lookup
and
Fn fhtonode .
It Fn puffs_newinfo_setsize pni size
Set the size of the newly located node to
Ar size .
If left unset, the value defaults to 0.
This call is valid only for
Fn lookup
and
Fn fhtovp .
It Fn puffs_newinfo_setrdev pni rdev
Set the type of the newly located node to
Ar vtype .
This call is valid only for
Fn lookup
and
Fn fhtovp
producing device type nodes.
It Fn puffs_newinfo_setva pni vap
Set the attributes for newly created vnode.
This call is valid for
Fn lookup ,
Fn create ,
Fn mkdir ,
Fn mknod ,
and
Fn symlink ,
if
Fn puffs_init
was called with
Dv PUFFS_KFLAG_CACHE_FS_TTL
flag set.
It Fn puffs_newinfo_setvattl pni va_ttl
Set cached attribute time to live for newly created vnode.
This call is valid for
Fn lookup ,
Fn create ,
Fn mkdir ,
Fn mknod ,
and
Fn symlink ,
if
Fn puffs_init
was called with
Dv PUFFS_KFLAG_CACHE_FS_TTL
flag set.
It Fn puffs_newinfo_setcnttl pni cn_ttl
Set cached name time to live for newly created vnode.
This call is valid for
Fn lookup ,
Fn create ,
Fn mkdir ,
Fn mknod ,
and
Fn symlink ,
if
Fn puffs_init
was called with
Dv PUFFS_KFLAG_CACHE_FS_TTL
flag set.
El
Sh SEE ALSO
Xr puffs 3 ,
Xr vfsops 9 ,
Xr vnodeops 9