xref: /minix/lib/libpuffs/puffs.3 (revision 0a6a1f1d)
1.\"	$NetBSD: puffs.3,v 1.61 2015/02/16 10:48:34 wiz Exp $
2.\"
3.\" Copyright (c) 2006, 2007, 2008 Antti Kantee.  All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
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.
13.\"
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
24.\" SUCH DAMAGE.
25.\"
26.Dd February 15, 2015
27.Dt PUFFS 3
28.Os
29.Sh NAME
30.Nm puffs
31.Nd Pass-to-Userspace Framework File System development interface
32.Sh LIBRARY
33.Lb libpuffs
34.Sh SYNOPSIS
35.In puffs.h
36.Ft struct puffs_usermount *
37.Fo puffs_init
38.Fa "struct puffs_ops *pops" "const char *mntfromname" "const char *puffsname"
39.Fa "void *private" "uint32_t flags"
40.Fc
41.Ft int
42.Fo puffs_mount
43.Fa "struct puffs_usermount *pu" "const char *dir" "int mntflags"
44.Fa "puffs_cookie_t root_cookie"
45.Fc
46.Ft int
47.Fn puffs_getselectable "struct puffs_usermount *pu"
48.Ft int
49.Fn puffs_setblockingmode "struct puffs_usermount *pu" "int mode"
50.Ft int
51.Fn puffs_getstate "struct puffs_usermount *pu"
52.Ft int
53.Fn puffs_setstacksize "struct puffs_usermount *pu" "size_t stacksize"
54.Ft void
55.Fn puffs_setroot "struct puffs_usermount *pu" "struct puffs_node *node"
56.Ft void
57.Fo puffs_setrootinfo
58.Fa "struct puffs_usermount *pu" "enum vtype vt" "vsize_t vsize" "dev_t rdev"
59.Fc
60.Ft struct puffs_node *
61.Fn puffs_getroot "struct puffs_usermount *pu"
62.Ft void *
63.Fn puffs_getspecific "struct puffs_usermount *pu"
64.Ft void
65.Fn puffs_setspecific "struct puffs_usermount *pu" "void *private"
66.Ft void
67.Fn puffs_setmaxreqlen "struct puffs_usermount *pu" "size_t maxreqlen"
68.Ft size_t
69.Fn puffs_getmaxreqlen "struct puffs_usermount *pu"
70.Ft void
71.Fn puffs_setfhsize "struct puffs_usermount *pu" "size_t fhsize" "int flags"
72.Ft void
73.Fn puffs_setncookiehash "struct puffs_usermount *pu" "int nhashes"
74.Ft void
75.Fn puffs_ml_loop_fn "struct puffs_usermount *pu"
76.Ft void
77.Fn puffs_ml_setloopfn "struct puffs_usermount *pu" "puffs_ml_loop_fn lfn"
78.Ft void
79.Fn puffs_ml_settimeout "struct puffs_usermount *pu" "struct timespec *ts"
80.Ft int
81.Fn puffs_daemon "struct puffs_usermount *pu" "int nochdir" "int noclose"
82.Ft int
83.Fn puffs_mainloop "struct puffs_usermount *pu"
84.Ft int
85.Fn puffs_unmountonsignal "int sig" "bool ignoresig"
86.Ft int
87.Fo puffs_dispatch_create
88.Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pb"
89.Fa "struct puffs_cc **pccp"
90.Fc
91.Ft int
92.Fn puffs_dispatch_exec "struct puffs_cc *pcc" "struct puffs_framebuf **pbp"
93.Sh DESCRIPTION
94.Nm
95provides a framework for creating file systems as userspace servers.
96Operations are transported from the kernel virtual file system layer
97to the concrete implementation behind
98.Nm ,
99where they are processed and results are sent back to the kernel.
100.Pp
101It is possible to use
102.Nm
103in two different ways.
104Calling
105.Fn puffs_mainloop
106takes execution context away from the caller and automatically handles
107all requests by using the callbacks.
108By using
109.Xr puffs_framebuf 3
110in conjuction with
111.Fn puffs_mainloop ,
112it is possible to handle I/O to and from file descriptors.
113This is suited e.g. for distributed file servers.
114.Ss Library operation
115Operations on the library always require a pointer to the opaque context
116identifier,
117.Va struct puffs_usermount .
118It is obtained by calling
119.Fn puffs_init .
120.Pp
121.Nm
122operates using operation callbacks.
123They can be initialized using the macro
124.Fn PUFFSOP_SET pops fsname type opname ,
125which will initialize the operation
126.Fn puffs_type_opname
127in
128.Fa pops
129to
130.Fn fsname_type_opname .
131All operations are initialized to a default state with the call
132.Fn PUFFSOP_INIT pops .
133All of the VFS routines are mandatory, but all of the node operations
134with the exception of
135.Fn puffs_node_lookup
136are optional.
137However, leaving operations blank will naturally have an effect on the
138features available from the file system implementation.
139.Bl -tag -width xxxx
140.It Fn puffs_init pops mntfromname puffsname private flags
141Initializes the library context.
142.Ar pops
143specifies the callback operations vector.
144.Ar mntfromname
145is device the file system is mounted from.
146This can be for example a block device such as
147.Pa /dev/wd0a
148or, if the file system is pseudo file system, the
149.Nm
150device name can be given by
151.Dv _PATH_PUFFS .
152This value is used for example in the first column of the output of
153.Xr mount 8
154and
155.Xr df 1 .
156.Ar puffsname
157is the file system type.
158It will always be prepended with the string "puffs|".
159If possible, file server binaries should be named using the format
160"mount_myfsnamehere" and this value should equal "myfsnamehere".
161A file system specific context pointer can optionally be given in
162.Ar private .
163This can be retrieved by
164.Fn puffs_getspecific .
165Flags for
166.Nm
167can be given via
168.Fa pflags .
169Currently the following flags are supported:
170.Bl -tag -width "XPUFFS_KFLAG_LOOKUP_FULLPNBUF"
171.It Dv PUFFS_KFLAG_NOCACHE_NAME
172Do not enter pathname components into the name cache.
173This means that every time the kernel does a lookup for a
174componentname, the file server will be consulted.
175.It Dv PUFFS_KFLAG_NOCACHE_PAGE
176Do not use the page cache.
177This means that all reads and writes to regular file are
178propagated to the file server for handling.
179This option makes a difference only for regular files.
180.It Dv PUFFS_KFLAG_NOCACHE
181An alias for both
182.Dv PUFFS_KFLAG_NOCACHE_NAME
183and
184.Dv PUFFS_KFLAG_NOCACHE_PAGE .
185.It Dv PUFFS_KFLAG_ALLOPS
186This flag requests that all operations are sent to userspace.
187Normally the kernel shortcircuits unimplemented operations.
188This flag is mostly useful for debugging purposes.
189.It Dv PUFFS_KFLAG_WTCACHE
190Set the file system cache behavior as write-through.
191This means that all writes are immediately issued to the file server
192instead of being flushed in file system sync.
193This is useful especially for distributed file systems.
194.It Dv PUFFS_KFLAG_IAONDEMAND
195Issue inactive only on demand.
196If a file server defines the inactive method, call it only if the file
197server has explicitly requested that inactive be called for the
198node in question.
199Once inactive has been called for a node, it will not be called
200again unless the request to call inactive is reissued by the file server.
201See
202.Fn puffs_setback
203in
204.Xr puffs_ops 3
205for more information.
206.It Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF
207This flag affects only the parameter
208.Ar pcn to
209.Fn puffs_node_lookup .
210If this flag is not given, only the next pathname component under
211lookup is found from
212.Ar pcn-\*[Gt]pcn_name .
213If this flag is given, the full path the kernel was
214asked to resolve can be found from there.
215.It Dv PUFFS_FLAG_BUILDPATH
216The framework will build a complete path name, which is supplied
217with each operation and can be found from the
218.Va pcn_po_full.po_path
219field in a
220.Vt struct puffs_cn .
221The option assumes that the framework can map a cookie to a
222.Vt struct puffs_node .
223See
224.Sx Cookies
225for more information on cookie mapping.
226See
227.Xr puffs_path 3
228for more information on library calls involving paths.
229.It Dv PUFFS_FLAG_HASHPATH
230Calculate a hash of the path into the path object field
231.Va po_hash .
232This hash value is used by
233.Fn puffs_path_walkcmp
234to avoid doing a full comparison for every path equal in length to
235the one searched for.
236Especially if the file system uses the abovementioned function, it
237is a good idea to define this flag.
238.It Dv PUFFS_FLAG_PNCOOKIE
239Tell puffs that cookies map to
240.Vt struct pnode .
241This is automagically set if
242.Fn puffs_pn_new
243is called.
244.It Dv PUFFS_KFLAG_CACHE_FS_TTL
245Enforce name and attribute caches based on file system-supplied TTL.
246In lookup, create, mknod, mkdir, and symlink, the file system must
247update the node attributes, their TTL, and the node name TTL through
248.Fn puffs_newinfo_setva ,
249.Fn puffs_newinfo_setvattl ,
250and
251.Fn puffs_newinfo_setcnttl .
252.Pp
253Additionally,
254.Fn puffs_node_getattr_ttl
255and
256.Fn puffs_node_setattr_ttl
257will be called instead of
258.Fn puffs_node_getattr
259and
260.Fn puffs_node_setattr .
261.It Dv PUFFS_KFLAG_CACHE_DOTDOT
262Never send lookups for
263.Dq ..
264to the file system.
265Parent vnodes are all kept active until their children are reclaimed.
266.It Dv PUFFS_KFLAG_NOFLUSH_META
267Do not send metadata cache flushes for time and size to the file system,
268which should take care of updating the values on its own.
269.It Dv PUFFS_FLAG_OPDUMP
270This option makes the framework dump a textual representation of
271each operation before executing it.
272It is useful for debugging purposes.
273.El
274.El
275.Pp
276The following functions can be used to query or modify the global
277state of the file system.
278Note, that all calls are not available at all times.
279.Bl -tag -width xxxx
280.It Fn puffs_getselectable "pu"
281Returns a handle to do I/O multiplexing with:
282.Xr select 2 ,
283.Xr poll 2 ,
284and
285.Xr kqueue 2
286are all examples of acceptable operations.
287.It Fn puffs_setblockingmode "pu" "mode"
288Sets the file system upstream access to blocking or non-blocking mode.
289Acceptable values for the argument are
290.Dv PUFFSDEV_BLOCK
291and
292.Dv PUFFSDEV_NONBLOCK .
293.Pp
294This routine can be called only after calling
295.Fn puffs_mount .
296.It Fn puffs_getstate "pu"
297Returns the state of the file system.
298It is maintained by the framework and is mostly useful for the framework
299itself.
300Possible values are
301.Dv PUFFS_STATE_BEFOREMOUNT ,
302.Dv PUFFS_STATE_RUNNING ,
303.Dv PUFFS_STATE_UNMOUNTING
304and
305.Dv PUFFS_STATE_UNMOUNTED .
306.It Fn puffs_setstacksize "pu" "stacksize"
307Sets the stack size used when running callbacks.
308The default is
309.Dv PUFFS_STACKSIZE_DEFAULT
310bytes of stack space per request.
311The minimum stacksize is architecture-dependent and can be specified
312by using the opaque constant
313.Dv PUFFS_STACKSIZE_MIN .
314.It Fn puffs_setroot "pu" "node"
315Sets the root node of mount
316.Fa pu
317to
318.Fa "node" .
319Setting the root node is currently required only if the path
320framework is used, see
321.Xr puffs_path 3 .
322.It Fn puffs_setrootinfo pu vt vsize rdev
323The default root node is a directory.
324In case the file system wants something different, it can call this
325function and set the type, size and possible device type to whatever
326it wants.
327This routine is independent of
328.Fn puffs_setroot .
329.It Fn puffs_getroot "pu"
330Returns the root node set earlier.
331.It Fn puffs_getspecific "pu"
332Returns the
333.Fa private
334argument of
335.Fn puffs_init .
336.It Fn puffs_setspecific "pu" "private"
337Can be used to set the specific data after the call to
338.Fn puffs_init .
339.It Fn puffs_setmaxreqlen "pu" "maxreqlen"
340In case the file system desires a maximum buffer length different from
341the default, the amount
342.Fa maxreqlen
343will be requested from the kernel when the file system is mounted.
344.Pp
345It is legal to call this function only between
346.Fn puffs_init
347and
348.Fn puffs_mount .
349.Pp
350.Em NOTE
351This does not currently work.
352.It Fn puffs_getmaxreqlen "pu"
353Returns the maximum request length the kernel will need for a single
354request.
355.Pp
356.Em NOTE
357This does not currently work.
358.It Fn puffs_setfhsize "pu" "fhsize" "flags"
359Sets the desired file handle size.
360This must be called if the file system wishes to support NFS exporting
361file systems of the
362.Fn fh*
363family of function calls.
364.Pp
365In case all nodes in the file system produce the same length file handle,
366it must be supplied as
367.Fa fhsize .
368In this case, the file system may ignore the length parameters in the
369file handle callback routines, as the kernel will always pass the
370correct length buffer.
371However, if the file handle size varies according to file, the argument
372.Fa fhsize
373defines the maximum size of a file handle for the file system.
374In this case the file system must take care of the handle lengths by
375itself in the file handle callbacks, see
376.Xr puffs_ops 3
377for more information.
378Also, the flag
379.Dv PUFFS_FHFLAG_DYNAMIC
380must be provided in the argument
381.Fa flags .
382.Pp
383In case the file system wants to sanity check its file handle lengths
384for the limits of NFS, it can supply
385.Dv PUFFS_FHFLAG_NFSV2
386and
387.Dv PUFFS_FHFLAG_NFSV3
388in the
389.Fa flags
390parameter.
391It is especially important to note that these are not directly the
392limits specified by the protocols, as the kernel uses some bytes from
393the buffer space.
394In case the file handles are too large, mount will return an error.
395.Pp
396It is legal to call this function only between
397.Fn puffs_init
398and
399.Fn puffs_mount .
400.It Fn puffs_setncookiehash "pu" "ncookiehash"
401The parameter
402.Fa ncookiehash
403controls the amount of hash buckets the kernel has for reverse lookups
404from cookie to vnode.
405Technically the default is enough, but a memory/time tradeoff can be
406made by increasing this for file systems which know they will have
407very many active files.
408.Pp
409It is legal to call this function only between
410.Fn puffs_init
411and
412.Fn puffs_mount .
413.El
414.Pp
415After the correct setup for the library has been established and the
416backend has been initialized the file system is made operational by calling
417.Fn puffs_mount .
418After this function returns the file system should start processing requests.
419.Bl -tag -width xxxx
420.It Fn puffs_mount pu dir mntflags root_cookie
421.Ar pu
422is the library context pointer from
423.Fn puffs_init .
424The argument
425.Fa dir
426signifies the mount point and
427.Fa mntflags
428is the flagset given to
429.Xr mount 2 .
430The value
431.Ar root_cookie
432will be used as the cookie for the file system root node.
433.El
434.Ss Using the built-in eventloop
435.Bl -tag -width xxxx
436.It Fn puffs_ml_loop_fn pu
437Loop function signature.
438.It Fn puffs_ml_setloopfn pu lfn
439Set loop function to
440.Ar lfn .
441This function is called once each time the event loop loops.
442It is not a well-defined interval, but it can be made fairly regular
443by setting the loop timeout by
444.Fn puffs_ml_settimeout .
445.It Fn puffs_ml_settimeout pu ts
446Sets the loop timeout to
447.Ar ts
448or disables it if
449.Ar ts
450is
451.Dv NULL .
452This can be used to roughly control how often the loop callback
453.Fn lfn
454is called
455.It Fn puffs_daemon pu nochdir noclose
456Detach from the console like
457.Fn daemon 3 .
458This call synchronizes with
459.Fn puffs_mount
460and the foreground process does not exit before the file system mount
461call has returned from the kernel.
462Since this routine internally calls fork, it has to be called
463.Em before
464.Fn puffs_mount .
465.It Fn puffs_mainloop pu flags
466Handle all requests automatically until the file system is unmounted.
467It returns 0 if the file system was successfully unmounted or \-1 if it
468was killed in action.
469.Pp
470In case
471.Xr puffs_framebuf 3
472has been initialized, I/O from the relevant descriptors is processed
473automatically by the eventloop.
474.It Fn puffs_unmountonsignal signum ignoresig
475Cause all file servers within the process to initiate unmount upon
476receipt of signal
477.Ar signum .
478This works only for servers which call
479.Fn puffs_mainloop
480and must be called before any server within the process enters the mainloop.
481The process signal handler is still called before starting the unmount
482procedure.
483The parameter
484.Ar ignoresig
485is provided as a convenience and tells if to install a signal handler
486to ignore
487.Ar sig
488so that the process will not e.g. terminate based on the default action
489before the file system unmount can be initiated.
490.It Fn puffs_dispatch_create pu pb pccp
491.It Fn puffs_dispatch_exec pcc pbp
492In case the use of
493.Fn puffs_mainloop
494is not possible, requests may be dispatched manually.
495However, as this is less efficient than using the mainloop,
496it should never be the first preference.
497.Pp
498Calling
499.Fn puffs_dispatch_create
500creates a dispatch request.
501The argument
502.Ar pb
503should contains a valid request and upon success
504.Ar pccp
505will contain a valid request context.
506This context is passed to
507.Fn puffs_dispatch_exec
508to execute the request.
509If the request yielded before completing, the routine returns 0,
510otherwise 1.
511When the routine completes,
512.Ar pcc
513is made invalid and a pointer to the processed buffer is placed in
514.Ar pbp .
515It is the responsibility of the caller to send the response (if
516necessary) and destroy the buffer.
517.Pp
518See
519.Xr puffs_cc 3
520and
521.Xr puffs_framebuf 3
522for further information.
523.El
524.Ss Cookies
525Every file (regular file, directory, device node, ...) instance is
526attached to the kernel using a cookie.
527A cookie should uniquely map to a file during its lifetime.
528If file instances are kept in memory, a simple strategy is to use
529the virtual address of the structure describing the file.
530The cookie can be recycled when
531.Fn puffs_node_reclaim
532is called for a node.
533.Pp
534For some operations (such as building paths) the framework needs to map
535the cookie to the framework-level structure describing a file,
536.Vt struct puffs_node .
537It is advisable to simply use the
538.Vt struct puffs_node
539address as a cookie and store file system specific data in the private
540portion of
541.Vt struct puffs_node .
542The library assumes this by default.
543If it is not desirable, the file system implementation can call
544.Fn puffs_set_cookiemap
545to provide an alternative cookie-to-node mapping function.
546.Sh SEE ALSO
547.Xr mount 2 ,
548.Xr puffs_cc 3 ,
549.Xr puffs_cred 3 ,
550.Xr puffs_flush 3 ,
551.Xr puffs_framebuf 3 ,
552.Xr puffs_node 3 ,
553.Xr puffs_ops 3 ,
554.Xr puffs_path 3 ,
555.Xr refuse 3 ,
556.Xr puffs 4
557.Rs
558.%A Antti Kantee
559.%D March 2007
560.%J Proceedings of AsiaBSDCon 2007
561.%P pp. 29-42
562.%T puffs - Pass-to-Userspace Framework File System
563.Re
564.Rs
565.%A Antti Kantee
566.%D September 2007
567.%I Helsinki University of Technology
568.%R Tech Report TKK-TKO-B157
569.%T Using puffs for Implementing Client-Server Distributed File Systems
570.Re
571.Rs
572.%A Antti Kantee
573.%A Alistair Crooks
574.%D September 2007
575.%J EuroBSDCon 2007
576.%T ReFUSE: Userspace FUSE Reimplementation Using puffs
577.Re
578.Rs
579.%A Antti Kantee
580.%D March 2008
581.%J Proceedings of AsiaBSDCon 2008
582.%P pp. 55-70
583.%T Send and Receive of File System Protocols: Userspace Approach With puffs
584.Re
585.Sh HISTORY
586An unsupported experimental version of
587.Nm
588first appeared in
589.Nx 4.0 .
590A stable version appeared in
591.Nx 5.0 .
592.Sh AUTHORS
593.An Antti Kantee Aq Mt pooka@iki.fi
594