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