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