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