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