1 /* $NetBSD: puffs_sys.h,v 1.77 2011/01/11 14:04:54 kefren Exp $ */ 2 3 /* 4 * Copyright (c) 2005, 2006 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_SYS_H_ 33 #define _PUFFS_SYS_H_ 34 35 #include <sys/param.h> 36 #include <sys/select.h> 37 #include <sys/kauth.h> 38 #include <sys/mutex.h> 39 #include <sys/queue.h> 40 #include <sys/pool.h> 41 42 #include <fs/puffs/puffs_msgif.h> 43 44 #include <miscfs/genfs/genfs_node.h> 45 46 extern int (**puffs_vnodeop_p)(void *); 47 extern int (**puffs_specop_p)(void *); 48 extern int (**puffs_fifoop_p)(void *); 49 50 extern const struct vnodeopv_desc puffs_vnodeop_opv_desc; 51 extern const struct vnodeopv_desc puffs_specop_opv_desc; 52 extern const struct vnodeopv_desc puffs_fifoop_opv_desc; 53 extern const struct vnodeopv_desc puffs_msgop_opv_desc; 54 55 extern struct pool puffs_pnpool; 56 57 #ifdef DEBUG 58 #ifndef PUFFSDEBUG 59 #define PUFFSDEBUG 60 #endif 61 #endif 62 63 #ifdef PUFFSDEBUG 64 extern int puffsdebug; /* puffs_subr.c */ 65 #define DPRINTF(x) if (puffsdebug > 0) printf x 66 #define DPRINTF_VERBOSE(x) if (puffsdebug > 1) printf x 67 #else 68 #define DPRINTF(x) 69 #define DPRINTF_VERBOSE(x) 70 #endif 71 72 #define MPTOPUFFSMP(mp) ((struct puffs_mount *)((mp)->mnt_data)) 73 #define PMPTOMP(pmp) (pmp->pmp_mp) 74 #define VPTOPP(vp) ((struct puffs_node *)(vp)->v_data) 75 #define VPTOPNC(vp) (((struct puffs_node *)(vp)->v_data)->pn_cookie) 76 #define VPTOPUFFSMP(vp) ((struct puffs_mount*)((struct puffs_node*)vp->v_data)) 77 78 /* we don't pass the kernel overlay to userspace */ 79 #define PUFFS_TOFHSIZE(s) ((s)==0 ? (s) : (s)+4) 80 #define PUFFS_FROMFHSIZE(s) ((s)==0 ? (s) : (s)-4) 81 82 #define ALLOPS(pmp) (pmp->pmp_flags & PUFFS_KFLAG_ALLOPS) 83 #define EXISTSOP(pmp, op) \ 84 (ALLOPS(pmp) || ((pmp)->pmp_vnopmask[PUFFS_VN_##op])) 85 86 #define PUFFS_USE_NAMECACHE(pmp) \ 87 (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_NAME) == 0) 88 #define PUFFS_USE_PAGECACHE(pmp) \ 89 (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_PAGE) == 0) 90 #define PUFFS_USE_FULLPNBUF(pmp) \ 91 ((pmp)->pmp_flags & PUFFS_KFLAG_LOOKUP_FULLPNBUF) 92 93 #define PUFFS_WCACHEINFO(pmp) 0 94 95 struct puffs_newcookie { 96 puffs_cookie_t pnc_cookie; 97 98 LIST_ENTRY(puffs_newcookie) pnc_entries; 99 }; 100 101 enum puffs_sopreqtype { 102 PUFFS_SOPREQSYS_EXIT, 103 PUFFS_SOPREQ_FLUSH, 104 PUFFS_SOPREQ_UNMOUNT, 105 }; 106 107 struct puffs_sopreq { 108 union { 109 struct puffs_req preq; 110 struct puffs_flush pf; 111 } psopr_u; 112 113 enum puffs_sopreqtype psopr_sopreq; 114 TAILQ_ENTRY(puffs_sopreq) psopr_entries; 115 }; 116 #define psopr_preq psopr_u.preq 117 #define psopr_pf psopr_u.pf 118 119 TAILQ_HEAD(puffs_wq, puffs_msgpark); 120 LIST_HEAD(puffs_node_hashlist, puffs_node); 121 struct puffs_mount { 122 kmutex_t pmp_lock; 123 124 struct puffs_kargs pmp_args; 125 #define pmp_flags pmp_args.pa_flags 126 #define pmp_vnopmask pmp_args.pa_vnopmask 127 128 struct puffs_wq pmp_msg_touser; 129 int pmp_msg_touser_count; 130 kcondvar_t pmp_msg_waiter_cv; 131 size_t pmp_msg_maxsize; 132 133 struct puffs_wq pmp_msg_replywait; 134 135 struct puffs_node_hashlist *pmp_pnodehash; 136 int pmp_npnodehash; 137 138 LIST_HEAD(, puffs_newcookie) pmp_newcookie; 139 140 struct mount *pmp_mp; 141 142 struct vnode *pmp_root; 143 puffs_cookie_t pmp_root_cookie; 144 enum vtype pmp_root_vtype; 145 vsize_t pmp_root_vsize; 146 dev_t pmp_root_rdev; 147 148 struct putter_instance *pmp_pi; 149 150 unsigned int pmp_refcount; 151 kcondvar_t pmp_refcount_cv; 152 153 kcondvar_t pmp_unmounting_cv; 154 uint8_t pmp_unmounting; 155 156 uint8_t pmp_status; 157 uint8_t pmp_suspend; 158 159 uint8_t *pmp_curput; 160 size_t pmp_curres; 161 void *pmp_curopaq; 162 163 uint64_t pmp_nextmsgid; 164 165 kmutex_t pmp_sopmtx; 166 kcondvar_t pmp_sopcv; 167 int pmp_sopthrcount; 168 TAILQ_HEAD(, puffs_sopreq) pmp_sopreqs; 169 bool pmp_docompat; 170 }; 171 172 #define PUFFSTAT_BEFOREINIT 0 173 #define PUFFSTAT_MOUNTING 1 174 #define PUFFSTAT_RUNNING 2 175 #define PUFFSTAT_DYING 3 /* Do you want your possessions identified? */ 176 177 178 #define PNODE_NOREFS 0x01 /* no backend reference */ 179 #define PNODE_DYING 0x02 /* NOREFS + inactive */ 180 #define PNODE_FAF 0x04 /* issue all operations as FAF */ 181 #define PNODE_DOINACT 0x08 /* if inactive-on-demand, call inactive */ 182 183 #define PNODE_METACACHE_ATIME 0x10 /* cache atime metadata */ 184 #define PNODE_METACACHE_CTIME 0x20 /* cache atime metadata */ 185 #define PNODE_METACACHE_MTIME 0x40 /* cache atime metadata */ 186 #define PNODE_METACACHE_SIZE 0x80 /* cache atime metadata */ 187 #define PNODE_METACACHE_MASK 0xf0 188 189 struct puffs_node { 190 struct genfs_node pn_gnode; /* genfs glue */ 191 192 kmutex_t pn_mtx; 193 int pn_refcount; 194 195 puffs_cookie_t pn_cookie; /* userspace pnode cookie */ 196 struct vnode *pn_vp; /* backpointer to vnode */ 197 uint32_t pn_stat; /* node status */ 198 199 struct selinfo pn_sel; /* for selecting on the node */ 200 short pn_revents; /* available events */ 201 202 /* metacache */ 203 struct timespec pn_mc_atime; 204 struct timespec pn_mc_ctime; 205 struct timespec pn_mc_mtime; 206 u_quad_t pn_mc_size; 207 208 voff_t pn_serversize; 209 210 struct lockf * pn_lockf; 211 212 LIST_ENTRY(puffs_node) pn_hashent; 213 }; 214 215 typedef void (*parkdone_fn)(struct puffs_mount *, struct puffs_req *, void *); 216 217 struct puffs_msgpark; 218 void puffs_msgif_init(void); 219 void puffs_msgif_destroy(void); 220 int puffs_msgmem_alloc(size_t, struct puffs_msgpark **, void **, int); 221 void puffs_msgmem_release(struct puffs_msgpark *); 222 223 void puffs_sop_thread(void *); 224 225 void puffs_msg_setfaf(struct puffs_msgpark *); 226 void puffs_msg_setdelta(struct puffs_msgpark *, size_t); 227 void puffs_msg_setinfo(struct puffs_msgpark *, int, int, puffs_cookie_t); 228 void puffs_msg_setcall(struct puffs_msgpark *, parkdone_fn, void *); 229 230 void puffs_msg_enqueue(struct puffs_mount *, struct puffs_msgpark *); 231 int puffs_msg_wait(struct puffs_mount *, struct puffs_msgpark *); 232 int puffs_msg_wait2(struct puffs_mount *, struct puffs_msgpark *, 233 struct puffs_node *, struct puffs_node *); 234 235 void puffs_msg_sendresp(struct puffs_mount *, struct puffs_req *, int); 236 237 int puffs_getvnode(struct mount *, puffs_cookie_t, enum vtype, 238 voff_t, dev_t, struct vnode **); 239 int puffs_newnode(struct mount *, struct vnode *, struct vnode **, 240 puffs_cookie_t, struct componentname *, 241 enum vtype, dev_t); 242 void puffs_putvnode(struct vnode *); 243 244 void puffs_releasenode(struct puffs_node *); 245 void puffs_referencenode(struct puffs_node *); 246 247 #define PUFFS_NOSUCHCOOKIE (-1) 248 int puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t, int, int, 249 struct vnode **); 250 void puffs_makecn(struct puffs_kcn *, struct puffs_kcred *, 251 const struct componentname *, int); 252 void puffs_credcvt(struct puffs_kcred *, kauth_cred_t); 253 254 void puffs_parkdone_asyncbioread(struct puffs_mount *, 255 struct puffs_req *, void *); 256 void puffs_parkdone_asyncbiowrite(struct puffs_mount *, 257 struct puffs_req *, void *); 258 void puffs_parkdone_poll(struct puffs_mount *, struct puffs_req *, void *); 259 260 void puffs_mp_reference(struct puffs_mount *); 261 void puffs_mp_release(struct puffs_mount *); 262 263 void puffs_gop_size(struct vnode *, off_t, off_t *, int); 264 void puffs_gop_markupdate(struct vnode *, int); 265 266 void puffs_senderr(struct puffs_mount *, int, int, const char *, 267 puffs_cookie_t); 268 269 bool puffs_compat_outgoing(struct puffs_req *, struct puffs_req**, ssize_t*); 270 void puffs_compat_incoming(struct puffs_req *, struct puffs_req *); 271 272 void puffs_updatenode(struct puffs_node *, int, voff_t); 273 #define PUFFS_UPDATEATIME 0x01 274 #define PUFFS_UPDATECTIME 0x02 275 #define PUFFS_UPDATEMTIME 0x04 276 #define PUFFS_UPDATESIZE 0x08 277 278 void puffs_userdead(struct puffs_mount *); 279 280 extern int (**puffs_vnodeop_p)(void *); 281 282 /* for putter */ 283 int puffs_msgif_getout(void *, size_t, int, uint8_t **, size_t *, void **); 284 void puffs_msgif_releaseout(void *, void *, int); 285 int puffs_msgif_dispatch(void *, struct putter_hdr *); 286 size_t puffs_msgif_waitcount(void *); 287 int puffs_msgif_close(void *); 288 289 static __inline int 290 checkerr(struct puffs_mount *pmp, int error, const char *str) 291 { 292 293 if (error < 0 || error > ELAST) { 294 puffs_senderr(pmp, PUFFS_ERR_ERROR, error, str, NULL); 295 error = EPROTO; 296 } 297 298 return error; 299 } 300 301 #define PUFFS_MSG_VARS(type, a) \ 302 struct puffs_##type##msg_##a *a##_msg; \ 303 struct puffs_msgpark *park_##a = NULL 304 305 #define PUFFS_MSG_ALLOC(type, a) \ 306 puffs_msgmem_alloc(sizeof(struct puffs_##type##msg_##a), \ 307 &park_##a, (void *)& a##_msg, 1) 308 309 #define PUFFS_MSG_RELEASE(a) \ 310 do { \ 311 if (park_##a) puffs_msgmem_release(park_##a); \ 312 } while (/*CONSTCOND*/0) 313 314 #define PUFFS_MSG_ENQUEUEWAIT(pmp, park, var) \ 315 do { \ 316 puffs_msg_enqueue(pmp, park); \ 317 var = puffs_msg_wait(pmp, park); \ 318 } while (/*CONSTCOND*/0) 319 320 #define PUFFS_MSG_ENQUEUEWAIT2(pmp, park, vp1, vp2, var) \ 321 do { \ 322 puffs_msg_enqueue(pmp, park); \ 323 var = puffs_msg_wait2(pmp, park, vp1, vp2); \ 324 } while (/*CONSTCOND*/0) 325 326 #endif /* _PUFFS_SYS_H_ */ 327