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
vsize_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_dispatch_create(
struct puffs_usermount *pu
struct puffs_framebuf *pb
struct puffs_cc **pccp
)
int
puffs_dispatch_exec(
.Fa
, struct puffs_cc *pcc
, struct puffs_framebuf **pbp
)
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 conjuction 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
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.
pops
, mntfromname
, puffsname
, private
, flags
)
/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
pflags
.
Currently the following flags are supported:
PUFFS_KFLAG_NOCACHE_NAME
PUFFS_KFLAG_NOCACHE_PAGE
PUFFS_KFLAG_NOCACHE
PUFFS_KFLAG_NOCACHE_NAME
and
PUFFS_KFLAG_NOCACHE_PAGE
.
PUFFS_KFLAG_ALLOPS
PUFFS_KFLAG_WTCACHE
PUFFS_KFLAG_IAONDEMAND
)
in
puffs_ops(3)
for more information.
PUFFS_KFLAG_LOOKUP_FULLPNBUF
).
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
PUFFS_FLAG_HASHPATH
)
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_OPDUMP
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.
pu
)
pu
, mode
)
PUFFSDEV_BLOCK
and
PUFFSDEV_NONBLOCK
.
This routine can be called only after calling
puffs_mount().
pu
)
PUFFS_STATE_BEFOREMOUNT
,
PUFFS_STATE_RUNNING
,
PUFFS_STATE_UNMOUNTING
and
PUFFS_STATE_UNMOUNTED
.
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
.
pu
, node
)
pu
to
node
.
Setting the root node is currently required only if the path
framework is used, see
puffs_path(3).
pu
, vt
, vsize
, rdev
)
).
pu
)
pu
)
private
argument of
puffs_init(
).
pu
, private
)
).
pu
, maxreqlen
)
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
puffs_mount(
).
NOTE This does not currently work.
pu
)NOTE This does not currently work.
pu
, fhsize
, flags
)
)
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(
).
pu
, ncookiehash
)
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
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.
pu
, dir
, mntflags
, root_cookie
)
).
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.
pu
)
pu
, lfn
)
).
pu
, ts
)
NULL
.
This can be used to roughly control how often the loop callback
lfn(
)
is called
pu
, nochdir
, noclose
)
3
).
This call synchronizes with
puffs_mount(
)
and the foreground process does not exit before the file system mount
call has returned from the kernel.
pu
, flags
)In case puffs_framebuf(3) has been initialized, I/O from the relevant descriptors is processed automatically by the eventloop.
pu
, pb
, pccp
)
pcc
, pbp
)
)
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.
)
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,
It is advisable to simply use the
address as a cookie and store file system specific data in the private
portion of
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.