1.\" $NetBSD: puffs.3,v 1.39 2008/01/28 18:35:50 pooka Exp $ 2.\" 3.\" Copyright (c) 2006, 2007, 2008 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 January 28, 2008 27.Dt PUFFS 3 28.Os 29.Sh NAME 30.Nm puffs 31.Nd Pass-to-Userspace Framework File System development interface 32.Sh LIBRARY 33.Lb libpuffs 34.Sh SYNOPSIS 35.In puffs.h 36.Ft struct puffs_usermount * 37.Fo puffs_init 38.Fa "struct puffs_ops *pops" "const char *mntfromname" "const char *puffsname" 39.Fa "void *private" "uint32_t flags" 40.Fc 41.Ft int 42.Fo puffs_mount 43.Fa "struct puffs_usermount *pu" "const char *dir" "int mntflags" 44.Fa "void *root_cookie" 45.Fc 46.Ft int 47.Fn puffs_getselectable "struct puffs_usermount *pu" 48.Ft int 49.Fn puffs_setblockingmode "struct puffs_usermount *pu" "int mode" 50.Ft int 51.Fn puffs_getstate "struct puffs_usermount *pu" 52.Ft int 53.Fn puffs_setstacksize "struct puffs_usermount *pu" "size_t stacksize" 54.Ft void 55.Fn puffs_setroot "struct puffs_usermount *pu" "struct puffs_node *node" 56.Ft void 57.Fo puffs_setrootinfo 58.Fa "struct puffs_usermount *pu" "enum vtype vt" "vsize_t vsize" "dev_t rdev" 59.Fc 60.Ft struct puffs_node * 61.Fn puffs_getroot "struct puffs_usermount *pu" 62.Ft void * 63.Fn puffs_getspecific "struct puffs_usermount *pu" 64.Ft void 65.Fn puffs_setmaxreqlen "struct puffs_usermount *pu" "size_t maxreqlen" 66.Ft size_t 67.Fn puffs_getmaxreqlen "struct puffs_usermount *pu" 68.Ft void 69.Fn puffs_setfhsize "struct puffs_usermount *pu" "size_t fhsize" "int flags" 70.Ft void 71.Fn puffs_setncookiehash "struct puffs_usermount *pu" "int nhashes" 72.Ft void 73.Fn puffs_ml_loop_fn "struct puffs_usermount *pu" 74.Ft void 75.Fn puffs_ml_setloopfn "struct puffs_usermount *pu" "puffs_ml_loop_fn lfn" 76.Ft void 77.Fn puffs_ml_settimeout "struct puffs_usermount *pu" "struct timespec *ts" 78.Ft int 79.Fn puffs_daemon "struct puffs_usermount *pu" "int nochdir" "int noclose" 80.Ft int 81.Fn puffs_mainloop "struct puffs_usermount *pu" 82.Ft int 83.Fo puffs_dispatch_create 84.Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pb" 85.Fa "struct puffs_cc **pccp" 86.Fc 87.Ft int 88.Fn puffs_dispatch_exec .Fa "struct puffs_cc *pcc" "struct puffs_framebuf **pbp" 89.Sh DESCRIPTION 90.Em IMPORTANT NOTE! 91This document describes interfaces which are not yet guaranteed to be 92stable. 93In case you update your system sources, please recompile everything 94and fix compilation errors. 95If your sources are out-of-sync, incorrect operation may result. 96The interfaces in this document will most likely be hugely simplified 97in later versions or made transparent to the implementation. 98.Pp 99.Nm 100provides a framework for creating file systems as userspace servers. 101Operations are transported from the kernel virtual file system layer 102to the concrete implementation behind 103.Nm , 104where they are processed and results are sent back to the kernel. 105.Pp 106It is possible to use 107.Nm 108in two different ways. 109Calling 110.Fn puffs_mainloop 111takes execution context away from the caller and automatically handles 112all requests by using the callbacks. 113By using 114.Xr puffs_framebuf 3 115in conjuction with 116.Fn puffs_mainloop , 117it is possible to handle I/O to and from file descriptors. 118This is suited e.g. for distributed file servers. 119.Ss Library operation 120Operations on the library always require a pointer to the opaque context 121identifier, 122.Va struct puffs_usermount . 123It is obtained by calling 124.Fn puffs_init . 125.Pp 126.Nm 127operates using operation callbacks. 128They can be initialized using the macro 129.Fn PUFFSOP_SET pops fsname type opname , 130which will initialize the operation 131.Fn puffs_type_opname 132in 133.Fa pops 134to 135.Fn fsname_type_opname . 136All operations are initialized to a default state with the call 137.Fn PUFFSOP_INIT pops . 138All of the VFS routines are mandatory, but all of the node operations 139with the exception of 140.Fn puffs_node_lookup 141are optional. 142However, leaving operations blank will naturally have an effect on the 143features available from the file system implementation. 144.Bl -tag -width xxxx 145.It Fn puffs_init pops mntfromname puffsname private flags 146Initializes the library context. 147.Ar pops 148specifies the callback operations vector. 149.Ar mntfromname 150is device the file system is mounted from. 151This can be for example a block device such as 152.Pa /dev/wd0a 153or, if the file system is pseudo file system, the 154.Nm 155device name can be given by 156.Dv _PATH_PUFFS . 157This value is used for example in the first column of the output of 158.Xr mount 8 159and 160.Xr df 1 . 161.Ar puffsname 162is the file system type. 163It will always be prepended with the string "puffs|". 164If possible, file server binaries should be named using the format 165"mount_myfsnamehere" and this value should equal "myfsnamehere". 166A file system specific context pointer can optionally be given in 167.Ar private . 168This can be retrieved by 169.Fn puffs_getspecific . 170Flags for 171.Nm 172can be given via 173.Fa pflags . 174Currently the following flags are supported: 175.Bl -tag -width "XPUFFS_KFLAG_LOOKUP_FULLPNBUF" 176.It Dv PUFFS_KFLAG_NOCACHE_NAME 177Do not enter pathname components into the name cache. 178This means that every time the kernel does a lookup for a 179componentname, the file server will be consulted. 180.It Dv PUFFS_KFLAG_NOCACHE_PAGE 181Do not use the page cache. 182This means that all reads and writes to regular file are 183propagated to the file server for handling. 184This option makes a difference only for regular files. 185.It Dv PUFFS_KFLAG_NOCACHE 186An alias for both 187.Dv PUFFS_KFLAG_NOCACHE_NAME 188and 189.Dv PUFFS_KFLAG_NOCACHE_PAGE . 190.It Dv PUFFS_KFLAG_ALLOPS 191This flag requests that all operations are sent to userspace. 192Normally the kernel shortcircuits unimplemented operations. 193This flag is mostly useful for debugging purposes. 194.It Dv PUFFS_KFLAG_WTCACHE 195Set the file system cache behavior as write-through. 196This means that all writes are immediately issued to the file server 197instead of being flushed in file system sync. 198This is useful especially for distributed file systems. 199.It Dv PUFFS_KFLAG_IAONDEMAND 200Issue inactive only on demand. 201If a file server defines the inactive method, call it only if the file 202server has explicitly requested that inactive be called for the 203node in question. 204Once inactive has been called for a node, it will not be called 205again unless the request to call inactive is reissued by the file server. 206See 207.Fn puffs_setback 208in 209.Xr puffs_ops 3 210for more information. 211.It Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF 212This flag affects only the parameter 213.Ar pcn to 214.Fn puffs_node_lookup . 215If this flag is not given, only the next pathname component under 216lookup is found from 217.Ar pcn-\*[Gt]pcn_name . 218If this flag is given, the full path the kernel was 219asked to resolve can be found from there. 220.It Dv PUFFS_FLAG_BUILDPATH 221The framework will build a complete path name, which is supplied 222with each operation and can be found from the 223.Va pn_po.po_full_pcn 224field in a 225.Vt struct puffs_node . 226The option assumes that the framework can map a cookie to a 227.Vt struct puffs_node . 228See 229.Sx Cookies 230for more information on cookie mapping. 231See 232.Xr puffs_path 3 233for more information on library calls involving paths. 234.It Dv PUFFS_FLAG_HASHPATH 235Calculate a hash of the path into the path object field 236.Va po_hash . 237This hash value is used by 238.Fn puffs_path_walkcmp 239to avoid doing a full comparison for every path equal in length to 240the one searched for. 241Especially if the file system uses the abovementioned function, it 242is a good idea to define this flag. 243.It Dv PUFFS_FLAG_OPDUMP 244This option makes the framework dump a textual representation of 245each operation before executing it. 246It is useful for debugging purposes. 247.El 248.El 249.Pp 250The following functions can be used to query or modify the global 251state of the file system. 252Note, that all calls are not available at all times. 253.Bl -tag -width xxxx 254.It Fn puffs_getselectable "pu" 255Returns a handle to do I/O multiplexing with: 256.Xr select 2 , 257.Xr poll 2 , 258and 259.Xr kqueue 2 260are all examples of acceptable operations. 261.It Fn puffs_setblockingmode "pu" "mode" 262Sets the file system upstream access to blocking or non-blocking mode. 263Acceptable values for the argument are 264.Dv PUFFSDEV_BLOCK 265and 266.Dv PUFFSDEV_NONBLOCK . 267.Pp 268This routine can be called only after calling 269.Fn puffs_mount . 270.It Fn puffs_getstate "pu" 271Returns the state of the file system. 272It is maintained by the framework and is mostly useful for the framework 273itself. 274Possible values are 275.Dv PUFFS_STATE_BEFOREMOUNT , 276.Dv PUFFS_STATE_RUNNING , 277.Dv PUFFS_STATE_UNMOUNTING 278and 279.Dv PUFFS_STATE_UNMOUNTED . 280.It Fn puffs_setstacksize "pu" "stacksize" 281Sets the stack size used when running callbacks. 282The default is 283.Dv PUFFS_STACKSIZE_DEFAULT 284bytes of stack space per request. 285The minimum stacksize is architecture-dependent and can be specified 286by using the opaque constant 287.Dv PUFFS_STACKSIZE_MIN . 288.It Fn puffs_setroot "pu" "node" 289Sets the root node of mount 290.Fa pu 291to 292.Fa "node" . 293Setting the root node is currently required only if the path 294framework is used, see 295.Xr puffs_path 3 . 296.It Fn puffs_setrootinfo pu vt vsize rdev 297The default root node is a directory. 298In case the file system wants something different, it can call this 299function and set the type, size and possible device type to whatever 300it wants. 301This routine is independent of 302.Fn puffs_setroot . 303.It Fn puffs_getroot "pu" 304Returns the root node set earlier. 305.It Fn puffs_getspecific "pu" 306Returns the 307.Fa private 308argument of 309.Fn puffs_init . 310.It Fn puffs_setmaxreqlen "pu" "maxreqlen" 311In case the file system desires a maximum buffer length different from 312the default, the amount 313.Fa maxreqlen 314will be requested from the kernel when the file system is mounted. 315.Pp 316It is legal to call this function only between 317.Fn puffs_init 318and 319.Fn puffs_mount . 320.Pp 321.Em NOTE 322This does not currently work. 323.It Fn puffs_getmaxreqlen "pu" 324Returns the maximum request length the kernel will need for a single 325request. 326.Pp 327.Em NOTE 328This does not currently work. 329.It Fn puffs_setfhsize "pu" "fhsize" "flags" 330Sets the desired file handle size. 331This must be called if the file system wishes to support NFS exporting 332file systems of the 333.Fn fh* 334family of function calls. 335.Pp 336In case all nodes in the file system produce the same length file handle, 337it must be supplied as 338.Fa fhsize . 339In this case, the file system may ignore the length parameters in the 340file handle callback routines, as the kernel will always pass the 341correct length buffer. 342However, if the file handle size varies according to file, the argument 343.Fa fhsize 344defines the maximum size of a file handle for the file system. 345In this case the file system must take care of the handle lengths by 346itself in the file handle callbacks, see 347.Xr puffs_ops 3 348for more information. 349Also, the flag 350.Dv PUFFS_FHFLAG_DYNAMIC 351must be provided in the argument 352.Fa flags . 353.Pp 354In case the file system wants to sanity check its file handle lengths 355for the limits of NFS, it can supply 356.Dv PUFFS_FHFLAG_NFSV2 357and 358.Dv PUFFS_FHFLAG_NFSV3 359in the 360.Fa flags 361parameter. 362It is especially important to note that these are not directly the 363limits specified by the protocols, as the kernel uses some bytes from 364the buffer space. 365In case the file handles are too large, mount will return an error. 366.Pp 367It is legal to call this function only between 368.Fn puffs_init 369and 370.Fn puffs_mount . 371.It Fn puffs_setncookiehash "pu" "ncookiehash" 372The parameter 373.Fa ncookiehash 374controls the amount of hash buckets the kernel has for reverse lookups 375from cookie to vnode. 376Technically the default is enough, but a memory/time tradeoff can be 377made by increasing this for file systems which know they will have 378very many active files. 379.Pp 380It is legal to call this function only between 381.Fn puffs_init 382and 383.Fn puffs_mount . 384.El 385.Pp 386After the correct setup for the library has been established and the 387backend has been initialized the file system is made operational by calling 388.Fn puffs_mount . 389After this function returns the file system should start processing requests. 390.Bl -tag -width xxxx 391.It Fn puffs_mount pu dir mntflags root_cookie 392.Ar pu 393is the library context pointer from 394.Fn puffs_init . 395The argument 396.Fa dir 397signifies the mount point and 398.Fa mntflags 399is the flagset given to 400.Xr mount 2 . 401The value 402.Ar root_cookie 403will be used as the cookie for the file system root node. 404.El 405.Ss Using the built-in eventloop 406.Bl -tag -width xxxx 407.It Fn puffs_ml_loop_fn pu 408Loop function signature. 409.It Fn puffs_ml_setloopfn pu lfn 410Set loop function to 411.Ar lfn . 412This function is called once each time the event loop loops. 413It is not a well-defined interval, but it can be made fairly regular 414by setting the loop timeout by 415.Fn puffs_ml_settimeout . 416.It Fn puffs_ml_settimeout pu ts 417Sets the loop timeout to 418.Ar ts 419or disables it if 420.Ar ts 421is 422.Dv NULL . 423This can be used to roughly control how often the loop callback 424.Fn lfn 425is called 426.It Fn puffs_daemon pu nochdir noclose 427Detach from the console like 428.Fn daemon 3 . 429This call synchronizes with 430.Fn puffs_mount 431and the foreground process does not exit before the file system mount 432call has returned from the kernel. 433.It Fn puffs_mainloop pu flags 434Handle all requests automatically until the file system is unmounted. 435It returns 0 if the file system was successfully unmounted or \-1 if it 436was killed in action. 437.Pp 438In case 439.Xr puffs_framebuf 3 440has been initialized, I/O from the relevant descriptors is processed 441automatically by the eventloop. 442.It Fn puffs_dispatch_create pu pb pccp 443.It Fn puffs_dispatch_exec pcc pbp 444In case the use of 445.Fn puffs_mainloop 446is not possible, requests may be dispatched manually. 447However, as this is less efficient than using the mainloop, 448it should never be the first preference. 449.Pp 450Calling 451.Fn puffs_dispatch_create 452creates a dispatch request. 453The argument 454.Ar pb 455should contains a valid request and upon success 456.Ar pccp 457will contain a valid request context. 458This context is passed to 459.Fn puffs_dispatch_exec 460to execute the request. 461If the request yielded before completing, the routine returns 0, 462otherwise 1. 463When the routine completes, 464.Ar pcc 465is made invalid and a pointer to the processed buffer is placed in 466.Ar pbp . 467It is the responsibility of the caller to send the response (if 468necessary) and destroy the buffer. 469.Pp 470See 471.Xr puffs_cc 3 472and 473.Xr puffs_framebuf 3 474for further information. 475.El 476.Ss Cookies 477Every file (regular file, directory, device node, ...) instance is 478attached to the kernel using a cookie. 479A cookie should uniquely map to a file during its lifetime. 480If file instances are kept in memory, a simple strategy is to use 481the virtual address of the structure describing the file. 482The cookie can be recycled when 483.Fn puffs_node_reclaim 484is called for a node. 485.Pp 486For some operations (such as building paths) the framework needs to map 487the cookie to the framework-level structure describing a file, 488.Vt struct puffs_node . 489It is advisable to simply use the 490.Vt struct puffs_node 491address as a cookie and store file system specific data in the private 492portion of 493.Vt struct puffs_node . 494The library assumes this by default. 495If it is not desirable, the file system implementation can call 496.Fn puffs_set_cookiemap 497to provide an alternative cookie-to-node mapping function. 498.Sh SEE ALSO 499.Xr mount 2 , 500.Xr puffs_cc 3 , 501.Xr puffs_cred 3 , 502.Xr puffs_flush 3 , 503.Xr puffs_framebuf 3 , 504.Xr puffs_node 3 , 505.Xr puffs_ops 3 , 506.Xr puffs_path 3 , 507.Xr puffs_suspend 3 , 508.Xr refuse 3 , 509.Xr puffs 4 510.Rs 511.%A Antti Kantee 512.%D March 2007 513.%J Proceedings of AsiaBSDCon 2007 514.%P pp. 29-42 515.%T puffs - Pass-to-Userspace Framework File System 516.Re 517.Rs 518.%A Antti Kantee 519.%D September 2007 520.%I Helsinki University of Technology 521.%R Tech Report TKK-TKO-B157 522.%T Using puffs for Implementing Client-Server Distributed File Systems 523.Re 524.Rs 525.%A Antti Kantee 526.%A Alistair Crooks 527.%D September 2007 528.%J EuroBSDCon 2007 529.%T ReFUSE: Userspace FUSE Reimplementation Using puffs 530.Re 531.Sh HISTORY 532An unsupported experimental version of 533.Nm 534first appeared in 535.Nx 4.0 . 536.Sh AUTHORS 537.An Antti Kantee Aq pooka@iki.fi 538.Sh BUGS 539Under construction. 540