1 .\" $NetBSD: puffs.3,v 1.61 2015/02/16 10:48:34 wiz Exp $
3 .\" Copyright (c) 2006, 2007, 2008 Antti Kantee. All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
8 .\" 1. Redistributions of source code must retain the above copyright
9 .\" notice, this list of conditions and the following disclaimer.
10 .\" 2. Redistributions in binary form must reproduce the above copyright
11 .\" notice, this list of conditions and the following disclaimer in the
12 .\" documentation and/or other materials provided with the distribution.
14 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 .Nd Pass-to-Userspace Framework File System development interface
36 .Ft struct puffs_usermount *
38 .Fa "struct puffs_ops *pops" "const char *mntfromname" "const char *puffsname"
39 .Fa "void *private" "uint32_t flags"
43 .Fa "struct puffs_usermount *pu" "const char *dir" "int mntflags"
44 .Fa "puffs_cookie_t root_cookie"
47 .Fn puffs_getselectable "struct puffs_usermount *pu"
49 .Fn puffs_setblockingmode "struct puffs_usermount *pu" "int mode"
51 .Fn puffs_getstate "struct puffs_usermount *pu"
53 .Fn puffs_setstacksize "struct puffs_usermount *pu" "size_t stacksize"
55 .Fn puffs_setroot "struct puffs_usermount *pu" "struct puffs_node *node"
58 .Fa "struct puffs_usermount *pu" "enum vtype vt" "vsize_t vsize" "dev_t rdev"
60 .Ft struct puffs_node *
61 .Fn puffs_getroot "struct puffs_usermount *pu"
63 .Fn puffs_getspecific "struct puffs_usermount *pu"
65 .Fn puffs_setspecific "struct puffs_usermount *pu" "void *private"
67 .Fn puffs_setmaxreqlen "struct puffs_usermount *pu" "size_t maxreqlen"
69 .Fn puffs_getmaxreqlen "struct puffs_usermount *pu"
71 .Fn puffs_setfhsize "struct puffs_usermount *pu" "size_t fhsize" "int flags"
73 .Fn puffs_setncookiehash "struct puffs_usermount *pu" "int nhashes"
75 .Fn puffs_ml_loop_fn "struct puffs_usermount *pu"
77 .Fn puffs_ml_setloopfn "struct puffs_usermount *pu" "puffs_ml_loop_fn lfn"
79 .Fn puffs_ml_settimeout "struct puffs_usermount *pu" "struct timespec *ts"
81 .Fn puffs_daemon "struct puffs_usermount *pu" "int nochdir" "int noclose"
83 .Fn puffs_mainloop "struct puffs_usermount *pu"
85 .Fn puffs_unmountonsignal "int sig" "bool ignoresig"
87 .Fo puffs_dispatch_create
88 .Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pb"
89 .Fa "struct puffs_cc **pccp"
92 .Fn puffs_dispatch_exec "struct puffs_cc *pcc" "struct puffs_framebuf **pbp"
95 provides a framework for creating file systems as userspace servers.
96 Operations are transported from the kernel virtual file system layer
97 to the concrete implementation behind
99 where they are processed and results are sent back to the kernel.
101 It is possible to use
103 in two different ways.
106 takes execution context away from the caller and automatically handles
107 all requests by using the callbacks.
112 it is possible to handle I/O to and from file descriptors.
113 This is suited e.g. for distributed file servers.
114 .Ss Library operation
115 Operations on the library always require a pointer to the opaque context
117 .Va struct puffs_usermount .
118 It is obtained by calling
122 operates using operation callbacks.
123 They can be initialized using the macro
124 .Fn PUFFSOP_SET pops fsname type opname ,
125 which will initialize the operation
126 .Fn puffs_type_opname
130 .Fn fsname_type_opname .
131 All operations are initialized to a default state with the call
132 .Fn PUFFSOP_INIT pops .
133 All of the VFS routines are mandatory, but all of the node operations
134 with the exception of
135 .Fn puffs_node_lookup
137 However, leaving operations blank will naturally have an effect on the
138 features available from the file system implementation.
140 .It Fn puffs_init pops mntfromname puffsname private flags
141 Initializes the library context.
143 specifies the callback operations vector.
145 is device the file system is mounted from.
146 This can be for example a block device such as
148 or, if the file system is pseudo file system, the
150 device name can be given by
152 This value is used for example in the first column of the output of
157 is the file system type.
158 It will always be prepended with the string "puffs|".
159 If possible, file server binaries should be named using the format
160 "mount_myfsnamehere" and this value should equal "myfsnamehere".
161 A file system specific context pointer can optionally be given in
163 This can be retrieved by
164 .Fn puffs_getspecific .
169 Currently the following flags are supported:
170 .Bl -tag -width "XPUFFS_KFLAG_LOOKUP_FULLPNBUF"
171 .It Dv PUFFS_KFLAG_NOCACHE_NAME
172 Do not enter pathname components into the name cache.
173 This means that every time the kernel does a lookup for a
174 componentname, the file server will be consulted.
175 .It Dv PUFFS_KFLAG_NOCACHE_PAGE
176 Do not use the page cache.
177 This means that all reads and writes to regular file are
178 propagated to the file server for handling.
179 This option makes a difference only for regular files.
180 .It Dv PUFFS_KFLAG_NOCACHE
182 .Dv PUFFS_KFLAG_NOCACHE_NAME
184 .Dv PUFFS_KFLAG_NOCACHE_PAGE .
185 .It Dv PUFFS_KFLAG_ALLOPS
186 This flag requests that all operations are sent to userspace.
187 Normally the kernel shortcircuits unimplemented operations.
188 This flag is mostly useful for debugging purposes.
189 .It Dv PUFFS_KFLAG_WTCACHE
190 Set the file system cache behavior as write-through.
191 This means that all writes are immediately issued to the file server
192 instead of being flushed in file system sync.
193 This is useful especially for distributed file systems.
194 .It Dv PUFFS_KFLAG_IAONDEMAND
195 Issue inactive only on demand.
196 If a file server defines the inactive method, call it only if the file
197 server has explicitly requested that inactive be called for the
199 Once inactive has been called for a node, it will not be called
200 again unless the request to call inactive is reissued by the file server.
205 for more information.
206 .It Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF
207 This flag affects only the parameter
209 .Fn puffs_node_lookup .
210 If this flag is not given, only the next pathname component under
212 .Ar pcn-\*[Gt]pcn_name .
213 If this flag is given, the full path the kernel was
214 asked to resolve can be found from there.
215 .It Dv PUFFS_FLAG_BUILDPATH
216 The framework will build a complete path name, which is supplied
217 with each operation and can be found from the
218 .Va pcn_po_full.po_path
220 .Vt struct puffs_cn .
221 The option assumes that the framework can map a cookie to a
222 .Vt struct puffs_node .
225 for more information on cookie mapping.
228 for more information on library calls involving paths.
229 .It Dv PUFFS_FLAG_HASHPATH
230 Calculate a hash of the path into the path object field
232 This hash value is used by
233 .Fn puffs_path_walkcmp
234 to avoid doing a full comparison for every path equal in length to
235 the one searched for.
236 Especially if the file system uses the abovementioned function, it
237 is a good idea to define this flag.
238 .It Dv PUFFS_FLAG_PNCOOKIE
239 Tell puffs that cookies map to
241 This is automagically set if
244 .It Dv PUFFS_KFLAG_CACHE_FS_TTL
245 Enforce name and attribute caches based on file system-supplied TTL.
246 In lookup, create, mknod, mkdir, and symlink, the file system must
247 update the node attributes, their TTL, and the node name TTL through
248 .Fn puffs_newinfo_setva ,
249 .Fn puffs_newinfo_setvattl ,
251 .Fn puffs_newinfo_setcnttl .
254 .Fn puffs_node_getattr_ttl
256 .Fn puffs_node_setattr_ttl
257 will be called instead of
258 .Fn puffs_node_getattr
260 .Fn puffs_node_setattr .
261 .It Dv PUFFS_KFLAG_CACHE_DOTDOT
262 Never send lookups for
265 Parent vnodes are all kept active until their children are reclaimed.
266 .It Dv PUFFS_KFLAG_NOFLUSH_META
267 Do not send metadata cache flushes for time and size to the file system,
268 which should take care of updating the values on its own.
269 .It Dv PUFFS_FLAG_OPDUMP
270 This option makes the framework dump a textual representation of
271 each operation before executing it.
272 It is useful for debugging purposes.
276 The following functions can be used to query or modify the global
277 state of the file system.
278 Note, that all calls are not available at all times.
280 .It Fn puffs_getselectable "pu"
281 Returns a handle to do I/O multiplexing with:
286 are all examples of acceptable operations.
287 .It Fn puffs_setblockingmode "pu" "mode"
288 Sets the file system upstream access to blocking or non-blocking mode.
289 Acceptable values for the argument are
292 .Dv PUFFSDEV_NONBLOCK .
294 This routine can be called only after calling
296 .It Fn puffs_getstate "pu"
297 Returns the state of the file system.
298 It is maintained by the framework and is mostly useful for the framework
301 .Dv PUFFS_STATE_BEFOREMOUNT ,
302 .Dv PUFFS_STATE_RUNNING ,
303 .Dv PUFFS_STATE_UNMOUNTING
305 .Dv PUFFS_STATE_UNMOUNTED .
306 .It Fn puffs_setstacksize "pu" "stacksize"
307 Sets the stack size used when running callbacks.
309 .Dv PUFFS_STACKSIZE_DEFAULT
310 bytes of stack space per request.
311 The minimum stacksize is architecture-dependent and can be specified
312 by using the opaque constant
313 .Dv PUFFS_STACKSIZE_MIN .
314 .It Fn puffs_setroot "pu" "node"
315 Sets the root node of mount
319 Setting the root node is currently required only if the path
320 framework is used, see
322 .It Fn puffs_setrootinfo pu vt vsize rdev
323 The default root node is a directory.
324 In case the file system wants something different, it can call this
325 function and set the type, size and possible device type to whatever
327 This routine is independent of
329 .It Fn puffs_getroot "pu"
330 Returns the root node set earlier.
331 .It Fn puffs_getspecific "pu"
336 .It Fn puffs_setspecific "pu" "private"
337 Can be used to set the specific data after the call to
339 .It Fn puffs_setmaxreqlen "pu" "maxreqlen"
340 In case the file system desires a maximum buffer length different from
341 the default, the amount
343 will be requested from the kernel when the file system is mounted.
345 It is legal to call this function only between
351 This does not currently work.
352 .It Fn puffs_getmaxreqlen "pu"
353 Returns the maximum request length the kernel will need for a single
357 This does not currently work.
358 .It Fn puffs_setfhsize "pu" "fhsize" "flags"
359 Sets the desired file handle size.
360 This must be called if the file system wishes to support NFS exporting
363 family of function calls.
365 In case all nodes in the file system produce the same length file handle,
366 it must be supplied as
368 In this case, the file system may ignore the length parameters in the
369 file handle callback routines, as the kernel will always pass the
370 correct length buffer.
371 However, if the file handle size varies according to file, the argument
373 defines the maximum size of a file handle for the file system.
374 In this case the file system must take care of the handle lengths by
375 itself in the file handle callbacks, see
377 for more information.
379 .Dv PUFFS_FHFLAG_DYNAMIC
380 must be provided in the argument
383 In case the file system wants to sanity check its file handle lengths
384 for the limits of NFS, it can supply
385 .Dv PUFFS_FHFLAG_NFSV2
387 .Dv PUFFS_FHFLAG_NFSV3
391 It is especially important to note that these are not directly the
392 limits specified by the protocols, as the kernel uses some bytes from
394 In case the file handles are too large, mount will return an error.
396 It is legal to call this function only between
400 .It Fn puffs_setncookiehash "pu" "ncookiehash"
403 controls the amount of hash buckets the kernel has for reverse lookups
404 from cookie to vnode.
405 Technically the default is enough, but a memory/time tradeoff can be
406 made by increasing this for file systems which know they will have
407 very many active files.
409 It is legal to call this function only between
415 After the correct setup for the library has been established and the
416 backend has been initialized the file system is made operational by calling
418 After this function returns the file system should start processing requests.
420 .It Fn puffs_mount pu dir mntflags root_cookie
422 is the library context pointer from
426 signifies the mount point and
428 is the flagset given to
432 will be used as the cookie for the file system root node.
434 .Ss Using the built-in eventloop
436 .It Fn puffs_ml_loop_fn pu
437 Loop function signature.
438 .It Fn puffs_ml_setloopfn pu lfn
441 This function is called once each time the event loop loops.
442 It is not a well-defined interval, but it can be made fairly regular
443 by setting the loop timeout by
444 .Fn puffs_ml_settimeout .
445 .It Fn puffs_ml_settimeout pu ts
446 Sets the loop timeout to
452 This can be used to roughly control how often the loop callback
455 .It Fn puffs_daemon pu nochdir noclose
456 Detach from the console like
458 This call synchronizes with
460 and the foreground process does not exit before the file system mount
461 call has returned from the kernel.
462 Since this routine internally calls fork, it has to be called
465 .It Fn puffs_mainloop pu flags
466 Handle all requests automatically until the file system is unmounted.
467 It returns 0 if the file system was successfully unmounted or \-1 if it
468 was killed in action.
472 has been initialized, I/O from the relevant descriptors is processed
473 automatically by the eventloop.
474 .It Fn puffs_unmountonsignal signum ignoresig
475 Cause all file servers within the process to initiate unmount upon
478 This works only for servers which call
480 and must be called before any server within the process enters the mainloop.
481 The process signal handler is still called before starting the unmount
485 is provided as a convenience and tells if to install a signal handler
488 so that the process will not e.g. terminate based on the default action
489 before the file system unmount can be initiated.
490 .It Fn puffs_dispatch_create pu pb pccp
491 .It Fn puffs_dispatch_exec pcc pbp
494 is not possible, requests may be dispatched manually.
495 However, as this is less efficient than using the mainloop,
496 it should never be the first preference.
499 .Fn puffs_dispatch_create
500 creates a dispatch request.
503 should contains a valid request and upon success
505 will contain a valid request context.
506 This context is passed to
507 .Fn puffs_dispatch_exec
508 to execute the request.
509 If the request yielded before completing, the routine returns 0,
511 When the routine completes,
513 is made invalid and a pointer to the processed buffer is placed in
515 It is the responsibility of the caller to send the response (if
516 necessary) and destroy the buffer.
522 for further information.
525 Every file (regular file, directory, device node, ...) instance is
526 attached to the kernel using a cookie.
527 A cookie should uniquely map to a file during its lifetime.
528 If file instances are kept in memory, a simple strategy is to use
529 the virtual address of the structure describing the file.
530 The cookie can be recycled when
531 .Fn puffs_node_reclaim
532 is called for a node.
534 For some operations (such as building paths) the framework needs to map
535 the cookie to the framework-level structure describing a file,
536 .Vt struct puffs_node .
537 It is advisable to simply use the
538 .Vt struct puffs_node
539 address as a cookie and store file system specific data in the private
541 .Vt struct puffs_node .
542 The library assumes this by default.
543 If it is not desirable, the file system implementation can call
544 .Fn puffs_set_cookiemap
545 to provide an alternative cookie-to-node mapping function.
551 .Xr puffs_framebuf 3 ,
560 .%J Proceedings of AsiaBSDCon 2007
562 .%T puffs - Pass-to-Userspace Framework File System
567 .%I Helsinki University of Technology
568 .%R Tech Report TKK-TKO-B157
569 .%T Using puffs for Implementing Client-Server Distributed File Systems
576 .%T ReFUSE: Userspace FUSE Reimplementation Using puffs
581 .%J Proceedings of AsiaBSDCon 2008
583 .%T Send and Receive of File System Protocols: Userspace Approach With puffs
586 An unsupported experimental version of
590 A stable version appeared in
593 .An Antti Kantee Aq Mt pooka@iki.fi