2007-04-13 01:45:29 +04:00
|
|
|
.\" $NetBSD: puffs.3,v 1.17 2007/04/12 21:45:29 pooka Exp $
|
2006-11-09 04:30:15 +03:00
|
|
|
.\"
|
2007-01-20 00:10:55 +03:00
|
|
|
.\" Copyright (c) 2006, 2007 Antti Kantee. All rights reserved.
|
2006-11-09 04:30:15 +03:00
|
|
|
.\"
|
|
|
|
.\" 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.
|
|
|
|
.\"
|
2007-04-13 01:45:29 +04:00
|
|
|
.Dd April 12, 2007
|
2006-11-09 04:30:15 +03:00
|
|
|
.Dt PUFFS 3
|
|
|
|
.Os
|
|
|
|
.Sh NAME
|
2007-02-08 08:24:36 +03:00
|
|
|
.Nm puffs
|
2006-11-09 04:30:15 +03:00
|
|
|
.Nd Pass-to-Userspace Framework File System development interface
|
|
|
|
.Sh LIBRARY
|
|
|
|
.Lb libpuffs
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.In puffs.h
|
|
|
|
.Ft struct puffs_usermount *
|
|
|
|
.Fo puffs_mount
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fa "struct puffs_ops *pops" "const char *dir" "int mntflags"
|
|
|
|
.Fa "const char *puffsname" "void *private"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "uint32_t pflags" "size_t maxreqlen"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_start
|
|
|
|
.Fa "struct puffs_usermount *pu" "void *rootcookie" "struct statvfs *svfsb"
|
|
|
|
.Fc
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_mainloop "struct puffs_usermount *pu" "int flags"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ft int
|
|
|
|
.Fn puffs_getselectable "struct puffs_usermount *pu"
|
|
|
|
.Ft int
|
|
|
|
.Fn puffs_setblockingmode "struct puffs_usermount *pu" "int mode"
|
|
|
|
.Ft int
|
2007-01-20 16:34:35 +03:00
|
|
|
.Fn puffs_getstate "struct puffs_usermount *pu"
|
|
|
|
.Ft int
|
|
|
|
.Fn puffs_setstacksize "struct puffs_usermount *pu" "size_t stacksize"
|
2007-04-13 01:45:29 +04:00
|
|
|
.Ft void
|
|
|
|
.Fn puffs_setroot "struct puffs_usermount *pu" "struct puffs_node *node"
|
|
|
|
.Ft struct puffs_node *
|
|
|
|
.Fn puffs_getroot "struct puffs_usermount *pu"
|
|
|
|
.Ft void *
|
|
|
|
.Fn puffs_getspecific "struct puffs_usermount *pu"
|
|
|
|
.Ft size_t
|
|
|
|
.Fn puffs_getmaxreqlen "struct puffs_usermount *pu"
|
2007-01-20 16:34:35 +03:00
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_fs_unmount "struct puffs_cc *pcc" "int flags" "pid_t pid"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_fs_statvfs
|
|
|
|
.Fa "struct puffs_cc *pcc" "struct statvfs *sbp" "pid_t pid"
|
2006-11-23 20:45:11 +03:00
|
|
|
.Fc
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_fs_sync
|
|
|
|
.Fa "struct puffs_cc *pcc" "int waitfor" "const struct puffs_cred *cred"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "pid_t pid"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_lookup
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void **newnode"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "enum vtype *newtype" "voff_t *newsize" "dev_t *newrdev"
|
|
|
|
.Fa "const struct puffs_cn *pcn"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_getattr
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "struct vattr *va"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cred *pcr" "pid_t pid"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_setattr
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "const struct vattr *va"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cred *pcr" "pid_t pid"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_create
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void **newnode"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn" "const struct vattr *va"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_remove
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void *targ"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_mkdir
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void **newnode"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn" "const struct vattr *va"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_rmdir
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void *targ"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_readdir
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "struct dirent *dent"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cred *pcr" "off_t *readoff" "size_t *reslen"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_rename
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void *src"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn_src" "void *targ_dir" "void *targ"
|
|
|
|
.Fa "const struct puffs_cn *pcn_targ"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_link
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void *targ"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_symlink
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void **newnode"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn_src" "const struct vattr *va"
|
|
|
|
.Fa "const char *link_target"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_readlink
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "const struct puffs_cred *cred"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "char *link" "size_t *linklen"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_mknod
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "void **newnode"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "const struct puffs_cn *pcn" "const struct vattr *va"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_open
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "int flags"
|
2006-11-23 20:45:11 +03:00
|
|
|
.Fa "const struct puffs_cred *pcr" "pid_t pid"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_close
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "int flags"
|
2006-11-23 20:45:11 +03:00
|
|
|
.Fa "const struct puffs_cred *pcr" "pid_t pid"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_access
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "int mode"
|
2007-03-20 21:25:56 +03:00
|
|
|
.Fa "const struct puffs_cred *pcr" "pid_t pid"
|
2006-11-23 20:45:11 +03:00
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_read
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "uint8_t *buf"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_write
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "uint8_t *buf"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_reclaim "struct puffs_cc *pcc" "void *opc" "pid_t pid"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ft int
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fo puffs_node_inactive
|
|
|
|
.Fa "struct puffs_cc *pcc" "void *opc" "pid_t pid" "int *refcount"
|
2006-11-09 04:30:15 +03:00
|
|
|
.Fc
|
|
|
|
.Sh DESCRIPTION
|
2006-11-19 03:11:21 +03:00
|
|
|
.Em IMPORTANT NOTE!
|
2006-11-09 04:30:15 +03:00
|
|
|
This document describes interfaces which are not yet guaranteed to be
|
|
|
|
stable.
|
|
|
|
In case you update your system sources, please recompile everything
|
|
|
|
and fix complation errors.
|
|
|
|
If your sources are out-of-sync, incorrect operation may result.
|
|
|
|
The interfaces in this document will most likely be hugely simplified
|
|
|
|
in later versions or made transparent to the implementation.
|
|
|
|
.Pp
|
|
|
|
.Nm
|
|
|
|
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
|
|
|
|
.Nm ,
|
|
|
|
where they are processed and results are sent back to the kernel.
|
|
|
|
.Pp
|
|
|
|
It is possible to use
|
|
|
|
.Nm
|
|
|
|
in two different ways.
|
2006-11-30 08:53:34 +03:00
|
|
|
Calling
|
|
|
|
.Fn puffs_mainloop
|
|
|
|
takes execution context away from the caller and automatically handles
|
|
|
|
all requests by using the callbacks.
|
|
|
|
Alternatively, control can be kept with the caller and operations
|
|
|
|
handled manually.
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ss Library operation
|
|
|
|
The file system is mounted using
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_mount .
|
|
|
|
The callbacks are passed as the fields in the structure
|
|
|
|
.Fa pops .
|
|
|
|
They can be initialized using the macro
|
|
|
|
.Fn PUFFSOP_SET pops fsname type opname ,
|
|
|
|
which will initialize the operation
|
|
|
|
.Fn puffs_type_opname
|
|
|
|
in
|
|
|
|
.Fa pops
|
|
|
|
to
|
|
|
|
.Fn fsname_type_opname .
|
|
|
|
All operations are initialized to a default state with the call
|
|
|
|
.Fn PUFFSOP_INIT pops .
|
2006-11-09 04:30:15 +03:00
|
|
|
All of the VFS routines are mandatory, but all of the node operations
|
|
|
|
with the exception of
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_fs_lookup
|
2006-11-09 04:30:15 +03:00
|
|
|
are optional.
|
|
|
|
However, leaving operations blank will naturally have an effect on the
|
|
|
|
features available from the file system implementation.
|
|
|
|
The argument
|
|
|
|
.Fa dir
|
|
|
|
signifies the mount point,
|
|
|
|
.Fa mntflags
|
|
|
|
is the flagset given to
|
|
|
|
.Xr mount 2 ,
|
|
|
|
and
|
|
|
|
.Fa puffsname
|
|
|
|
is the name of the file system implementation.
|
|
|
|
Flags for
|
|
|
|
.Nm
|
|
|
|
can be given via
|
|
|
|
.Fa pflags .
|
2007-01-20 00:10:55 +03:00
|
|
|
Currently the following flags are supported:
|
|
|
|
.Bl -tag -width "XPUFFS_KFLAG_BUILDPATHX"
|
|
|
|
.It Dv PUFFS_KFLAG_NOCACHE
|
|
|
|
Do not cache anything in the kernel.
|
|
|
|
Currently this means not using the page cache for regular files or
|
|
|
|
the name cache (directory entry cache) for all files.
|
|
|
|
This is useful if the file system does not want to include flushing
|
|
|
|
and invalidation logic in case it is possible to modify the backend
|
|
|
|
from "under" our view of the file system (a distributed file system,
|
|
|
|
for example).
|
|
|
|
.It Dv PUFFS_KFLAG_ALLOPS
|
|
|
|
This flag requests that all operations are sent to userspace.
|
|
|
|
Normally the kernel shortcircuits unimplemented operations.
|
|
|
|
This flag is mostly useful for debugging purposes.
|
|
|
|
.It Dv PUFFS_FLAG_BUILDPATH
|
|
|
|
The framework will build a complete path name, which is supplied
|
|
|
|
with each operation and can be found from the
|
|
|
|
.Va pn_po.po_full_pcn
|
|
|
|
field in a
|
|
|
|
.Vt struct puffs_node .
|
|
|
|
The option assumes that the framework can map a cookie to a
|
|
|
|
.Vt struct puffs_node .
|
|
|
|
See
|
|
|
|
.Sx Cookies
|
|
|
|
for more information on cookie mapping.
|
|
|
|
See
|
|
|
|
.Xr puffs_path 3
|
|
|
|
for more information on library calls involving paths.
|
|
|
|
.It Dv PUFFS_FLAG_OPDUMP
|
|
|
|
This option makes the framework dump a textual representation of
|
|
|
|
each operation before executing it.
|
|
|
|
It is useful for debugging purposes.
|
|
|
|
.El
|
|
|
|
.Pp
|
2006-11-09 04:30:15 +03:00
|
|
|
Finally, the maximum operation buffer length is requested by
|
|
|
|
.Fa maxreqlen .
|
|
|
|
The field
|
|
|
|
.Va pu_maxreqlen
|
|
|
|
from the returned mount structure is the kernel sanity-checked value and
|
|
|
|
should always be consulted after the mount call returns.
|
|
|
|
Supplying 0 as this parameter will make the kernel choose the longest
|
|
|
|
possible buffer length.
|
|
|
|
In case of success,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_fs_mount
|
2006-11-09 04:30:15 +03:00
|
|
|
returns the address of the user mount instance.
|
|
|
|
Otherwise,
|
|
|
|
.Dv NULL
|
|
|
|
is returned and errno is set to specify the error.
|
|
|
|
.Pp
|
|
|
|
To handle all requests automatically until the file system is
|
|
|
|
unmounted,
|
|
|
|
.Fn puffs_mainloop
|
|
|
|
should be used.
|
2006-11-19 03:11:21 +03:00
|
|
|
It returns 0 if the file system was succesfully unmounted or \-1 if it
|
2006-11-09 04:30:15 +03:00
|
|
|
was killed in action.
|
2006-11-30 08:53:34 +03:00
|
|
|
Unless
|
|
|
|
.Fa flags
|
|
|
|
is used to pass
|
|
|
|
.Dv PUFFSLOOP_NODAEMON ,
|
|
|
|
.Fn puffs_mainloop
|
|
|
|
will also detach from the terminal.
|
2007-04-13 01:45:29 +04:00
|
|
|
.Bl -tag -width xxxx
|
|
|
|
.It Fn puffs_getselectable "pu"
|
|
|
|
Returns a handle to do I/O multiplexing with:
|
2006-11-09 04:30:15 +03:00
|
|
|
.Xr select 2 ,
|
2006-11-19 03:11:21 +03:00
|
|
|
.Xr poll 2 ,
|
2006-11-09 04:30:15 +03:00
|
|
|
and
|
|
|
|
.Xr kqueue 2
|
2006-11-19 03:11:21 +03:00
|
|
|
are all examples of acceptable operations.
|
2007-04-13 01:45:29 +04:00
|
|
|
.It Fn puffs_setblockingmode "pu" "mode"
|
|
|
|
Sets the library to blocking or non-blocking.
|
2006-11-09 04:30:15 +03:00
|
|
|
Acceptable values for the argument are
|
|
|
|
.Dv PUFFSDEV_BLOCK
|
|
|
|
and
|
|
|
|
.Dv PUFFSDEV_NONBLOCK .
|
2007-04-13 01:45:29 +04:00
|
|
|
.It Fn puffs_getstate "pu"
|
|
|
|
Returns the state of the file system.
|
2007-01-20 16:34:35 +03:00
|
|
|
It is maintained by the framework and is mostly useful for the framework
|
|
|
|
itself.
|
|
|
|
Possible values are
|
|
|
|
.Dv PUFFS_STATE_MOUNTING ,
|
|
|
|
.Dv PUFFS_STATE_RUNNING ,
|
|
|
|
.Dv PUFFS_STATE_UNMOUNTING
|
|
|
|
and
|
|
|
|
.Dv PUFFS_STATE_UNMOUNTED .
|
2007-04-13 01:45:29 +04:00
|
|
|
.It Fn puffs_setstacksize "stacksize"
|
|
|
|
Sets the stack size used when running callbacks.
|
2007-01-20 16:34:35 +03:00
|
|
|
The default is one megabyte of stack space per request.
|
|
|
|
See
|
|
|
|
.Xr puffs_cc 3 .
|
2007-04-13 01:45:29 +04:00
|
|
|
.It Fn puffs_setroot "pu" "node"
|
|
|
|
Sets the root node of mount
|
|
|
|
.Fa pu
|
|
|
|
to
|
|
|
|
.Fa "node" .
|
|
|
|
Setting the root node is currently required only if the path
|
|
|
|
framework is used, see
|
|
|
|
.Xr puffs_path 3 .
|
|
|
|
.It Fn puffs_getroot "pu"
|
|
|
|
Returns the root node set earlier.
|
|
|
|
.It Fn puffs_getspecific "pu"
|
|
|
|
Returns the
|
|
|
|
.Fa private
|
|
|
|
argument of
|
|
|
|
.Fn puffs_mount .
|
|
|
|
.It Fn puffs_getmaxreqlen "pu"
|
|
|
|
Returns the maximum request length the kernel will need for a single
|
|
|
|
request.
|
|
|
|
This information can be used to allocate the request buffer.
|
|
|
|
.El
|
2007-01-20 16:34:35 +03:00
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
After the correct setup for the library has been established and the
|
|
|
|
backend has been initialized, the file system is made operational
|
|
|
|
by calling
|
|
|
|
.Fn puffs_start .
|
|
|
|
Immediately after the return of this function the file system must
|
|
|
|
be ready to process requests.
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ss Cookies
|
|
|
|
Every file (regular file, directory, device node, ...) instance is
|
|
|
|
attached to the kernel using a cookie.
|
|
|
|
A cookie should uniquely map to a file during its lifetime.
|
|
|
|
If file instances are kept in memory, a simple strategy is to use
|
|
|
|
the virtual address of the structure describing the file.
|
|
|
|
The cookie can be recycled when
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_reclaim
|
2006-11-09 04:30:15 +03:00
|
|
|
is called for a node.
|
2007-01-20 00:10:55 +03:00
|
|
|
.Pp
|
|
|
|
For some operations (such as building paths) the framework needs to map
|
|
|
|
the cookie to the framework-level structure describing a file,
|
|
|
|
.Vt struct puffs_node .
|
|
|
|
It is advisable to simply use the
|
|
|
|
.Vt struct puffs_node
|
|
|
|
address as a cookie and store file system specific data in the private
|
|
|
|
portion of
|
|
|
|
.Vt struct puffs_node .
|
|
|
|
The library assumes this by default.
|
|
|
|
If it is not desireable, the file system implementation can call
|
|
|
|
.Fn puffs_set_cookiemap
|
|
|
|
to provide an alternative cookie-to-node mapping function.
|
2006-11-09 04:30:15 +03:00
|
|
|
.Ss File system callbacks
|
|
|
|
The callbacks do all the actual work in implementing the file system.
|
|
|
|
Currently they are fairly close to the vfs and vnode operations in
|
|
|
|
the kernel but with simplified operation.
|
|
|
|
This section describes the calls which relate to the file system
|
|
|
|
itself.
|
|
|
|
.Pp
|
|
|
|
All callbacks can be prototyped with the file system name and operation
|
|
|
|
name using the macro
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn PUFFSOP_PROTOS fsname .
|
2006-11-09 04:30:15 +03:00
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_fs_statvfs
|
2006-11-09 04:30:15 +03:00
|
|
|
should fill in the following fields of
|
|
|
|
.Fa sbp :
|
|
|
|
.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
|
|
|
|
The process requiring this information is given by
|
|
|
|
.Fa pid .
|
|
|
|
.Pp
|
2006-11-23 20:45:11 +03:00
|
|
|
The file system should be sychronized to storage when
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_fs_sync
|
2006-11-09 04:30:15 +03:00
|
|
|
is called.
|
|
|
|
The
|
|
|
|
.Fa waitfor
|
|
|
|
parameter should handled similarly as inside the kernel.
|
|
|
|
.Pp
|
|
|
|
The file system should be unmounted when
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_fs_unmount
|
2006-11-09 04:30:15 +03:00
|
|
|
is called.
|
|
|
|
If the flag
|
|
|
|
.Dv MNT_FORCE
|
|
|
|
is not honored, the kernel will proceed to forcibly unmount the file system
|
|
|
|
despite this.
|
|
|
|
.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.
|
2006-11-19 03:11:21 +03:00
|
|
|
The case the operation involves a directory (such as
|
|
|
|
.Dq create file in directory ) ,
|
|
|
|
the cookie will be for the directory.
|
2006-11-09 04:30:15 +03:00
|
|
|
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.
|
2006-11-19 03:11:21 +03:00
|
|
|
Please note that neither this list nor the descriptions are complete.
|
2006-11-09 04:30:15 +03:00
|
|
|
.Pp
|
|
|
|
The
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_lookup
|
2006-11-09 04:30:15 +03:00
|
|
|
function is used to locate nodes.
|
|
|
|
The implementation should match the name in
|
|
|
|
.Fa pcn
|
|
|
|
against the existing entries in the directory provided by the cookie.
|
|
|
|
If found, the cookie for the located node should be returned in
|
|
|
|
.Fa newnode .
|
2006-11-14 00:06:16 +03:00
|
|
|
Additionally, the type and size (latter applicable to regular files only)
|
2006-11-09 04:30:15 +03:00
|
|
|
should be returned in
|
|
|
|
.Fa newtype
|
|
|
|
and
|
|
|
|
.Fa newsize ,
|
|
|
|
respectively.
|
|
|
|
If the located entry is a block device or character device file,
|
|
|
|
the dev_t for the entry should be returned in
|
|
|
|
.Fa newrdev .
|
2006-11-14 00:06:16 +03:00
|
|
|
Otherwise, 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 PUFFSLOOKUP_CREATE
|
|
|
|
or
|
|
|
|
.Dv PUFFSLOOKUP_RENAME .
|
|
|
|
Failure in these cases can be signalled by returning another appropriate
|
|
|
|
error code, for example
|
|
|
|
.Er EACCESS .
|
2006-11-09 04:30:15 +03:00
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_getattr
|
2006-11-09 04:30:15 +03:00
|
|
|
fills out a struct vattr pointed to by
|
|
|
|
.Fa va .
|
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_setattr
|
2006-11-09 04:30:15 +03:00
|
|
|
sets the attributes in
|
|
|
|
.Fa va .
|
|
|
|
Instead of setting everything according to that file, only fields which
|
|
|
|
are not marked
|
|
|
|
.Dv VNOVAL
|
|
|
|
should be set.
|
|
|
|
.Pp
|
|
|
|
A file node is created in the directory specified by the cookie when
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_create
|
2006-11-09 04:30:15 +03:00
|
|
|
is called.
|
|
|
|
The attributes are specified by
|
|
|
|
.Fa va
|
|
|
|
and the cookie for the newly created node should be returned in
|
|
|
|
.Fa newnode .
|
|
|
|
Similarly,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_mkdir
|
2006-11-09 04:30:15 +03:00
|
|
|
creates a directory.
|
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_remove
|
2006-11-09 04:30:15 +03:00
|
|
|
removes the file
|
|
|
|
.Fa targ
|
|
|
|
from the directory indicated by the cookie.
|
|
|
|
Similarly,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_rmdir
|
2006-11-09 04:30:15 +03:00
|
|
|
removes a directory.
|
|
|
|
The name of the directory entry to remove is described by
|
|
|
|
.Fa pcn .
|
|
|
|
.Pp
|
|
|
|
To read directory entries,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_readdir
|
2006-11-09 04:30:15 +03:00
|
|
|
is called.
|
|
|
|
It should store directories as struct dirents 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 intepretation is up to the file systme 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.
|
|
|
|
In case the directory was exhausted, the parameters should not be
|
|
|
|
modified to signal end-of-directory.
|
|
|
|
.Pp
|
|
|
|
A node rename is done by calling
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_rename .
|
2006-11-09 04:30:15 +03:00
|
|
|
If the destination file cookie is non-null, it must be removed
|
|
|
|
and the new entry overwritten atomically.
|
|
|
|
The directory entry names to be used are described by the
|
|
|
|
struct puffs_cn's (cf. create and remove).
|
|
|
|
.Pp
|
|
|
|
A hard link is created by
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_link .
|
2006-11-09 04:30:15 +03:00
|
|
|
In practice this means adding a directory entry described by
|
|
|
|
.Fa pcn
|
|
|
|
to the cookied directory and the entry pointing to the target node.
|
|
|
|
.Pp
|
|
|
|
A symbolic link in turn is created by
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_symlink .
|
2006-11-09 04:30:15 +03:00
|
|
|
It is similar to creating a regular file, except that
|
|
|
|
.Fa link_target
|
|
|
|
specifies the target of the link which should be set for the link.
|
|
|
|
.Pp
|
|
|
|
To read the target of a symbolic link,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fa puffs_node_readlink
|
2006-11-09 04:30:15 +03:00
|
|
|
is called.
|
|
|
|
The path in the link target should be copied to
|
|
|
|
.Fa link
|
|
|
|
and the length without the terminating nul set in
|
|
|
|
.Fa linklen .
|
|
|
|
.Pp
|
|
|
|
A device node is created using
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_mknod .
|
2006-11-09 04:30:15 +03:00
|
|
|
The only difference to creating a normal file is that the attribute
|
|
|
|
struct contains the device identifier in
|
2006-11-19 03:11:21 +03:00
|
|
|
.Fa va-\*[Gt]va_rdev .
|
2006-11-09 04:30:15 +03:00
|
|
|
.Pp
|
2006-11-23 20:45:11 +03:00
|
|
|
Files are opened with a call to
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_open .
|
2006-11-23 20:45:11 +03:00
|
|
|
Most of the time this can be left unimplemented, unless special
|
|
|
|
resource allocation is required.
|
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_close
|
2006-11-23 20:45:11 +03:00
|
|
|
releases all the resources allocated by
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_open .
|
2006-11-23 20:45:11 +03:00
|
|
|
.Pp
|
|
|
|
To check if access of type
|
|
|
|
.Va mode
|
|
|
|
to a file is allowed,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_access
|
2006-11-23 20:45:11 +03:00
|
|
|
is called.
|
|
|
|
This controls file access, not e.g.
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_open .
|
2006-11-23 20:45:11 +03:00
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_read
|
2006-11-09 04:30:15 +03:00
|
|
|
reads the contents of a file.
|
|
|
|
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.
|
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_write
|
2006-11-09 04:30:15 +03:00
|
|
|
writes data to a file at
|
|
|
|
.Fa offset
|
|
|
|
extending 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 flag
|
|
|
|
.Dv PUFFS_IO_APPEND
|
|
|
|
is specified, the data should be appended to the end of the file.
|
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_reclaim
|
2006-11-09 04:30:15 +03:00
|
|
|
signals that the cookie will no longer be referenced without a further
|
|
|
|
call to
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_lookup .
|
2006-11-09 04:30:15 +03:00
|
|
|
This information can be used to free resources and specifically release
|
|
|
|
a file for which no directory entries remain.
|
|
|
|
.Pp
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_inactive
|
2006-11-09 04:30:15 +03:00
|
|
|
signals that the kernel has released its last reference to the node.
|
|
|
|
However, the cookie must still remain valid until
|
2007-01-20 00:10:55 +03:00
|
|
|
.Fn puffs_node_reclaim
|
2006-11-09 04:30:15 +03:00
|
|
|
is called.
|
|
|
|
The file system should return its internal reference count on the file
|
|
|
|
(usually number of links to the file) in
|
|
|
|
.Fa refcount .
|
|
|
|
If this is zero, the kernel will call reclaim immediately.
|
|
|
|
.Sh SEE ALSO
|
2007-01-20 00:10:55 +03:00
|
|
|
.Xr puffs_cc 3 ,
|
2007-03-22 20:38:09 +03:00
|
|
|
.Xr puffs_cred 3 ,
|
2007-01-20 00:10:55 +03:00
|
|
|
.Xr puffs_flush 3 ,
|
|
|
|
.Xr puffs_node 3 ,
|
2007-01-20 16:23:59 +03:00
|
|
|
.Xr puffs_path 3 ,
|
2007-01-20 18:10:38 +03:00
|
|
|
.Xr puffs_req 3 ,
|
2007-01-27 02:55:27 +03:00
|
|
|
.Xr puffs_suspend 3 ,
|
2007-01-20 16:23:59 +03:00
|
|
|
.Xr puffs 4
|
2007-03-13 20:06:10 +03:00
|
|
|
.Rs
|
|
|
|
.%A Antti Kantee
|
|
|
|
.%D March 2007
|
|
|
|
.%J Proceedings of AsiaBSDCon 2007
|
|
|
|
.%P pp. 29-42
|
|
|
|
.%T puffs - Pass-to-Userspace Framework File System
|
|
|
|
.Re
|
2006-11-09 04:30:15 +03:00
|
|
|
.Sh HISTORY
|
2006-11-30 08:53:34 +03:00
|
|
|
An unsupported experimental version of
|
2006-11-09 04:30:15 +03:00
|
|
|
.Nm
|
|
|
|
first appeared in
|
|
|
|
.Nx 4.0 .
|
|
|
|
.Sh AUTHORS
|
|
|
|
.An Antti Kantee Aq pooka@iki.fi
|
|
|
|
.Sh BUGS
|
2007-01-20 00:10:55 +03:00
|
|
|
Under construction.
|