puffs(4)
- NetBSD Manual Pages
PUFFS(4) NetBSD Kernel Interfaces Manual PUFFS(4)
NAME
puffs -- Pass-to-Userspace Framework File System
SYNOPSIS
file-system PUFFS
pseudo-device putter
DESCRIPTION
THIS DOCUMENT IS HOPELESSLY OUT OF DATE. While some parts are still
valid, please refer to the source code for current reality.
IMPORTANT NOTE! This document describes interfaces which are not yet
guaranteed to be stable. In case you update your system sources, please
recompile everything and fix compilation errors. If your sources are
out-of-sync, incorrect operation may result.
puffs provides a framework for creating file systems as userspace
servers. The in-kernel VFS attachment is controlled through a special
device node, /dev/puffs. This document describes the operations on the
device. People looking to implement file systems should prefer using the
system through the convenience library described in puffs(3). Users
wanting to access the device node directly should include the header
sys/fs/puffs/puffs_msgif.h for relevant definitions.
Mounting
The puffs device node should be opened once per file system instance
(i.e. mount). The device itself is a cloning node, so the same node can
be opened a practically unlimited number of times. Once the device is
open, the file system can be mounted the normal way using the mount(2)
system call and using the argument structure to control mount options:
struct puffs_args {
int pa_vers;
int pa_fd;
unsigned int pa_flags;
size_t pa_maxreqlen;
char pa_name[PUFFSNAMESIZE];
uint8_t pa_vnopmask[PUFFS_VN_MAX];
};
The member pa_vers is currently always 0 and ignored. The pa_fd member
is the file descriptor number from opening the device node. pa_flags
controls some operations specific to puffs:
PUFFS_KFLAG_ALLOWCTL Allow file system fcntl and ioctl operations.
Allowing these has security implications as the
file system can technically read anything out of a
calling processes address space. This flag may
additionally be enforced by the kernel security
policy.
PUFFS_KFLAG_NOCACHE Do not store data in the page cache. This causes
operations to always consult the user server
instead of consulting the page cache. This makes
sense in situations where there is relatively lit-
tle bulk data to be transferred and the user server
does not want to take part in complex cache manage-
ment routines in case the file system data can be
modified through routes other than the file system
interface.
PUFFS_KFLAG_ALLOPS Transport all vnode operations to the file system
server instead of just the ones specified by
pa_vnopmask.
The pa_maxreqlen member signifies the length of the incoming data buffer
in userspace. A good value is PUFFS_REQ_MAXSIZE, which is the maximum
the kernel will use. A minimum value is also enforced, so the value of
this field should be checked after the mount operation to determine the
correct buffer size. During operation, in case request fetch is
attempted with a buffer too short, the error E2BIG will be returned. The
file system type is give in pa_name. It will always be prepended by
"puffs:" by the kernel. Finally, the array pa_vnopmask specifies which
operations are supported by the file system server. The array is indexed
with PUFFS_VN_FOO and 0 means vnode operation FOO is unimplemented while
non-zero means an implemented operation. This array is ignored if
PUFFS_KFLAG_ALLOPS is given.
After a successful mount system call, the the ioctl PUFFSSTARTOP must be
issued through the open device node. The parameter for this ioctl is the
following structure:
struct puffs_startreq {
void *psr_cookie;
struct statvfs psr_sb;
};
The member psr_cookie should be set before calling. This signals the
cookie value of the root node of the file system (see puffs(3) for more
details on cookie strategies). The value of psr_sb should be filled with
the same results as for a regular statvfs call. After successfully exe-
cuting this operation the file system is active.
Operation
Operations must be queried from the kernel using the ioctl PUFFSGETOP,
processed, and the results pushed back to the kernel using PUFFSPUTOP.
Normally the system will block until an event is available for
PUFFSGETOP, but it is possible to set the file descriptor into non-block-
ing mode, in which case EWOULDBLOCK is returned if no event is available.
Asynchronous I/O calls (i.e., select(2), poll(2), and kevent(2)) can be
issued to be notified of events.
As the argument both get and push use the following structure:
struct puffs_req {
uint64_t preq_id;
uint8_t preq_opclass;
uint8_t preq_optype;
void *preq_cookie;
int preq_rv;
void *preq_aux;
size_t preq_auxlen;
};
The member preq_id is used as an identifier in the reply. It should not
be modified during the processing of a PUFFSGETOP - PUFFSPUTOP sequence.
The members preq_opclass and preq_optype identify the request; they also
are used for typing the data pointed to by preq_aux. Currently the map-
ping between these two is only documented in code in
src/lib/libpuffs/puff.c:puffcall(). The handling of this will very
likely change in the future towards a more automatic direction. The
length of the buffer given to PUFFSGETOP is described by preq_auxlen and
will be modified by the kernel to indicate how much data actually was
transmitted. This is for the benefit of calls such as write, which
transmit a variable amount of data. Similarly, the user server should
fill in the amount of data the kernel must copy for PUFFSPUTOP; most of
the time this will be constant for a given operation, but operations such
as read want to adjust it dynamically. Finally, preq_rv is used by the
userspace server to fill in the success value of the operation in ques-
tion.
In case the macro PUFFSOP_WANTREPLY() returns false for preq_opclass, a
return value is not wanted and PUFFSPUTOP should not be issued.
Additionally, an operation of type PUFFSSIZEOP is supported, but it is
only used by the ioctl and fcntl operations and will likely go away in
the future. It is not described here.
Termination
The file system can be unmounted regularly using umount(8). It will
automatically be unmounted in case the userspace server is killed or the
control file descriptor closed, but in this case the userspace server
will not be separately requested to unmount itself and this may result in
data loss.
SEE ALSO
ioctl(2), mount(2), puffs(3), umount(8)
Antti Kantee, "puffs - Pass-to-Userspace Framework File System",
Proceedings of AsiaBSDCon 2007, pp. 29-42, March 2007.
HISTORY
An unsupported experimental version of puffs first appeared in
NetBSD 4.0.
AUTHORS
Antti Kantee <pooka@iki.fi>
BUGS
puffs is currently more like a souffle than puff pastry.
NetBSD 5.1 December 1, 2006 NetBSD 5.1
Powered by man-cgi (2021-06-01).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.