Fix some typos.
[dragonfly.git] / lib / libpuffs / puffs_ops.3
... / ...
CommitLineData
1.\" $NetBSD: puffs_ops.3,v 1.29 2011/07/04 08:07:30 manu Exp $
2.\"
3.\" Copyright (c) 2007 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 5, 2012
27.Dt PUFFS_OPS 3
28.Os
29.Sh NAME
30.Nm puffs_ops
31.Nd puffs callback operations
32.Sh LIBRARY
33.Lb libpuffs
34.Sh SYNOPSIS
35.In puffs.h
36.Ft int
37.Fo puffs_fs_statvfs
38.Fa "struct puffs_usermount *pu" "struct statvfs *sbp"
39.Fc
40.Ft int
41.Fo puffs_fs_sync
42.Fa "struct puffs_usermount *pu" "int waitfor" "const struct puffs_cred *pcr"
43.Fc
44.Ft int
45.Fo puffs_fs_fhtonode
46.Fa "struct puffs_usermount *pu" "void *fid" "size_t fidsize"
47.Fa "struct puffs_newinfo *pni"
48.Fc
49.Ft int
50.Fo puffs_fs_nodetofh
51.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "void *fid"
52.Fa "size_t *fidsize"
53.Fc
54.Ft void
55.Fo puffs_fs_extattrctl
56.Fa "struct puffs_usermount *pu" "int cmd" "puffs_cookie_t cookie" "int flags"
57.Fa "int attrnamespace" "const char *attrname"
58.Fc
59.Ft int
60.Fo puffs_fs_unmount
61.Fa "struct puffs_usermount *pu" "int flags"
62.Fc
63.Ft int
64.Fo puffs_node_lookup
65.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
66.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
67.Fc
68.Ft int
69.Fo puffs_node_create
70.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
71.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
72.Fa "const struct vattr *vap"
73.Fc
74.Ft int
75.Fo puffs_node_mknod
76.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
77.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
78.Fa "const struct vattr *vap"
79.Fc
80.Ft int
81.Fo puffs_node_open
82.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
83.Fa "const struct puffs_cred *pcr"
84.Fc
85.Ft int
86.Fo puffs_node_close
87.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
88.Fa "const struct puffs_cred *pcr"
89.Fc
90.Ft int
91.Fo puffs_node_access
92.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
93.Fa "const struct puffs_cred *pcr"
94.Fc
95.Ft int
96.Fo puffs_node_getattr
97.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap"
98.Fa "const struct puffs_cred *pcr"
99.Fc
100.Ft int
101.Fo puffs_node_setattr
102.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "const struct vattr *vap"
103.Fa "const struct puffs_cred *pcr"
104.Fc
105.Ft int
106.Fo puffs_node_poll
107.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int *events"
108.Fc
109.Ft int
110.Fo puffs_node_mmap
111.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
112.Fa "const struct puffs_cred *pcr"
113.Fc
114.Ft int
115.Fo puffs_node_fsync
116.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
117.Fa "int flags"
118.Fc
119.Ft int
120.Fo puffs_node_seek
121.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t oldoff"
122.Fa "off_t newoff" "const struct puffs_cred *pcr"
123.Fc
124.Ft int
125.Fo puffs_node_remove
126.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
127.Fa "const struct puffs_cn *pcn"
128.Fc
129.Ft int
130.Fo puffs_node_link
131.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
132.Fa "const struct puffs_cn *pcn"
133.Fc
134.Ft int
135.Fo puffs_node_rename
136.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t src"
137.Fa "const struct puffs_cn *pcn_src" "puffs_cookie_t targ_dir"
138.Fa "puffs_cookie_t targ" "const struct puffs_cn *pcn_targ"
139.Fc
140.Ft int
141.Fo puffs_node_mkdir
142.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
143.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
144.Fa "const struct vattr *vap"
145.Fc
146.Ft int
147.Fo puffs_node_rmdir
148.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
149.Fa "const struct puffs_cn *pcn"
150.Fc
151.Ft int
152.Fo puffs_node_readdir
153.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct dirent *dent"
154.Fa "off_t *readoff" "size_t *reslen" "const struct puffs_cred *pcr"
155.Fa "int *eofflag" "off_t *cookies" "size_t *ncookies"
156.Fc
157.Ft int
158.Fo puffs_node_symlink
159.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
160.Fa "struct puffs_newinfo *pni"
161.Fa "const struct puffs_cn *pcn_src" "const struct vattr *vap"
162.Fa "const char *link_target"
163.Fc
164.Ft int
165.Fo puffs_node_readlink
166.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
167.Fa "const struct puffs_cred *pcr" "char *link" "size_t *linklen"
168.Fc
169.Ft int
170.Fo puffs_node_read
171.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
172.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
173.Fc
174.Ft int
175.Fo puffs_node_write
176.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf"
177.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag"
178.Fc
179.Ft int
180.Fo puffs_node_abortop
181.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
182.Fa "const struct puffs_cn *pcn"
183.Fc
184.Ft int
185.Fo puffs_node_getextattr
186.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
187.Fa "const char *attrname" "size_t *attrsize" "uint8_t *attr" "size_t *resid"
188.Fa "const struct puffs_cred *pcr"
189.Fc
190.Ft int
191.Fo puffs_node_setextattr
192.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
193.Fa "const char *attrname" "uint8_t *attr" "size_t *resid"
194.Fa "const struct puffs_cred *pcr"
195.Fc
196.Ft int
197.Fo puffs_node_listextattr
198.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
199.Fa "size_t *attrssize" "uint8_t *attrs" "iint flag" "size_t *resid"
200.Fa "const struct puffs_cred *pcr"
201.Fc
202.Ft int
203.Fo puffs_node_deleteextattr
204.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace"
205.Fa "const char *attrname"
206.Fa "const struct puffs_cred *pcr"
207.Fc
208.Ft int
209.Fn puffs_node_print "struct puffs_usermount *pu" "puffs_cookie_t opc"
210.Ft int
211.Fo puffs_node_reclaim
212.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
213.Fc
214.Ft int
215.Fo puffs_node_inactive
216.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
217.Fc
218.Ft void
219.Fn puffs_setback "struct puffs_cc *pcc" "int op"
220.Ft void
221.Fn puffs_newinfo_setcookie "struct puffs_newinfo *pni" "puffs_cookie_t cookie"
222.Ft void
223.Fn puffs_newinfo_setvtype "struct puffs_newinfo *pni" "enum vtype vtype"
224.Ft void
225.Fn puffs_newinfo_setsize "struct puffs_newinfo *pni" "voff_t size"
226.Sh DESCRIPTION
227The operations
228.Nm puffs
229requires to function can be divided into two categories: file system
230callbacks and node callbacks.
231The former affect the entire file system while the latter are targeted
232at a file or a directory and a file.
233They are roughly equivalent to the vfs and vnode operations in the
234kernel.
235.Pp
236All callbacks can be prototyped with the file system name and operation
237name using the macro
238.Fn PUFFSOP_PROTOS fsname .
239.Ss File system callbacks (puffs_fs)
240.Bl -tag -width xxxx
241.It Fn puffs_fs_statvfs "pu" "sbp"
242The following fields of the argument
243.Fa sbp
244need to be filled:
245.Bd -literal
246 * unsigned long f_bsize; file system block size
247 * unsigned long f_frsize; fundamental file system block size
248 * fsblkcnt_t f_blocks; number of blocks in file system,
249 * (in units of f_frsize)
250 *
251 * fsblkcnt_t f_bfree; free blocks avail in file system
252 * fsblkcnt_t f_bavail; free blocks avail to non-root
253 * fsblkcnt_t f_bresvd; blocks reserved for root
254
255 * fsfilcnt_t f_files; total file nodes in file system
256 * fsfilcnt_t f_ffree; free file nodes in file system
257 * fsfilcnt_t f_favail; free file nodes avail to non-root
258 * fsfilcnt_t f_fresvd; file nodes reserved for root
259
260.Ed
261.It Fn puffs_fs_sync "pu" "waitfor" "pcr"
262All the dirty buffers that have been cached at the file server
263level including metadata should be committed to stable storage.
264The
265.Fa waitfor
266parameter affects the operation.
267Possible values are:
268.Bl -tag -width XMNT_NOWAITX
269.It Dv MNT_WAIT
270Wait for all I/O for complete until returning.
271.It Dv MNT_NOWAIT
272Initiate I/O, but do not wait for completion.
273.It Dv MNT_LAZY
274Synchorize data not synchoronized by the file system syncer,
275i.e. data not written when
276.Fn node_fsync
277is called with
278.Dv FSYNC_LAZY .
279.El
280.Pp
281The credentials for the initiator of the sync operation are present in
282.Fa pcr
283and will usually be either file system or kernel credentials, but might
284also be user credentials.
285However, most of the time it is advisable to sync regardless of the
286credentials of the caller.
287.It Fn puffs_fs_fhtonode "pu" "fid" "fidsize" "pni"
288Translates a file handle
289.Fa fid
290to a node.
291The parameter
292.Fa fidsize
293indicates how large the file handle is.
294In case the file system's handles are static length, this parameter can
295be ignored as the kernel guarantees all file handles passed to the file
296server are of correct length.
297For dynamic length handles the field should be examined and
298.Er EINVAL
299returned in case the file handle length is not correct.
300.Pp
301This function provides essentially the same information to the kernel as
302.Fn puffs_node_lookup .
303The information is necessary for creating a new vnode corresponding to
304the file handle.
305.It Fn puffs_fs_nodetofh "pu" "cookie" "fid" "fidsize"
306Create a file handle from the node described by
307.Fa cookie .
308The file handle should contain enough information to reliably identify
309the node even after reboots and the pathname/inode being replaced by
310another file.
311If this is not possible, it is up to the author of the file system to
312act responsibly and decide if the file system can support file handles
313at all.
314.Pp
315For file systems which want dynamic length file handles, this function
316must check if the file handle space indicated by
317.Fa fidsize
318is large enough to accommodate the file handle for the node.
319If not, it must fill in the correct size and return
320.Er E2BIG .
321In either case, the handle length should be supplied to the kernel in
322.Fa fidsize .
323File systems with static length handles can ignore the size parameter as
324the kernel always supplies the correct size buffer.
325.It Fn puffs_fs_unmount "pu" "flags"
326Unmount the file system.
327The kernel has assumedly flushed all cached data when this callback
328is executed.
329If the file system cannot currently be safely be unmounted, for whatever
330reason, the kernel will honor an error value and not forcibly unmount.
331However, if the flag
332.Dv MNT_FORCE
333is not honored by the file server, the kernel will forcibly unmount
334the file system.
335.El
336.Ss Node callbacks
337These operations operate in the level of individual files.
338The file cookie is always provided as the second argument
339.Fa opc .
340If the operation is for a file, it will be the cookie of the file.
341The case the operation involves a directory (such as
342.Dq create file in directory ) ,
343the cookie will be for the directory.
344Some operations take additional cookies to describe the rest of
345the operands.
346The return value 0 signals success, else an appropriate errno value
347should be returned.
348Please note that neither this list nor the descriptions are complete.
349.Bl -tag -width xxxx
350.It Fn puffs_node_lookup "pu" "opc" "pni" "pcn"
351This function is used to locate nodes, or in other words translate
352pathname components to file system data structures.
353The implementation should match the name in
354.Fa pcn
355against the existing entries in the directory provided by the cookie
356.Fa opc .
357If found, the cookie for the located node should be set in
358.Fa pni
359using
360.Fn puffs_newinfo_setcookie .
361Additionally, the vnode type and size (latter applicable to regular files only)
362should be set using
363.Fn puffs_newinfo_setvtype
364and
365.Fn puffs_newinfo_setsize ,
366respectively.
367.Pp
368The type of operation is found from
369.Va pcn-\*[Gt]pcn_nameiop :
370.Bl -tag -width XNAMEI_LOOKUPX
371.It Dv NAMEI_LOOKUP
372Normal lookup operation.
373.It Dv NAMEI_CREATE
374Lookup to create a node.
375.It Dv NAMEI_DELETE
376Lookup for node deletion.
377.It Dv NAMEI_RENAME
378Lookup for the target of a rename operation (source will be looked
379up using
380.Dv NAMEI_DELETE ) .
381.El
382.Pp
383The final component from a pathname lookup usually requires special
384treatment.
385It can be identified by looking at the
386.Va pcn-\*[Gt]pcn_flags
387fields for the flag
388.Dv PUFFSLOOKUP_ISLASTCN .
389For example, in most cases the lookup operation will want to check if
390a delete, rename or create operation has enough credentials to perform
391the operation.
392.Pp
393The return value 0 signals a found node and a nonzero value signals
394an errno.
395As a special case,
396.Er ENOENT
397signals "success" for cases where the lookup operation is
398.Dv NAMEI_CREATE
399or
400.Dv NAMEI_RENAME .
401Failure in these cases can be signalled by returning another appropriate
402error code, for example
403.Er EACCESS .
404.Pp
405Usually a null-terminated string for the next pathname component is
406provided in
407.Ar pcn-\*[Gt]pcn_name .
408In case the file system is using the option
409.Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF ,
410the remainder of the complete pathname under lookup is found in
411the same location.
412.Ar pcn-\*[Gt]pcn_namelen
413always specifies the length of the next component.
414If operating with a full path, the file system is allowed to consume
415more than the next component's length in node lookup.
416This is done by setting
417.Ar pcn-\*[Gt]pcn_consume
418to indicate the amount of
419.Em extra
420characters in addition to
421.Ar pcn-\*[Gt]pcn_namelen
422processed.
423.It Fn puffs_node_create "pu" "opc" "pni" "pcn" "va"
424.It Fn puffs_node_mkdir "pu" "opc" "pni" "pcn" "va"
425.It Fn puffs_node_mknod "pu" "opc" "pni" "pcn" "va"
426A file node is created in the directory denoted by the cookie
427.Fa opc
428by any of the above callbacks.
429The name of the new file can be found from
430.Fa pcn
431and the attributes are specified by
432.Fa va
433and the cookie for the newly created node should be set in
434.Fa pni .
435The only difference between these three is that they create a regular
436file, directory and device special file, respectively.
437.Pp
438In case of mknod, the device identifier can be found in
439.Fa va-\*[Gt]va_rdev .
440.It Fn puffs_node_open "pu" "opc" "mode" "pcr"
441Open the node denoted by the cookie
442.Fa opc .
443The parameter
444.Fa mode
445specifies the flags that
446.Xr open 2
447was called with, e.g.
448.Dv O_APPEND
449and
450.Dv O_NONBLOCK .
451.It Fn puffs_node_close "pu" "opc" "flags" "pcr"
452Close a node.
453The parameter
454.Fa flags
455parameter describes the flags that the file was opened with.
456.It Fn puffs_node_access "pu" "opc" "mode" "pcr"
457Check if the credentials of
458.Fa pcr
459have the right to perform the operation specified by
460.Fa mode
461onto the node
462.Fa opc .
463The argument
464.Fa mode
465can specify read, write or execute by
466.Dv PUFFS_VREAD ,
467.Dv PUFFS_VWRITE ,
468and
469.Dv PUFFS_VEXEC ,
470respectively.
471.It Fn puffs_node_getattr "pu" "opc" "va" "pcr"
472The attributes of the node specified by
473.Fa opc
474must be copied to the space pointed by
475.Fa va .
476.It Fn puffs_node_setattr "pu" "opc" "va" "pcr"
477The attributes for the node specified by
478.Fa opc
479must be set to those contained in
480.Fa va .
481Only fields of
482.Fa va
483which contain a value different from
484.Dv PUFFS_VNOVAL
485(typecast to the field's type!) contain a valid value.
486.It Fn puffs_node_poll "pu" "opc" "events"
487Poll for events on node
488.Ar opc .
489If
490.Xr poll 2
491events specified in
492.Ar events
493are available, the function should set the bitmask to match available
494events and return immediately.
495Otherwise, the function should block (yield) until some events in
496.Ar events
497become available and only then set the
498.Ar events
499bitmask and return.
500.Pp
501In case this function returns an error,
502.Dv POLLERR
503(or it's
504.Xr select 2
505equivalent) will be delivered to the calling process.
506.Pp
507.Em NOTE!
508The system call interface for
509.Fn poll
510contains a timeout parameter.
511At this level, however, the timeout is not supplied.
512In case input does not arrive, the file system should periodically
513unblock and return 0 new events to avoid hanging forever.
514This will hopefully be better supported by libpuffs in the future.
515.It Fn puffs_node_mmap "pu" "opc" "flags" "pcr"
516Called when a regular file is being memory mapped by
517.Xr mmap 2 .
518.Fa flags
519is currently always 0.
520.It Fn puffs_node_fsync "pu" "opc" "pcr" "flags" "offlo" "offhi"
521Sychronize a node's contents onto stable storage.
522This is necessary only if the file server caches some information
523before committing it.
524The parameter
525.Fa flags
526specifies the minimum level of sychronization required (XXX: they are
527not yet available).
528The parameters
529.Fa offlo
530and
531.Fa offhi
532specify the data offsets requiring to be synced.
533A high offset of 0 means sync from
534.Fa offlo
535to the end of the file.
536.It Fn puffs_node_seek "pu" "opc" "oldoff" "newoff" "pcr"
537Test if the node
538.Ar opc
539is seekable to the location
540.Ar newoff .
541The argument
542.Ar oldoff
543specifies the offset we are starting the seek from.
544Most file systems dealing only with regular will choose to not
545implement this.
546However, it is useful for example in cases where files are
547unseekable streams.
548.It Fn puffs_node_remove "pu" "opc" "targ" "pcn"
549.It Fn puffs_node_rmdir "pu" "opc" "targ" "pcn"
550Remove the node
551.Fa targ
552from the directory indicated by
553.Fa opc .
554The directory entry name to be removed is provided by
555.Fa pcn .
556The rmdir operation removes only directories, while the remove
557operation removes all other types except directories.
558.Pp
559It is paramount to note that the file system may not remove the
560node data structures at this point, only the directory entry and prevent
561lookups from finding the node again.
562This is to retain the
563.Ux
564open file semantics.
565The data may be removed only when
566.Fn puffs_node_reclaim
567is called for the node, as this assures there are no further users.
568.It Fn puffs_node_link "pu" "opc" "targ" "pcn"
569Create a hard link for the node
570.Fa targ
571into the directory
572.Fa opc .
573The argument
574.Fa pcn
575provides the directory entry name for the new link.
576.It Fn puffs_node_rename "pu" "src_dir" "src" "pcn_src" "targ_dir" "targ" "pcn_targ"
577Rename the node
578.Fa src
579with the name specified by
580.Fa pcn_src
581from the directory
582.Fa src_dir .
583The target directory and target name are given by
584.Fa targ_dir
585and
586.Fa pcn_targ ,
587respectively.
588.Em If
589the target node already exists, it is specified by
590.Fa targ
591and must be replaced atomically.
592Otherwise
593.Fa targ
594is gives as
595.Dv NULL .
596.Pp
597It is legal to replace a directory node by another directory node with
598the means of rename if the target directory is empty, otherwise
599.Er ENOTEMPTY
600should be returned.
601All other types can replace all other types.
602In case a rename between incompatible types is attempted, the errors
603.Er ENOTDIR
604or
605.Er EISDIR
606should be returned, depending on the target type.
607.It Fn puffs_node_readdir "pu" "opc" "dent" "readoff" "reslen" "pcr" "eofflag" "cookies" "ncookies"
608To read directory entries,
609.Fn puffs_node_readdir
610is called.
611It should store directories as
612.Va struct dirent
613in the space pointed to by
614.Fa dent .
615The amount of space available is given by
616.Fa reslen
617and before returning it should be set to the amount of space
618.Em remaining
619in the buffer.
620The argument
621.Fa offset
622is used to specify the offset to the directory.
623Its interpretation is up to the file system and it should be set to
624signal the continuation point when there is no more room for the next
625entry in
626.Fa dent .
627It is most performant to return the maximal amount of directory
628entries each call.
629It is easiest to generate directory entries by using
630.Fn puffs_nextdent ,
631which also automatically advances the necessary pointers.
632.Pp
633In case end-of-directory is reached,
634.Fa eofflag
635should be set to one.
636Note that even a new call to readdir may start where
637.Fa readoff
638points to end-of-directory.
639.Pp
640If the file system supports file handles, the arguments
641.Fa cookies
642and
643.Fa ncookies
644must be filled out.
645.Fa cookies
646is a vector for offsets corresponding to read offsets.
647One cookie should be filled out for each directory entry.
648The value of the cookie should equal the offset of the
649.Em next
650directory entry, i.e. which offset should be passed to readdir for
651the first entry read to be the entry following the current one.
652.Fa ncookies
653is the number of slots for cookies in the cookie vector upon entry to
654the function and must be set to the amount of cookies stored in the
655vector (i.e. amount of directory entries read) upon exit.
656There is always enough space in the cookie vector for the maximal number
657of entries that will fit into the directory entry buffer.
658For filling out the vector, the helper function
659.Fn PUFFS_STORE_DCOOKIE cookies ncookies offset
660can be used.
661This properly checks against
662.Fa cookies
663being
664.Dv NULL .
665Note that
666.Fa ncookies
667must be initialized to zero before the first call to
668.Fn PUFFS_STORE_DCOOKIE .
669.It Fn puffs_node_symlink "pu" "opc" "pni" "pcn_src" "va" "link_target"
670Create a symbolic link into the directory
671.Fa opc
672with the name in
673.Fa pcn_src
674and the initial attributes in
675.Fa va .
676The argument
677.Ar link_target
678contains a null-terminated string for the link target.
679The created node cookie should be set in
680.Fa pni .
681.It Fn puffs_node_readlink "pu" "opc" "pcr" "link" "linklen"
682Read the target of a symbolic link
683.Fa opc .
684The result is placed in the buffer pointed to by
685.Fa link .
686This buffer's length is given in
687.Fa linklen
688and it must be updated to reflect the real link length.
689A terminating nul character should not be put into the buffer and
690.Em "must not"
691be included in the link length.
692.It Fn puffs_node_read "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
693Read the contents of a file
694.Fa opc .
695It will gather the data from
696.Fa offset
697in the file and read the number
698.Fa resid
699octets.
700The buffer is guaranteed to have this much space.
701The amount of data requested by
702.Fa resid
703should be read, except in the case of eof-of-file or an error.
704The parameter
705.Fa resid
706should be set to indicate the amount of request NOT completed.
707In the normal case this should be 0.
708.It Fn puffs_node_write "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
709.Fn puffs_node_write
710Write data to a file
711.Fa opc
712at
713.Fa offset
714and extend the file if necessary.
715The number of octets written is indicated by
716.Fa resid ;
717everything must be written or an error will be generated.
718The parameter must be set to indicate the amount of data NOT written.
719In case the flag
720.Dv PUFFS_IO_APPEND
721is specified, the data should be appended to the end of the file.
722.It Fn puffs_node_print "pu" "opc"
723Print information about node.
724This is used only for kernel-initiated diagnostic purposes.
725.It Fn puffs_node_reclaim "pu" "opc"
726The kernel will no longer reference the cookie and resources associated
727with it may be freed.
728In case the file
729.Fa opc
730has a link count of zero, it may be safely removed now.
731.It Fn puffs_node_abortop "pu" "opc" "pcn"
732In case the operation following lookup (e.g. mkdir or remove) is not
733executed for some reason, abortop will be issued.
734This is useful only for servers which cache state between lookup
735and a directory operation and is generally left unimplemented.
736.It Fn puffs_node_inactive "pu" "opc"
737The node
738.Fa opc
739has lost its last reference in the kernel.
740However, the cookie must still remain valid until
741.Fn puffs_node_reclaim
742is called.
743.It Fn puffs_setback "pcc" "op"
744Issue a "setback" operation which will be handled when the request response
745is returned to the kernel.
746Currently this can be only called from mmap, open, remove and rmdir.
747The valid parameters for
748.Ar op
749are
750.Dv PUFFS_SETBACK_INACT_N1
751and
752.Dv PUFFS_SETBACK_INACT_N2 .
753These signal that a file system mounted with
754.Dv PUFFS_KFLAG_IAONDEMAND
755should call the file system inactive method for the specified node.
756The node number 1 always means the operation cookie
757.Ar opc ,
758while the node number 2 can be used to specify the second node argument
759present in some methods, e.g. remove.
760.It Fn puffs_newinfo_setcookie pni cookie
761Set cookie for node provided by this method to
762.Ar cookie .
763.It Fn puffs_newinfo_setvtype pni vtype
764Set the type of the newly located node to
765.Ar vtype .
766This call is valid only for
767.Fn lookup
768and
769.Fn fhtonode .
770.It Fn puffs_newinfo_setsize pni size
771Set the size of the newly located node to
772.Ar size .
773If left unset, the value defaults to 0.
774This call is valid only for
775.Fn lookup
776and
777.Fn fhtovp .
778.El
779.Sh SEE ALSO
780.Xr puffs 3
781.\".Xr vfsops 9 ,
782.\".Xr vnodeops 9