| 1 | /*	$NetBSD: puffs.h,v 1.127 2015/11/12 17:51:05 christos Exp $	*/ | 
| 2 |  | 
| 3 | /* | 
| 4 |  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved. | 
| 5 |  * | 
| 6 |  * Development of this software was supported by the | 
| 7 |  * Google Summer of Code program and the Ulla Tuominen Foundation. | 
| 8 |  * The Google SoC project was mentored by Bill Studenmund. | 
| 9 |  * | 
| 10 |  * Redistribution and use in source and binary forms, with or without | 
| 11 |  * modification, are permitted provided that the following conditions | 
| 12 |  * are met: | 
| 13 |  * 1. Redistributions of source code must retain the above copyright | 
| 14 |  *    notice, this list of conditions and the following disclaimer. | 
| 15 |  * 2. Redistributions in binary form must reproduce the above copyright | 
| 16 |  *    notice, this list of conditions and the following disclaimer in the | 
| 17 |  *    documentation and/or other materials provided with the distribution. | 
| 18 |  * | 
| 19 |  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | 
| 20 |  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
| 21 |  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
| 22 |  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 
| 23 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
| 24 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
| 25 |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
| 26 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
| 27 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
| 28 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
| 29 |  * SUCH DAMAGE. | 
| 30 |  */ | 
| 31 |  | 
| 32 | #ifndef _PUFFS_H_ | 
| 33 | #define _PUFFS_H_ | 
| 34 |  | 
| 35 | #include <sys/param.h> | 
| 36 | #include <sys/types.h> | 
| 37 | #include <sys/mount.h> | 
| 38 | #include <sys/namei.h> | 
| 39 | #include <sys/stat.h> | 
| 40 | #include <sys/statvfs.h> | 
| 41 | #include <sys/time.h> | 
| 42 | #include <sys/vnode.h> | 
| 43 |  | 
| 44 | #include <fs/puffs/puffs_msgif.h> | 
| 45 |  | 
| 46 | #include <mntopts.h> | 
| 47 | #include <stdbool.h> | 
| 48 | #include <string.h> | 
| 49 |  | 
| 50 | /* forwards */ | 
| 51 | struct puffs_cc; | 
| 52 |  | 
| 53 | struct puffs_getreq; | 
| 54 | struct puffs_cred; | 
| 55 | struct puffs_newinfo; | 
| 56 |  | 
| 57 | /* paths */ | 
| 58 | struct puffs_pathobj { | 
| 59 | 	void 		*po_path; | 
| 60 | 	size_t		po_len; | 
| 61 | 	uint32_t	po_hash; | 
| 62 | }; | 
| 63 |  | 
| 64 | /* for prefix rename */ | 
| 65 | struct puffs_pathinfo { | 
| 66 | 	struct puffs_pathobj *pi_old; | 
| 67 | 	struct puffs_pathobj *pi_new; | 
| 68 | }; | 
| 69 |  | 
| 70 | /* describes one segment cached in the kernel */ | 
| 71 | struct puffs_kcache { | 
| 72 | 	off_t	pkc_start; | 
| 73 | 	off_t	pkc_end; | 
| 74 |  | 
| 75 | 	LIST_ENTRY(puffs_kcache) pkc_entries; | 
| 76 | }; | 
| 77 |  | 
| 78 | /* XXX: might disappear from here into a private header */ | 
| 79 | struct puffs_node { | 
| 80 | 	off_t			pn_size; | 
| 81 | 	int			pn_flags; | 
| 82 | 	int			pn_nlookup; | 
| 83 | 	struct vattr		pn_va; | 
| 84 |  | 
| 85 | 	void			*pn_data;	/* private data		*/ | 
| 86 |  | 
| 87 | 	struct puffs_pathobj	pn_po;		/* PUFFS_FLAG_BUILDPATH */ | 
| 88 |  | 
| 89 | 	struct puffs_usermount 	*pn_mnt; | 
| 90 | 	LIST_ENTRY(puffs_node)	pn_entries; | 
| 91 |  | 
| 92 | 	LIST_HEAD(,puffs_kcache)pn_cacheinfo;	/* PUFFS_KFLAG_CACHE	*/ | 
| 93 | }; | 
| 94 | #define PUFFS_NODE_REMOVED	0x01		/* not on entry list	*/ | 
| 95 |  | 
| 96 |  | 
| 97 | struct puffs_usermount; | 
| 98 |  | 
| 99 | /* | 
| 100 |  * megaXXX: these are values from inside _KERNEL | 
| 101 |  * need to work on the translation for ALL the necessary values. | 
| 102 |  */ | 
| 103 | #define PUFFS_VNOVAL (-1) | 
| 104 |  | 
| 105 | #define PUFFS_IO_APPEND 0x020 | 
| 106 | #define PUFFS_IO_NDELAY	0x100 | 
| 107 |  | 
| 108 | #define PUFFS_VEXEC	01 | 
| 109 | #define PUFFS_VWRITE	02 | 
| 110 | #define PUFFS_VREAD	04 | 
| 111 |  | 
| 112 | #define PUFFS_FSYNC_DATAONLY 0x0002 | 
| 113 | #define PUFFS_FSYNC_CACHE    0x0100 | 
| 114 |  | 
| 115 | /* | 
| 116 |  * xflags for setattr_ttl and write2 | 
| 117 |  */ | 
| 118 | #define PUFFS_SETATTR_FAF    0x1 | 
| 119 | #define PUFFS_WRITE_FAF      0x1 | 
| 120 |  | 
| 121 | #define PUFFS_EXTATTR_LIST_LENPREFIX 1 | 
| 122 | /* | 
| 123 |  * Magic constants | 
| 124 |  */ | 
| 125 | #define PUFFS_CC_STACKSHIFT_DEFAULT 18 | 
| 126 |  | 
| 127 | struct puffs_cn { | 
| 128 | 	struct puffs_kcn	*pcn_pkcnp;	/* kernel input */ | 
| 129 | 	struct puffs_cred	*pcn_cred;	/* cred used for lookup */ | 
| 130 |  | 
| 131 | 	struct puffs_pathobj	pcn_po_full;	/* PUFFS_FLAG_BUILDPATH */ | 
| 132 | }; | 
| 133 | #define pcn_nameiop	pcn_pkcnp->pkcn_nameiop | 
| 134 | #define pcn_flags	pcn_pkcnp->pkcn_flags | 
| 135 | #define pcn_name	pcn_pkcnp->pkcn_name | 
| 136 | #define pcn_namelen	pcn_pkcnp->pkcn_namelen | 
| 137 | #define pcn_consume	pcn_pkcnp->pkcn_consume | 
| 138 |  | 
| 139 | /* | 
| 140 |  * Puffs options to mount | 
| 141 |  */ | 
| 142 | /* kernel */ | 
| 143 | #define	PUFFSMOPT_NAMECACHE	{ "namecache", 1, PUFFS_KFLAG_NOCACHE_NAME, 1 } | 
| 144 | #define	PUFFSMOPT_PAGECACHE	{ "pagecache", 1, PUFFS_KFLAG_NOCACHE_PAGE, 1 } | 
| 145 | #define	PUFFSMOPT_ATTRCACHE	{ "attrcache", 1, PUFFS_KFLAG_NOCACHE_ATTR, 1 } | 
| 146 | #define	PUFFSMOPT_CACHE		{ "cache", 1, PUFFS_KFLAG_NOCACHE, 1 } | 
| 147 | #define PUFFSMOPT_ALLOPS	{ "allops", 0, PUFFS_KFLAG_ALLOPS, 1 } | 
| 148 |  | 
| 149 | /* libpuffs */ | 
| 150 | #define PUFFSMOPT_DUMP		{ "dump", 0, PUFFS_FLAG_OPDUMP, 1 } | 
| 151 |  | 
| 152 | #define PUFFSMOPT_STD							\ | 
| 153 | 	PUFFSMOPT_NAMECACHE,						\ | 
| 154 | 	PUFFSMOPT_PAGECACHE,						\ | 
| 155 | 	PUFFSMOPT_ATTRCACHE,						\ | 
| 156 | 	PUFFSMOPT_CACHE,						\ | 
| 157 | 	PUFFSMOPT_ALLOPS,						\ | 
| 158 | 	PUFFSMOPT_DUMP | 
| 159 |  | 
| 160 | extern const struct mntopt puffsmopts[]; /* puffs.c */ | 
| 161 |  | 
| 162 | /* callbacks for operations */ | 
| 163 | struct puffs_ops { | 
| 164 | 	int (*puffs_fs_unmount)(struct puffs_usermount *, int); | 
| 165 | 	int (*puffs_fs_statvfs)(struct puffs_usermount *, struct statvfs *); | 
| 166 | 	int (*puffs_fs_sync)(struct puffs_usermount *, int, | 
| 167 | 	    const struct puffs_cred *); | 
| 168 | 	int (*puffs_fs_fhtonode)(struct puffs_usermount *, void *, size_t, | 
| 169 | 	    struct puffs_newinfo *); | 
| 170 | 	int (*puffs_fs_nodetofh)(struct puffs_usermount *, puffs_cookie_t, | 
| 171 | 	    void *, size_t *); | 
| 172 | 	int (*puffs_fs_extattrctl)(struct puffs_usermount *, int, | 
| 173 | 	    puffs_cookie_t, int, int, const char *); | 
| 174 |  | 
| 175 | 	int (*puffs_node_lookup)(struct puffs_usermount *, | 
| 176 | 	    puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *); | 
| 177 | 	int (*puffs_node_create)(struct puffs_usermount *, | 
| 178 | 	    puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, | 
| 179 | 	    const struct vattr *); | 
| 180 | 	int (*puffs_node_mknod)(struct puffs_usermount *, | 
| 181 | 	    puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, | 
| 182 | 	    const struct vattr *); | 
| 183 | 	int (*puffs_node_open)(struct puffs_usermount *, | 
| 184 | 	    puffs_cookie_t, int, const struct puffs_cred *); | 
| 185 | 	int (*puffs_node_close)(struct puffs_usermount *, | 
| 186 | 	    puffs_cookie_t, int, const struct puffs_cred *); | 
| 187 | 	int (*puffs_node_access)(struct puffs_usermount *, | 
| 188 | 	    puffs_cookie_t, int, const struct puffs_cred *); | 
| 189 | 	int (*puffs_node_getattr)(struct puffs_usermount *, | 
| 190 | 	    puffs_cookie_t, struct vattr *, const struct puffs_cred *); | 
| 191 | 	int (*puffs_node_setattr)(struct puffs_usermount *, | 
| 192 | 	    puffs_cookie_t, const struct vattr *, const struct puffs_cred *); | 
| 193 | 	int (*puffs_node_poll)(struct puffs_usermount *, puffs_cookie_t, int *); | 
| 194 | 	int (*puffs_node_mmap)(struct puffs_usermount *, | 
| 195 | 	    puffs_cookie_t, vm_prot_t, const struct puffs_cred *); | 
| 196 | 	int (*puffs_node_fsync)(struct puffs_usermount *, | 
| 197 | 	    puffs_cookie_t, const struct puffs_cred *, int, off_t, off_t); | 
| 198 | 	int (*puffs_node_seek)(struct puffs_usermount *, | 
| 199 | 	    puffs_cookie_t, off_t, off_t, const struct puffs_cred *); | 
| 200 | 	int (*puffs_node_remove)(struct puffs_usermount *, | 
| 201 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); | 
| 202 | 	int (*puffs_node_link)(struct puffs_usermount *, | 
| 203 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); | 
| 204 | 	int (*puffs_node_rename)(struct puffs_usermount *, | 
| 205 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *, | 
| 206 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); | 
| 207 | 	int (*puffs_node_mkdir)(struct puffs_usermount *, | 
| 208 | 	    puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, | 
| 209 | 	    const struct vattr *); | 
| 210 | 	int (*puffs_node_rmdir)(struct puffs_usermount *, | 
| 211 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); | 
| 212 | 	int (*puffs_node_symlink)(struct puffs_usermount *, | 
| 213 | 	    puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, | 
| 214 | 	    const struct vattr *, | 
| 215 | 	    const char *); | 
| 216 | 	int (*puffs_node_readdir)(struct puffs_usermount *, | 
| 217 | 	    puffs_cookie_t, struct dirent *, off_t *, size_t *, | 
| 218 | 	    const struct puffs_cred *, int *, off_t *, size_t *); | 
| 219 | 	int (*puffs_node_readlink)(struct puffs_usermount *, | 
| 220 | 	    puffs_cookie_t, const struct puffs_cred *, char *, size_t *); | 
| 221 | 	int (*puffs_node_reclaim)(struct puffs_usermount *, puffs_cookie_t); | 
| 222 | 	int (*puffs_node_inactive)(struct puffs_usermount *, puffs_cookie_t); | 
| 223 | 	int (*puffs_node_print)(struct puffs_usermount *, puffs_cookie_t); | 
| 224 | 	int (*puffs_node_pathconf)(struct puffs_usermount *, | 
| 225 | 	    puffs_cookie_t, int, register_t *); | 
| 226 | 	int (*puffs_node_advlock)(struct puffs_usermount *, | 
| 227 | 	    puffs_cookie_t, void *, int, struct flock *, int); | 
| 228 | 	int (*puffs_node_read)(struct puffs_usermount *, puffs_cookie_t, | 
| 229 | 	    uint8_t *, off_t, size_t *, const struct puffs_cred *, int); | 
| 230 | 	int (*puffs_node_write)(struct puffs_usermount *, puffs_cookie_t, | 
| 231 | 	    uint8_t *, off_t, size_t *, const struct puffs_cred *, int); | 
| 232 | 	int (*puffs_node_abortop)(struct puffs_usermount *, puffs_cookie_t, | 
| 233 | 	    const struct puffs_cn *); | 
| 234 | 	int (*puffs_node_getextattr)(struct puffs_usermount *, puffs_cookie_t, | 
| 235 | 	    int, const char *, size_t *, uint8_t *, size_t *, | 
| 236 | 	    const struct puffs_cred *); | 
| 237 | 	int (*puffs_node_setextattr)(struct puffs_usermount *, puffs_cookie_t, | 
| 238 | 	    int, const char *, uint8_t *, size_t *, const struct puffs_cred *); | 
| 239 | 	int (*puffs_node_listextattr)(struct puffs_usermount *, puffs_cookie_t, | 
| 240 | 	    int, size_t *, uint8_t *, size_t *, int, const struct puffs_cred *); | 
| 241 | 	int (*puffs_node_deleteextattr)(struct puffs_usermount *, | 
| 242 | 	    puffs_cookie_t, int, const char *, const struct puffs_cred *); | 
| 243 | 	int (*puffs_node_getattr_ttl)(struct puffs_usermount *, | 
| 244 | 	    puffs_cookie_t, struct vattr *, const struct puffs_cred *, | 
| 245 | 	    struct timespec *); | 
| 246 | 	int (*puffs_node_setattr_ttl)(struct puffs_usermount *, | 
| 247 | 	    puffs_cookie_t, struct vattr *, const struct puffs_cred *, | 
| 248 | 	    struct timespec *, int); | 
| 249 | 	int (*puffs_node_write2)(struct puffs_usermount *, puffs_cookie_t, | 
| 250 | 	    uint8_t *, off_t, size_t *, const struct puffs_cred *, int, int); | 
| 251 | 	int (*puffs_node_reclaim2)(struct puffs_usermount *, | 
| 252 | 	    puffs_cookie_t, int); | 
| 253 | 	int (*puffs_node_open2)(struct puffs_usermount *, | 
| 254 | 	    puffs_cookie_t, int, const struct puffs_cred *, int *); | 
| 255 | 	int (*puffs_node_fallocate)(struct puffs_usermount *, | 
| 256 | 	    puffs_cookie_t, off_t, off_t); | 
| 257 | 	int (*puffs_node_fdiscard)(struct puffs_usermount *, | 
| 258 | 	    puffs_cookie_t, off_t, off_t); | 
| 259 |  | 
| 260 | 	void *puffs_ops_spare[26]; | 
| 261 | }; | 
| 262 |  | 
| 263 | typedef	int (*pu_pathbuild_fn)(struct puffs_usermount *, | 
| 264 | 			       const struct puffs_pathobj *, | 
| 265 | 			       const struct puffs_pathobj *, size_t, | 
| 266 | 			       struct puffs_pathobj *); | 
| 267 | typedef int (*pu_pathtransform_fn)(struct puffs_usermount *, | 
| 268 | 				   const struct puffs_pathobj *, | 
| 269 | 				   const struct puffs_cn *, | 
| 270 | 				   struct puffs_pathobj *); | 
| 271 | typedef int (*pu_pathcmp_fn)(struct puffs_usermount *, struct puffs_pathobj *, | 
| 272 | 			  struct puffs_pathobj *, size_t, int); | 
| 273 | typedef void (*pu_pathfree_fn)(struct puffs_usermount *, | 
| 274 | 			       struct puffs_pathobj *); | 
| 275 | typedef int (*pu_namemod_fn)(struct puffs_usermount *, | 
| 276 | 			     struct puffs_pathobj *, struct puffs_cn *); | 
| 277 |  | 
| 278 | typedef void (*pu_errnotify_fn)(struct puffs_usermount *, | 
| 279 | 				uint8_t, int, const char *, puffs_cookie_t); | 
| 280 |  | 
| 281 | typedef void (*pu_prepost_fn)(struct puffs_usermount *); | 
| 282 |  | 
| 283 | typedef struct puffs_node *(*pu_cmap_fn)(struct puffs_usermount *, | 
| 284 | 					 puffs_cookie_t); | 
| 285 |  | 
| 286 | enum { | 
| 287 | 	PUFFS_STATE_BEFOREMOUNT,	PUFFS_STATE_RUNNING, | 
| 288 | 	PUFFS_STATE_UNMOUNTING,		PUFFS_STATE_UNMOUNTED | 
| 289 | }; | 
| 290 |  | 
| 291 | #define PUFFS_FLAG_BUILDPATH	0x80000000	/* node paths in pnode */ | 
| 292 | #define PUFFS_FLAG_OPDUMP	0x40000000	/* dump all operations */ | 
| 293 | #define PUFFS_FLAG_HASHPATH	0x20000000	/* speedup: hash paths */ | 
| 294 | #define PUFFS_FLAG_PNCOOKIE	0x10000000	/* cookies are pnodes */ | 
| 295 | #define PUFFS_FLAG_MASK		0xf0000000 | 
| 296 |  | 
| 297 | #define PUFFS_FLAG_KERN(a)	((a) & PUFFS_KFLAG_MASK) | 
| 298 | #define PUFFS_FLAG_LIB(a)	((a) & PUFFS_FLAG_MASK) | 
| 299 |  | 
| 300 | /* blocking mode argument */ | 
| 301 | #define PUFFSDEV_BLOCK 0 | 
| 302 | #define PUFFSDEV_NONBLOCK 1 | 
| 303 |  | 
| 304 | #define PUFFS_STACKSIZE_DEFAULT (1<<PUFFS_CC_STACKSHIFT_DEFAULT) | 
| 305 | #define PUFFS_STACKSIZE_MIN ((size_t)-1) | 
| 306 |  | 
| 307 | #define		DENT_DOT	0 | 
| 308 | #define		DENT_DOTDOT	1 | 
| 309 | #define		DENT_ADJ(a)	((a)-2)	/* nth request means dir's n-2th */ | 
| 310 |  | 
| 311 |  | 
| 312 | /* | 
| 313 |  * protos | 
| 314 |  */ | 
| 315 |  | 
| 316 | #define PUFFSOP_PROTOS(fsname)						\ | 
| 317 | 	int fsname##_fs_unmount(struct puffs_usermount *, int);		\ | 
| 318 | 	int fsname##_fs_statvfs(struct puffs_usermount *,		\ | 
| 319 | 	    struct statvfs *);						\ | 
| 320 | 	int fsname##_fs_sync(struct puffs_usermount *, int,		\ | 
| 321 | 	    const struct puffs_cred *cred);				\ | 
| 322 | 	int fsname##_fs_fhtonode(struct puffs_usermount *, void *,	\ | 
| 323 | 	    size_t, struct puffs_newinfo *);				\ | 
| 324 | 	int fsname##_fs_nodetofh(struct puffs_usermount *,		\ | 
| 325 | 	    puffs_cookie_t, void *, size_t *);				\ | 
| 326 | 	int fsname##_fs_extattrctl(struct puffs_usermount *, int,	\ | 
| 327 | 	    puffs_cookie_t, int, int, const char *);			\ | 
| 328 | 									\ | 
| 329 | 	int fsname##_node_lookup(struct puffs_usermount *,		\ | 
| 330 | 	    puffs_cookie_t, struct puffs_newinfo *,			\ | 
| 331 | 	    const struct puffs_cn *);					\ | 
| 332 | 	int fsname##_node_create(struct puffs_usermount *,		\ | 
| 333 | 	    puffs_cookie_t, struct puffs_newinfo *,			\ | 
| 334 | 	    const struct puffs_cn *, const struct vattr *);		\ | 
| 335 | 	int fsname##_node_mknod(struct puffs_usermount *,		\ | 
| 336 | 	    puffs_cookie_t, struct puffs_newinfo *,			\ | 
| 337 | 	    const struct puffs_cn *, const struct vattr *);		\ | 
| 338 | 	int fsname##_node_open(struct puffs_usermount *,		\ | 
| 339 | 	    puffs_cookie_t, int, const struct puffs_cred *);		\ | 
| 340 | 	int fsname##_node_close(struct puffs_usermount *,		\ | 
| 341 | 	    puffs_cookie_t, int, const struct puffs_cred *);		\ | 
| 342 | 	int fsname##_node_access(struct puffs_usermount *,		\ | 
| 343 | 	    puffs_cookie_t, int, const struct puffs_cred *);		\ | 
| 344 | 	int fsname##_node_getattr(struct puffs_usermount *,		\ | 
| 345 | 	    puffs_cookie_t, struct vattr *, const struct puffs_cred *);	\ | 
| 346 | 	int fsname##_node_setattr(struct puffs_usermount *,		\ | 
| 347 | 	    puffs_cookie_t, const struct vattr *,			\ | 
| 348 | 	    const struct puffs_cred *);					\ | 
| 349 | 	int fsname##_node_poll(struct puffs_usermount *,		\ | 
| 350 | 	    puffs_cookie_t, int *);					\ | 
| 351 | 	int fsname##_node_mmap(struct puffs_usermount *,		\ | 
| 352 | 	    puffs_cookie_t, vm_prot_t, const struct puffs_cred *);	\ | 
| 353 | 	int fsname##_node_fsync(struct puffs_usermount *,		\ | 
| 354 | 	    puffs_cookie_t, const struct puffs_cred *, int,		\ | 
| 355 | 	    off_t, off_t);						\ | 
| 356 | 	int fsname##_node_seek(struct puffs_usermount *,		\ | 
| 357 | 	    puffs_cookie_t, off_t, off_t, const struct puffs_cred *);	\ | 
| 358 | 	int fsname##_node_remove(struct puffs_usermount *,		\ | 
| 359 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *);	\ | 
| 360 | 	int fsname##_node_link(struct puffs_usermount *,		\ | 
| 361 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *);	\ | 
| 362 | 	int fsname##_node_rename(struct puffs_usermount *,		\ | 
| 363 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *,	\ | 
| 364 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *);	\ | 
| 365 | 	int fsname##_node_mkdir(struct puffs_usermount *,		\ | 
| 366 | 	    puffs_cookie_t, struct puffs_newinfo *,			\ | 
| 367 | 	    const struct puffs_cn *, const struct vattr *);		\ | 
| 368 | 	int fsname##_node_rmdir(struct puffs_usermount *,		\ | 
| 369 | 	    puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *);	\ | 
| 370 | 	int fsname##_node_symlink(struct puffs_usermount *,		\ | 
| 371 | 	    puffs_cookie_t, struct puffs_newinfo *,			\ | 
| 372 | 	    const struct puffs_cn *, const struct vattr *,		\ | 
| 373 | 	    const char *);						\ | 
| 374 | 	int fsname##_node_readdir(struct puffs_usermount *,		\ | 
| 375 | 	    puffs_cookie_t, struct dirent *, off_t *, size_t *,		\ | 
| 376 | 	    const struct puffs_cred *, int *, off_t *, size_t *);	\ | 
| 377 | 	int fsname##_node_readlink(struct puffs_usermount *,		\ | 
| 378 | 	    puffs_cookie_t, const struct puffs_cred *, char *,		\ | 
| 379 | 	    size_t *);							\ | 
| 380 | 	int fsname##_node_reclaim(struct puffs_usermount *,		\ | 
| 381 | 	    puffs_cookie_t);						\ | 
| 382 | 	int fsname##_node_inactive(struct puffs_usermount *,		\ | 
| 383 | 	    puffs_cookie_t);						\ | 
| 384 | 	int fsname##_node_print(struct puffs_usermount *,		\ | 
| 385 | 	    puffs_cookie_t);						\ | 
| 386 | 	int fsname##_node_pathconf(struct puffs_usermount *,		\ | 
| 387 | 	    puffs_cookie_t, int, register_t *);				\ | 
| 388 | 	int fsname##_node_advlock(struct puffs_usermount *,		\ | 
| 389 | 	    puffs_cookie_t, void *, int, struct flock *, int);		\ | 
| 390 | 	int fsname##_node_read(struct puffs_usermount *, puffs_cookie_t,\ | 
| 391 | 	    uint8_t *, off_t, size_t *, const struct puffs_cred *, int);\ | 
| 392 | 	int fsname##_node_write(struct puffs_usermount *,		\ | 
| 393 | 	    puffs_cookie_t, uint8_t *, off_t, size_t *,			\ | 
| 394 | 	    const struct puffs_cred *, int);				\ | 
| 395 | 	int fsname##_node_abortop(struct puffs_usermount *,		\ | 
| 396 | 	    puffs_cookie_t, const struct puffs_cn *);			\ | 
| 397 | 	int fsname##_node_getextattr(struct puffs_usermount *,		\ | 
| 398 | 	    puffs_cookie_t, int, const char *, size_t *, uint8_t *,	\ | 
| 399 | 	    size_t *, const struct puffs_cred *);			\ | 
| 400 | 	int fsname##_node_setextattr(struct puffs_usermount *,		\ | 
| 401 | 	    puffs_cookie_t, int, const char *, uint8_t *, size_t *,	\ | 
| 402 | 	    const struct puffs_cred *);					\ | 
| 403 | 	int fsname##_node_listextattr(struct puffs_usermount *,		\ | 
| 404 | 	    puffs_cookie_t, int, size_t *, uint8_t *, size_t *,		\ | 
| 405 | 	    int, const struct puffs_cred *);				\ | 
| 406 | 	int fsname##_node_deleteextattr(struct puffs_usermount *,	\ | 
| 407 | 	    puffs_cookie_t, int, const char *,				\ | 
| 408 | 	    const struct puffs_cred *);					\ | 
| 409 | 	int fsname##_node_getattr_ttl(struct puffs_usermount *,		\ | 
| 410 | 	    puffs_cookie_t, struct vattr *, const struct puffs_cred *,	\ | 
| 411 | 	    struct timespec *);						\ | 
| 412 | 	int fsname##_node_setattr_ttl(struct puffs_usermount *,		\ | 
| 413 | 	    puffs_cookie_t, struct vattr *, const struct puffs_cred *,	\ | 
| 414 | 	    struct timespec *, int);					\ | 
| 415 | 	int fsname##_node_write2(struct puffs_usermount *,		\ | 
| 416 | 	    puffs_cookie_t, uint8_t *, off_t, size_t *,			\ | 
| 417 | 	    const struct puffs_cred *, int, int);			\ | 
| 418 | 	int fsname##_node_reclaim2(struct puffs_usermount *,		\ | 
| 419 | 	    puffs_cookie_t, int);					\ | 
| 420 | 	int fsname##_node_open2(struct puffs_usermount *,		\ | 
| 421 | 	    puffs_cookie_t, int, const struct puffs_cred *, int *);	\ | 
| 422 | 	int fsname##_node_fallocate(struct puffs_usermount *,		\ | 
| 423 | 	    puffs_cookie_t, off_t, off_t);				\ | 
| 424 | 	int fsname##_node_fdiscard(struct puffs_usermount *,		\ | 
| 425 | 	    puffs_cookie_t, off_t, off_t); | 
| 426 |  | 
| 427 |  | 
| 428 | #define PUFFSOP_INIT(ops)						\ | 
| 429 |     ops = malloc(sizeof(struct puffs_ops));				\ | 
| 430 |     memset(ops, 0, sizeof(struct puffs_ops)) | 
| 431 | #define PUFFSOP_SET(ops, fsname, fsornode, opname)			\ | 
| 432 |     (ops)->puffs_##fsornode##_##opname = fsname##_##fsornode##_##opname | 
| 433 | #define PUFFSOP_SETFSNOP(ops, opname)					\ | 
| 434 |     (ops)->puffs_fs_##opname = puffs_fsnop_##opname | 
| 435 |  | 
| 436 | PUFFSOP_PROTOS(puffs_null)	/* XXX */ | 
| 437 |  | 
| 438 | #define PNPATH(pnode)	((pnode)->pn_po.po_path) | 
| 439 | #define PNPLEN(pnode)	((pnode)->pn_po.po_len) | 
| 440 | #define PCNPATH(pcnode)	((pcnode)->pcn_po_full.po_path) | 
| 441 | #define PCNPLEN(pcnode)	((pcnode)->pcn_po_full.po_len) | 
| 442 | #define PCNISDOTDOT(pcnode) \ | 
| 443 | 	((pcnode)->pcn_namelen == 2 && strcmp((pcnode)->pcn_name, "..") == 0) | 
| 444 |  | 
| 445 | #define PUFFS_STORE_DCOOKIE(cp, ncp, off)				\ | 
| 446 | if (cp)	{								\ | 
| 447 | 	*((cp)++) = off;						\ | 
| 448 | 	(*(ncp))++;							\ | 
| 449 | } | 
| 450 |  | 
| 451 | /* mainloop */ | 
| 452 | typedef void (*puffs_ml_loop_fn)(struct puffs_usermount *); | 
| 453 |  | 
| 454 | /* framebuf stuff */ | 
| 455 | struct puffs_framebuf; | 
| 456 | typedef int (*puffs_framev_readframe_fn)(struct puffs_usermount *, | 
| 457 | 					   struct puffs_framebuf *, | 
| 458 | 					   int, int *); | 
| 459 | typedef	int (*puffs_framev_writeframe_fn)(struct puffs_usermount *, | 
| 460 | 					    struct puffs_framebuf *, | 
| 461 | 					    int, int *); | 
| 462 | typedef int (*puffs_framev_cmpframe_fn)(struct puffs_usermount *, | 
| 463 | 					 struct puffs_framebuf *, | 
| 464 | 					 struct puffs_framebuf *, | 
| 465 | 					 int *); | 
| 466 | typedef void (*puffs_framev_fdnotify_fn)(struct puffs_usermount *, int, int); | 
| 467 | typedef void (*puffs_framev_gotframe_fn)(struct puffs_usermount *, | 
| 468 | 					struct puffs_framebuf *); | 
| 469 | typedef void (*puffs_framev_cb)(struct puffs_usermount *, | 
| 470 | 				struct puffs_framebuf *, | 
| 471 | 				void *, int); | 
| 472 | #define PUFFS_FBIO_READ		0x01 | 
| 473 | #define PUFFS_FBIO_WRITE	0x02 | 
| 474 | #define PUFFS_FBIO_ERROR	0x04 | 
| 475 |  | 
| 476 | #define PUFFS_FBQUEUE_URGENT	0x01 | 
| 477 |  | 
| 478 |  | 
| 479 | __BEGIN_DECLS | 
| 480 |  | 
| 481 | #define PUFFS_DEFER ((void *)-1) | 
| 482 | struct puffs_usermount *puffs_init(struct puffs_ops *, const char *, | 
| 483 | 				    const char *, void *, uint32_t); | 
| 484 | int		puffs_mount(struct puffs_usermount *, const char *, int, void*); | 
| 485 | int		puffs_exit(struct puffs_usermount *, int); | 
| 486 | void		puffs_cancel(struct puffs_usermount *, int); | 
| 487 | int		puffs_mainloop(struct puffs_usermount *); | 
| 488 | int		puffs_daemon(struct puffs_usermount *, int, int); | 
| 489 |  | 
| 490 | int		puffs_unmountonsignal(int, bool); | 
| 491 |  | 
| 492 |  | 
| 493 | int	puffs_getselectable(struct puffs_usermount *); | 
| 494 | int	puffs_setblockingmode(struct puffs_usermount *, int); | 
| 495 | int	puffs_getstate(struct puffs_usermount *); | 
| 496 | void	puffs_setstacksize(struct puffs_usermount *, size_t); | 
| 497 |  | 
| 498 | void	puffs_ml_setloopfn(struct puffs_usermount *, puffs_ml_loop_fn); | 
| 499 | void	puffs_ml_settimeout(struct puffs_usermount *, struct timespec *); | 
| 500 |  | 
| 501 | void			puffs_setroot(struct puffs_usermount *, | 
| 502 | 				      struct puffs_node *); | 
| 503 | struct puffs_node 	*puffs_getroot(struct puffs_usermount *); | 
| 504 | void			puffs_setrootinfo(struct puffs_usermount *, | 
| 505 | 					  enum vtype, vsize_t, dev_t);  | 
| 506 |  | 
| 507 | void			*puffs_getspecific(struct puffs_usermount *); | 
| 508 | void			puffs_setspecific(struct puffs_usermount *, void *); | 
| 509 | void			puffs_setmaxreqlen(struct puffs_usermount *, size_t); | 
| 510 | size_t			puffs_getmaxreqlen(struct puffs_usermount *); | 
| 511 | void			puffs_setfhsize(struct puffs_usermount *, size_t, int); | 
| 512 | void			puffs_setmntinfo(struct puffs_usermount *, | 
| 513 | 					 const char *, const char *); | 
| 514 |  | 
| 515 | void			puffs_setncookiehash(struct puffs_usermount *, int); | 
| 516 |  | 
| 517 | struct puffs_pathobj	*puffs_getrootpathobj(struct puffs_usermount *); | 
| 518 |  | 
| 519 | void			puffs_setback(struct puffs_cc *, int); | 
| 520 |  | 
| 521 | struct puffs_node	*puffs_pn_new(struct puffs_usermount *, void *); | 
| 522 | void			puffs_pn_remove(struct puffs_node *); | 
| 523 | void			puffs_pn_put(struct puffs_node *); | 
| 524 | struct vattr		*puffs_pn_getvap(struct puffs_node *); | 
| 525 | void *			puffs_pn_getpriv(struct puffs_node *); | 
| 526 | void			puffs_pn_setpriv(struct puffs_node *, void *); | 
| 527 | struct puffs_pathobj	*puffs_pn_getpo(struct puffs_node *); | 
| 528 | struct puffs_usermount	*puffs_pn_getmnt(struct puffs_node *); | 
| 529 | struct timespec		*puffs_pn_getvattl(struct puffs_node *); | 
| 530 | struct timespec		*puffs_pn_getcnttl(struct puffs_node *); | 
| 531 |  | 
| 532 | void	puffs_newinfo_setcookie(struct puffs_newinfo *, puffs_cookie_t); | 
| 533 | void	puffs_newinfo_setvtype(struct puffs_newinfo *, enum vtype); | 
| 534 | void	puffs_newinfo_setsize(struct puffs_newinfo *, voff_t); | 
| 535 | void	puffs_newinfo_setrdev(struct puffs_newinfo *, dev_t); | 
| 536 | void	puffs_newinfo_setva(struct puffs_newinfo *, struct vattr *); | 
| 537 | void	puffs_newinfo_setvattl(struct puffs_newinfo *, struct timespec *); | 
| 538 | void	puffs_newinfo_setcnttl(struct puffs_newinfo *, struct timespec *); | 
| 539 |  | 
| 540 | void			*puffs_pn_getmntspecific(struct puffs_node *); | 
| 541 |  | 
| 542 | typedef		void *	(*puffs_nodewalk_fn)(struct puffs_usermount *, | 
| 543 | 					     struct puffs_node *, void *); | 
| 544 | void			*puffs_pn_nodewalk(struct puffs_usermount *, | 
| 545 | 					   puffs_nodewalk_fn, void *); | 
| 546 |  | 
| 547 | void			puffs_setvattr(struct vattr *, const struct vattr *); | 
| 548 | void			puffs_vattr_null(struct vattr *); | 
| 549 |  | 
| 550 | void			puffs_null_setops(struct puffs_ops *); | 
| 551 |  | 
| 552 | int			puffs_dispatch_create(struct puffs_usermount *, | 
| 553 | 					      struct puffs_framebuf *, | 
| 554 | 					      struct puffs_cc **); | 
| 555 | int			puffs_dispatch_exec(struct puffs_cc *, | 
| 556 | 					    struct puffs_framebuf **); | 
| 557 |  | 
| 558 | /* | 
| 559 |  * generic/dummy routines applicable for some file systems | 
| 560 |  */ | 
| 561 | int  puffs_fsnop_unmount(struct puffs_usermount *, int); | 
| 562 | int  puffs_fsnop_statvfs(struct puffs_usermount *, struct statvfs *); | 
| 563 | void puffs_zerostatvfs(struct statvfs *); | 
| 564 | int  puffs_fsnop_sync(struct puffs_usermount *, int waitfor, | 
| 565 | 		      const struct puffs_cred *); | 
| 566 |  | 
| 567 | int  puffs_genfs_node_getattr(struct puffs_usermount *, puffs_cookie_t, | 
| 568 | 			      struct vattr *, const struct puffs_cred *); | 
| 569 | int  puffs_genfs_node_reclaim(struct puffs_usermount *, puffs_cookie_t); | 
| 570 |  | 
| 571 | /* | 
| 572 |  * Subroutine stuff | 
| 573 |  */ | 
| 574 |  | 
| 575 | int		puffs_gendotdent(struct dirent **, ino_t, int, size_t *); | 
| 576 | int		puffs_nextdent(struct dirent **, const char *, ino_t, | 
| 577 | 			       uint8_t, size_t *); | 
| 578 | int		puffs_vtype2dt(enum vtype); | 
| 579 | enum vtype	puffs_mode2vt(mode_t); | 
| 580 | void		puffs_stat2vattr(struct vattr *va, const struct stat *); | 
| 581 | mode_t		puffs_addvtype2mode(mode_t, enum vtype); | 
| 582 |  | 
| 583 |  | 
| 584 | /* | 
| 585 |  * credentials & permissions | 
| 586 |  */ | 
| 587 |  | 
| 588 | /* Credential fetch */ | 
| 589 | int	puffs_cred_getuid(const struct puffs_cred *, uid_t *); | 
| 590 | int	puffs_cred_getgid(const struct puffs_cred *, gid_t *); | 
| 591 | int	puffs_cred_getgroups(const struct puffs_cred *, gid_t *, short *); | 
| 592 |  | 
| 593 | /* Credential check */ | 
| 594 | bool	puffs_cred_isuid(const struct puffs_cred *, uid_t); | 
| 595 | bool	puffs_cred_hasgroup(const struct puffs_cred *, gid_t); | 
| 596 | bool	puffs_cred_isregular(const struct puffs_cred *); | 
| 597 | bool	puffs_cred_iskernel(const struct puffs_cred *); | 
| 598 | bool	puffs_cred_isfs(const struct puffs_cred *); | 
| 599 | bool	puffs_cred_isjuggernaut(const struct puffs_cred *); | 
| 600 |  | 
| 601 | /* misc */ | 
| 602 | int	puffs_access(enum vtype, mode_t, uid_t, gid_t, mode_t, | 
| 603 | 		     const struct puffs_cred *); | 
| 604 | int	puffs_access_chown(uid_t, gid_t, uid_t, gid_t, | 
| 605 | 			   const struct puffs_cred *); | 
| 606 | int	puffs_access_chmod(uid_t, gid_t, enum vtype, mode_t, | 
| 607 | 			   const struct puffs_cred *); | 
| 608 | int	puffs_access_times(uid_t, gid_t, mode_t, int, | 
| 609 | 			   const struct puffs_cred *); | 
| 610 |  | 
| 611 |  | 
| 612 | /* | 
| 613 |  * Call Context interfaces relevant for user. | 
| 614 |  */ | 
| 615 |  | 
| 616 | void			puffs_cc_yield(struct puffs_cc *); | 
| 617 | void			puffs_cc_continue(struct puffs_cc *); | 
| 618 | void			puffs_cc_schedule(struct puffs_cc *); | 
| 619 | int			puffs_cc_getcaller(struct puffs_cc *,pid_t *,lwpid_t *); | 
| 620 | struct puffs_cc		*puffs_cc_getcc(struct puffs_usermount *); | 
| 621 |  | 
| 622 | /* | 
| 623 |  * Flushing / invalidation routines | 
| 624 |  */ | 
| 625 |  | 
| 626 | int	puffs_inval_namecache_dir(struct puffs_usermount *, puffs_cookie_t); | 
| 627 | int	puffs_inval_namecache_all(struct puffs_usermount *); | 
| 628 |  | 
| 629 | int	puffs_inval_pagecache_node(struct puffs_usermount *, puffs_cookie_t); | 
| 630 | int	puffs_inval_pagecache_node_range(struct puffs_usermount *, | 
| 631 | 					 puffs_cookie_t, off_t, off_t); | 
| 632 | int	puffs_flush_pagecache_node(struct puffs_usermount *, puffs_cookie_t); | 
| 633 | int	puffs_flush_pagecache_node_range(struct puffs_usermount *, | 
| 634 | 					 puffs_cookie_t, off_t, off_t); | 
| 635 |  | 
| 636 | /* | 
| 637 |  * Path constructicons | 
| 638 |  */ | 
| 639 |  | 
| 640 | int	puffs_stdpath_buildpath(struct puffs_usermount *, | 
| 641 | 			     const struct puffs_pathobj *, | 
| 642 | 			     const struct puffs_pathobj *, size_t, | 
| 643 | 			     struct puffs_pathobj *); | 
| 644 | int	puffs_stdpath_cmppath(struct puffs_usermount *, struct puffs_pathobj *, | 
| 645 | 			   struct puffs_pathobj *, size_t, int); | 
| 646 | void	puffs_stdpath_freepath(struct puffs_usermount *,struct puffs_pathobj *); | 
| 647 |  | 
| 648 | void	*puffs_path_walkcmp(struct puffs_usermount *, | 
| 649 | 			    struct puffs_node *, void *); | 
| 650 | void	*puffs_path_prefixadj(struct puffs_usermount *, | 
| 651 | 			      struct puffs_node *, void *); | 
| 652 | int	puffs_path_pcnbuild(struct puffs_usermount *, | 
| 653 | 			    struct puffs_cn *, void *); | 
| 654 | void	puffs_path_buildhash(struct puffs_usermount *, struct puffs_pathobj *); | 
| 655 | void	puffs_set_pathbuild(struct puffs_usermount *, pu_pathbuild_fn); void	puffs_set_pathtransform(struct puffs_usermount *, pu_pathtransform_fn); | 
| 656 | void	puffs_set_pathcmp(struct puffs_usermount *, pu_pathcmp_fn); | 
| 657 | void	puffs_set_pathfree(struct puffs_usermount *, pu_pathfree_fn); | 
| 658 | void	puffs_set_namemod(struct puffs_usermount *, pu_namemod_fn); | 
| 659 |  | 
| 660 | void	puffs_set_errnotify(struct puffs_usermount *, pu_errnotify_fn); | 
| 661 | void	puffs_kernerr_log(struct puffs_usermount *, uint8_t, int, | 
| 662 | 			  const char *, puffs_cookie_t); | 
| 663 | __dead void	puffs_kernerr_abort(struct puffs_usermount *, uint8_t, int, | 
| 664 | 			    const char *, puffs_cookie_t); | 
| 665 | void	puffs_set_prepost(struct puffs_usermount *, | 
| 666 | 			  pu_prepost_fn, pu_prepost_fn); | 
| 667 | void	puffs_set_cmap(struct puffs_usermount *, pu_cmap_fn); | 
| 668 |  | 
| 669 | /* | 
| 670 |  * Suspension | 
| 671 |  */ | 
| 672 |  | 
| 673 | int	puffs_fs_suspend(struct puffs_usermount *); | 
| 674 |  | 
| 675 | /* | 
| 676 |  * Frame buffering | 
| 677 |  */ | 
| 678 |  | 
| 679 | void	puffs_framev_init(struct puffs_usermount *, | 
| 680 | 			  puffs_framev_readframe_fn, | 
| 681 | 			  puffs_framev_writeframe_fn, | 
| 682 | 			  puffs_framev_cmpframe_fn, | 
| 683 | 			  puffs_framev_gotframe_fn, | 
| 684 | 			  puffs_framev_fdnotify_fn); | 
| 685 |  | 
| 686 | struct puffs_framebuf 	*puffs_framebuf_make(void); | 
| 687 | void			puffs_framebuf_destroy(struct puffs_framebuf *); | 
| 688 | int			puffs_framebuf_dup(struct puffs_framebuf *, | 
| 689 | 					   struct puffs_framebuf **); | 
| 690 | void			puffs_framebuf_recycle(struct puffs_framebuf *); | 
| 691 | int			puffs_framebuf_reserve_space(struct puffs_framebuf *, | 
| 692 | 						     size_t); | 
| 693 |  | 
| 694 | int	puffs_framebuf_putdata(struct puffs_framebuf *, const void *, size_t); | 
| 695 | int	puffs_framebuf_putdata_atoff(struct puffs_framebuf *, size_t, | 
| 696 | 				     const void *, size_t); | 
| 697 | int	puffs_framebuf_getdata(struct puffs_framebuf *, void *, size_t); | 
| 698 | int	puffs_framebuf_getdata_atoff(struct puffs_framebuf *, size_t, | 
| 699 | 				     void *, size_t); | 
| 700 |  | 
| 701 | size_t	puffs_framebuf_telloff(struct puffs_framebuf *); | 
| 702 | size_t	puffs_framebuf_tellsize(struct puffs_framebuf *); | 
| 703 | size_t	puffs_framebuf_remaining(struct puffs_framebuf *); | 
| 704 | int	puffs_framebuf_seekset(struct puffs_framebuf *, size_t); | 
| 705 | int	puffs_framebuf_getwindow(struct puffs_framebuf *, size_t, | 
| 706 | 				 void **, size_t *); | 
| 707 |  | 
| 708 | int	puffs_framev_enqueue_cc(struct puffs_cc *, int, | 
| 709 | 				struct puffs_framebuf *, int); | 
| 710 | int	puffs_framev_enqueue_cb(struct puffs_usermount *, int, | 
| 711 | 				struct puffs_framebuf *, | 
| 712 | 				puffs_framev_cb, void *, int); | 
| 713 | int	puffs_framev_enqueue_justsend(struct puffs_usermount *, int, | 
| 714 | 				      struct puffs_framebuf *, int, int); | 
| 715 | int	puffs_framev_enqueue_directreceive(struct puffs_cc *, int, | 
| 716 | 					   struct puffs_framebuf *, int); | 
| 717 | int	puffs_framev_enqueue_directsend(struct puffs_cc *, int, | 
| 718 | 					   struct puffs_framebuf *, int); | 
| 719 | int	puffs_framev_enqueue_waitevent(struct puffs_cc *, int, int *); | 
| 720 | int	puffs_framev_framebuf_ccpromote(struct puffs_framebuf *, | 
| 721 | 					struct puffs_cc *); | 
| 722 |  | 
| 723 | int	puffs_framev_addfd(struct puffs_usermount *, int, int); | 
| 724 | int	puffs_framev_enablefd(struct puffs_usermount *, int, int); | 
| 725 | int	puffs_framev_disablefd(struct puffs_usermount *, int, int); | 
| 726 | int	puffs_framev_removefd(struct puffs_usermount *, int, int); | 
| 727 | void	puffs_framev_removeonclose(struct puffs_usermount *, int, int); | 
| 728 | void	puffs_framev_unmountonclose(struct puffs_usermount *, int, int); | 
| 729 |  | 
| 730 | __END_DECLS | 
| 731 |  | 
| 732 | #endif /* _PUFFS_H_ */ | 
| 733 |  |