1 .\" $NetBSD: puffs_ops.3,v 1.29 2011/07/04 08:07:30 manu Exp $
3 .\" Copyright (c) 2007 Antti Kantee. All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
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.
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
31 .Nd puffs callback operations
38 .Fa "struct puffs_usermount *pu" "struct statvfs *sbp"
42 .Fa "struct puffs_usermount *pu" "int waitfor" "const struct puffs_cred *pcr"
46 .Fa "struct puffs_usermount *pu" "void *fid" "size_t fidsize"
47 .Fa "struct puffs_newinfo *pni"
51 .Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "void *fid"
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"
61 .Fa "struct puffs_usermount *pu" "int flags"
65 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
66 .Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn"
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"
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"
82 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
83 .Fa "const struct puffs_cred *pcr"
87 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
88 .Fa "const struct puffs_cred *pcr"
92 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode"
93 .Fa "const struct puffs_cred *pcr"
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"
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"
107 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int *events"
111 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags"
112 .Fa "const struct puffs_cred *pcr"
116 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
121 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t oldoff"
122 .Fa "off_t newoff" "const struct puffs_cred *pcr"
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"
131 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
132 .Fa "const struct puffs_cn *pcn"
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"
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"
148 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ"
149 .Fa "const struct puffs_cn *pcn"
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"
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"
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"
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"
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"
180 .Fo puffs_node_abortop
181 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
182 .Fa "const struct puffs_cn *pcn"
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"
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"
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" "int flag" "size_t *resid"
200 .Fa "const struct puffs_cred *pcr"
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"
209 .Fn puffs_node_print "struct puffs_usermount *pu" "puffs_cookie_t opc"
211 .Fo puffs_node_reclaim
212 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
215 .Fo puffs_node_inactive
216 .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc"
219 .Fn puffs_setback "struct puffs_cc *pcc" "int op"
221 .Fn puffs_newinfo_setcookie "struct puffs_newinfo *pni" "puffs_cookie_t cookie"
223 .Fn puffs_newinfo_setvtype "struct puffs_newinfo *pni" "enum vtype vtype"
225 .Fn puffs_newinfo_setsize "struct puffs_newinfo *pni" "voff_t size"
229 requires to function can be divided into two categories: file system
230 callbacks and node callbacks.
231 The former affect the entire file system while the latter are targeted
232 at a file or a directory and a file.
233 They are roughly equivalent to the vfs and vnode operations in the
236 All callbacks can be prototyped with the file system name and operation
238 .Fn PUFFSOP_PROTOS fsname .
239 .Ss File system callbacks (puffs_fs)
241 .It Fn puffs_fs_statvfs "pu" "sbp"
242 The following fields of the argument
246 * unsigned long f_bsize; file system block size
247 * unsigned long f_frsize; fundamental file system block size
248 * fsblkcnt_t f_blocks; number of blocks in file system,
249 * (in units of f_frsize)
251 * fsblkcnt_t f_bfree; free blocks avail in file system
252 * fsblkcnt_t f_bavail; free blocks avail to non-root
253 * fsblkcnt_t f_bresvd; blocks reserved for root
255 * fsfilcnt_t f_files; total file nodes in file system
256 * fsfilcnt_t f_ffree; free file nodes in file system
257 * fsfilcnt_t f_favail; free file nodes avail to non-root
258 * fsfilcnt_t f_fresvd; file nodes reserved for root
261 .It Fn puffs_fs_sync "pu" "waitfor" "pcr"
262 All the dirty buffers that have been cached at the file server
263 level including metadata should be committed to stable storage.
266 parameter affects the operation.
268 .Bl -tag -width XMNT_NOWAITX
270 Wait for all I/O for complete until returning.
272 Initiate I/O, but do not wait for completion.
274 Synchorize data not synchoronized by the file system syncer,
275 i.e. data not written when
281 The credentials for the initiator of the sync operation are present in
283 and will usually be either file system or kernel credentials, but might
284 also be user credentials.
285 However, most of the time it is advisable to sync regardless of the
286 credentials of the caller.
287 .It Fn puffs_fs_fhtonode "pu" "fid" "fidsize" "pni"
288 Translates a file handle
293 indicates how large the file handle is.
294 In case the file system's handles are static length, this parameter can
295 be ignored as the kernel guarantees all file handles passed to the file
296 server are of correct length.
297 For dynamic length handles the field should be examined and
299 returned in case the file handle length is not correct.
301 This function provides essentially the same information to the kernel as
302 .Fn puffs_node_lookup .
303 The information is necessary for creating a new vnode corresponding to
305 .It Fn puffs_fs_nodetofh "pu" "cookie" "fid" "fidsize"
306 Create a file handle from the node described by
308 The file handle should contain enough information to reliably identify
309 the node even after reboots and the pathname/inode being replaced by
311 If this is not possible, it is up to the author of the file system to
312 act responsibly and decide if the file system can support file handles
315 For file systems which want dynamic length file handles, this function
316 must check if the file handle space indicated by
318 is large enough to accommodate the file handle for the node.
319 If not, it must fill in the correct size and return
321 In either case, the handle length should be supplied to the kernel in
323 File systems with static length handles can ignore the size parameter as
324 the kernel always supplies the correct size buffer.
325 .It Fn puffs_fs_unmount "pu" "flags"
326 Unmount the file system.
327 The kernel has assumedly flushed all cached data when this callback
329 If the file system cannot currently be safely be unmounted, for whatever
330 reason, the kernel will honor an error value and not forcibly unmount.
333 is not honored by the file server, the kernel will forcibly unmount
337 These operations operate in the level of individual files.
338 The file cookie is always provided as the second argument
340 If the operation is for a file, it will be the cookie of the file.
341 The case the operation involves a directory (such as
342 .Dq create file in directory ) ,
343 the cookie will be for the directory.
344 Some operations take additional cookies to describe the rest of
346 The return value 0 signals success, else an appropriate errno value
348 Please note that neither this list nor the descriptions are complete.
350 .It Fn puffs_node_lookup "pu" "opc" "pni" "pcn"
351 This function is used to locate nodes, or in other words translate
352 pathname components to file system data structures.
353 The implementation should match the name in
355 against the existing entries in the directory provided by the cookie
357 If found, the cookie for the located node should be set in
360 .Fn puffs_newinfo_setcookie .
361 Additionally, the vnode type and size (latter applicable to regular files only)
363 .Fn puffs_newinfo_setvtype
365 .Fn puffs_newinfo_setsize ,
368 The type of operation is found from
369 .Va pcn-\*[Gt]pcn_nameiop :
370 .Bl -tag -width XNAMEI_LOOKUPX
372 Normal lookup operation.
374 Lookup to create a node.
376 Lookup for node deletion.
378 Lookup for the target of a rename operation (source will be looked
383 The final component from a pathname lookup usually requires special
385 It can be identified by looking at the
386 .Va pcn-\*[Gt]pcn_flags
388 .Dv PUFFSLOOKUP_ISLASTCN .
389 For example, in most cases the lookup operation will want to check if
390 a delete, rename or create operation has enough credentials to perform
393 The return value 0 signals a found node and a nonzero value signals
397 signals "success" for cases where the lookup operation is
401 Failure in these cases can be signalled by returning another appropriate
402 error code, for example
405 Usually a null-terminated string for the next pathname component is
407 .Ar pcn-\*[Gt]pcn_name .
408 In case the file system is using the option
409 .Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF ,
410 the remainder of the complete pathname under lookup is found in
412 .Ar pcn-\*[Gt]pcn_namelen
413 always specifies the length of the next component.
414 If operating with a full path, the file system is allowed to consume
415 more than the next component's length in node lookup.
416 This is done by setting
417 .Ar pcn-\*[Gt]pcn_consume
418 to indicate the amount of
420 characters in addition to
421 .Ar pcn-\*[Gt]pcn_namelen
423 .It Fn puffs_node_create "pu" "opc" "pni" "pcn" "va"
424 .It Fn puffs_node_mkdir "pu" "opc" "pni" "pcn" "va"
425 .It Fn puffs_node_mknod "pu" "opc" "pni" "pcn" "va"
426 A file node is created in the directory denoted by the cookie
428 by any of the above callbacks.
429 The name of the new file can be found from
431 and the attributes are specified by
433 and the cookie for the newly created node should be set in
435 The only difference between these three is that they create a regular
436 file, directory and device special file, respectively.
438 In case of mknod, the device identifier can be found in
439 .Fa va-\*[Gt]va_rdev .
440 .It Fn puffs_node_open "pu" "opc" "mode" "pcr"
441 Open the node denoted by the cookie
445 specifies the flags that
447 was called with, e.g.
451 .It Fn puffs_node_close "pu" "opc" "flags" "pcr"
455 parameter describes the flags that the file was opened with.
456 .It Fn puffs_node_access "pu" "opc" "mode" "pcr"
457 Check if the credentials of
459 have the right to perform the operation specified by
465 can specify read, write or execute by
471 .It Fn puffs_node_getattr "pu" "opc" "va" "pcr"
472 The attributes of the node specified by
474 must be copied to the space pointed by
476 .It Fn puffs_node_setattr "pu" "opc" "va" "pcr"
477 The attributes for the node specified by
479 must be set to those contained in
483 which contain a value different from
485 (typecast to the field's type!) contain a valid value.
486 .It Fn puffs_node_poll "pu" "opc" "events"
487 Poll for events on node
493 are available, the function should set the bitmask to match available
494 events and return immediately.
495 Otherwise, the function should block (yield) until some events in
497 become available and only then set the
501 In case this function returns an error,
505 equivalent) will be delivered to the calling process.
508 The system call interface for
510 contains a timeout parameter.
511 At this level, however, the timeout is not supplied.
512 In case input does not arrive, the file system should periodically
513 unblock and return 0 new events to avoid hanging forever.
514 This will hopefully be better supported by libpuffs in the future.
515 .It Fn puffs_node_mmap "pu" "opc" "flags" "pcr"
516 Called when a regular file is being memory mapped by
519 is currently always 0.
520 .It Fn puffs_node_fsync "pu" "opc" "pcr" "flags" "offlo" "offhi"
521 Sychronize a node's contents onto stable storage.
522 This is necessary only if the file server caches some information
523 before committing it.
526 specifies the minimum level of sychronization required (XXX: they are
532 specify the data offsets requiring to be synced.
533 A high offset of 0 means sync from
535 to the end of the file.
536 .It Fn puffs_node_seek "pu" "opc" "oldoff" "newoff" "pcr"
539 is seekable to the location
543 specifies the offset we are starting the seek from.
544 Most file systems dealing only with regular will choose to not
546 However, it is useful for example in cases where files are
548 .It Fn puffs_node_remove "pu" "opc" "targ" "pcn"
549 .It Fn puffs_node_rmdir "pu" "opc" "targ" "pcn"
552 from the directory indicated by
554 The directory entry name to be removed is provided by
556 The rmdir operation removes only directories, while the remove
557 operation removes all other types except directories.
559 It is paramount to note that the file system may not remove the
560 node data structures at this point, only the directory entry and prevent
561 lookups from finding the node again.
562 This is to retain the
565 The data may be removed only when
566 .Fn puffs_node_reclaim
567 is called for the node, as this assures there are no further users.
568 .It Fn puffs_node_link "pu" "opc" "targ" "pcn"
569 Create a hard link for the node
575 provides the directory entry name for the new link.
576 .It Fn puffs_node_rename "pu" "src_dir" "src" "pcn_src" "targ_dir" "targ" "pcn_targ"
579 with the name specified by
583 The target directory and target name are given by
589 the target node already exists, it is specified by
591 and must be replaced atomically.
597 It is legal to replace a directory node by another directory node with
598 the means of rename if the target directory is empty, otherwise
601 All other types can replace all other types.
602 In case a rename between incompatible types is attempted, the errors
606 should be returned, depending on the target type.
607 .It Fn puffs_node_readdir "pu" "opc" "dent" "readoff" "reslen" "pcr" "eofflag" "cookies" "ncookies"
608 To read directory entries,
609 .Fn puffs_node_readdir
611 It should store directories as
613 in the space pointed to by
615 The amount of space available is given by
617 and before returning it should be set to the amount of space
622 is used to specify the offset to the directory.
623 Its interpretation is up to the file system and it should be set to
624 signal the continuation point when there is no more room for the next
627 It is most performant to return the maximal amount of directory
629 It is easiest to generate directory entries by using
631 which also automatically advances the necessary pointers.
633 In case end-of-directory is reached,
635 should be set to one.
636 Note that even a new call to readdir may start where
638 points to end-of-directory.
640 If the file system supports file handles, the arguments
646 is a vector for offsets corresponding to read offsets.
647 One cookie should be filled out for each directory entry.
648 The value of the cookie should equal the offset of the
650 directory entry, i.e. which offset should be passed to readdir for
651 the first entry read to be the entry following the current one.
653 is the number of slots for cookies in the cookie vector upon entry to
654 the function and must be set to the amount of cookies stored in the
655 vector (i.e. amount of directory entries read) upon exit.
656 There is always enough space in the cookie vector for the maximal number
657 of entries that will fit into the directory entry buffer.
658 For filling out the vector, the helper function
659 .Fn PUFFS_STORE_DCOOKIE cookies ncookies offset
661 This properly checks against
667 must be initialized to zero before the first call to
668 .Fn PUFFS_STORE_DCOOKIE .
669 .It Fn puffs_node_symlink "pu" "opc" "pni" "pcn_src" "va" "link_target"
670 Create a symbolic link into the directory
674 and the initial attributes in
678 contains a null-terminated string for the link target.
679 The created node cookie should be set in
681 .It Fn puffs_node_readlink "pu" "opc" "pcr" "link" "linklen"
682 Read the target of a symbolic link
684 The result is placed in the buffer pointed to by
686 This buffer's length is given in
688 and it must be updated to reflect the real link length.
689 A terminating nul character should not be put into the buffer and
691 be included in the link length.
692 .It Fn puffs_node_read "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
693 Read the contents of a file
695 It will gather the data from
697 in the file and read the number
700 The buffer is guaranteed to have this much space.
701 The amount of data requested by
703 should be read, except in the case of eof-of-file or an error.
706 should be set to indicate the amount of request NOT completed.
707 In the normal case this should be 0.
708 .It Fn puffs_node_write "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag"
714 and extend the file if necessary.
715 The number of octets written is indicated by
717 everything must be written or an error will be generated.
718 The parameter must be set to indicate the amount of data NOT written.
721 is specified, the data should be appended to the end of the file.
722 .It Fn puffs_node_print "pu" "opc"
723 Print information about node.
724 This is used only for kernel-initiated diagnostic purposes.
725 .It Fn puffs_node_reclaim "pu" "opc"
726 The kernel will no longer reference the cookie and resources associated
727 with it may be freed.
730 has a link count of zero, it may be safely removed now.
731 .It Fn puffs_node_abortop "pu" "opc" "pcn"
732 In case the operation following lookup (e.g. mkdir or remove) is not
733 executed for some reason, abortop will be issued.
734 This is useful only for servers which cache state between lookup
735 and a directory operation and is generally left unimplemented.
736 .It Fn puffs_node_inactive "pu" "opc"
739 has lost its last reference in the kernel.
740 However, the cookie must still remain valid until
741 .Fn puffs_node_reclaim
743 .It Fn puffs_setback "pcc" "op"
744 Issue a "setback" operation which will be handled when the request response
745 is returned to the kernel.
746 Currently this can be only called from mmap, open, remove and rmdir.
747 The valid parameters for
750 .Dv PUFFS_SETBACK_INACT_N1
752 .Dv PUFFS_SETBACK_INACT_N2 .
753 These signal that a file system mounted with
754 .Dv PUFFS_KFLAG_IAONDEMAND
755 should call the file system inactive method for the specified node.
756 The node number 1 always means the operation cookie
758 while the node number 2 can be used to specify the second node argument
759 present in some methods, e.g. remove.
760 .It Fn puffs_newinfo_setcookie pni cookie
761 Set cookie for node provided by this method to
763 .It Fn puffs_newinfo_setvtype pni vtype
764 Set the type of the newly located node to
766 This call is valid only for
770 .It Fn puffs_newinfo_setsize pni size
771 Set the size of the newly located node to
773 If left unset, the value defaults to 0.
774 This call is valid only for