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