1 /* $NetBSD: puffs_sys.h,v 1.89 2015/02/15 20:21:29 manu Exp $ */
4 * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
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.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
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>
42 #include <fs/puffs/puffs_msgif.h>
44 #include <miscfs/genfs/genfs_node.h>
46 extern int (**puffs_vnodeop_p
)(void *);
47 extern int (**puffs_specop_p
)(void *);
48 extern int (**puffs_fifoop_p
)(void *);
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
;
55 extern struct pool puffs_pnpool
;
56 extern struct pool puffs_vapool
;
65 extern int puffsdebug
; /* puffs_subr.c */
66 #define DPRINTF(x) do { \
67 if (puffsdebug > 0) printf x; \
68 } while (/*CONSTCOND*/0)
69 #define DPRINTF_VERBOSE(x) do { \
70 if (puffsdebug > 1) printf x; \
71 } while (/*CONSTCOND*/0)
73 #define DPRINTF(x) ((void)0)
74 #define DPRINTF_VERBOSE(x) ((void)0)
77 #define MPTOPUFFSMP(mp) ((struct puffs_mount *)((mp)->mnt_data))
78 #define PMPTOMP(pmp) (pmp->pmp_mp)
79 #define VPTOPP(vp) ((struct puffs_node *)(vp)->v_data)
80 #define VPTOPNC(vp) (((struct puffs_node *)(vp)->v_data)->pn_cookie)
81 #define VPTOPUFFSMP(vp) ((struct puffs_mount*)((struct puffs_node*)vp->v_data))
83 /* we don't pass the kernel overlay to userspace */
84 #define PUFFS_TOFHSIZE(s) ((s)==0 ? (s) : (s)+4)
85 #define PUFFS_FROMFHSIZE(s) ((s)==0 ? (s) : (s)-4)
87 #define ALLOPS(pmp) (pmp->pmp_flags & PUFFS_KFLAG_ALLOPS)
88 #define EXISTSOP(pmp, op) \
89 (ALLOPS(pmp) || ((pmp)->pmp_vnopmask[PUFFS_VN_##op]))
91 #define PUFFS_USE_NAMECACHE(pmp) \
92 (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_NAME) == 0)
93 #define PUFFS_USE_PAGECACHE(pmp) \
94 (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_PAGE) == 0)
95 #define PUFFS_USE_FULLPNBUF(pmp) \
96 ((pmp)->pmp_flags & PUFFS_KFLAG_LOOKUP_FULLPNBUF)
97 #define PUFFS_USE_FS_TTL(pmp) \
98 ((pmp)->pmp_flags & PUFFS_KFLAG_CACHE_FS_TTL)
99 #define PUFFS_USE_DOTDOTCACHE(pmp) \
100 ((pmp)->pmp_flags & PUFFS_KFLAG_CACHE_DOTDOT)
101 #define PUFFS_USE_METAFLUSH(pmp) \
102 (((pmp)->pmp_flags & PUFFS_KFLAG_NOFLUSH_META) == 0)
104 #define PUFFS_WCACHEINFO(pmp) (__USE(pmp), 0)
106 struct puffs_newcookie
{
107 puffs_cookie_t pnc_cookie
;
109 LIST_ENTRY(puffs_newcookie
) pnc_entries
;
112 #define PUFFS_SOPREQ_EXPIRE_TIMEOUT 1000
113 extern int puffs_sopreq_expire_timeout
;
115 enum puffs_sopreqtype
{
116 PUFFS_SOPREQSYS_EXIT
,
118 PUFFS_SOPREQ_UNMOUNT
,
122 struct puffs_sopreq
{
124 struct puffs_req preq
;
125 struct puffs_flush pf
;
129 enum puffs_sopreqtype psopr_sopreq
;
130 TAILQ_ENTRY(puffs_sopreq
) psopr_entries
;
133 #define psopr_preq psopr_u.preq
134 #define psopr_pf psopr_u.pf
135 #define psopr_ck psopr_u.ck
137 TAILQ_HEAD(puffs_wq
, puffs_msgpark
);
138 LIST_HEAD(puffs_node_hashlist
, puffs_node
);
142 struct puffs_kargs pmp_args
;
143 #define pmp_flags pmp_args.pa_flags
144 #define pmp_vnopmask pmp_args.pa_vnopmask
146 struct puffs_wq pmp_msg_touser
;
147 int pmp_msg_touser_count
;
148 kcondvar_t pmp_msg_waiter_cv
;
149 size_t pmp_msg_maxsize
;
151 struct puffs_wq pmp_msg_replywait
;
153 struct mount
*pmp_mp
;
155 struct vnode
*pmp_root
;
156 puffs_cookie_t pmp_root_cookie
;
157 enum vtype pmp_root_vtype
;
158 vsize_t pmp_root_vsize
;
161 struct putter_instance
*pmp_pi
;
163 unsigned int pmp_refcount
;
164 kcondvar_t pmp_refcount_cv
;
166 kcondvar_t pmp_unmounting_cv
;
167 uint8_t pmp_unmounting
;
176 uint64_t pmp_nextmsgid
;
179 kcondvar_t pmp_sopcv
;
181 TAILQ_HEAD(, puffs_sopreq
) pmp_sopfastreqs
;
182 TAILQ_HEAD(, puffs_sopreq
) pmp_sopnodereqs
;
186 #define PUFFSTAT_BEFOREINIT 0
187 #define PUFFSTAT_MOUNTING 1
188 #define PUFFSTAT_RUNNING 2
189 #define PUFFSTAT_DYING 3 /* Do you want your possessions identified? */
192 #define PNODE_NOREFS 0x001 /* no backend reference */
193 #define PNODE_DYING 0x002 /* NOREFS + inactive */
194 #define PNODE_FAF 0x004 /* issue all operations as FAF */
195 #define PNODE_DOINACT 0x008 /* if inactive-on-demand, call inactive */
196 #define PNODE_SOPEXP 0x100 /* Node reclaim postponed in sop thread */
197 #define PNODE_RDIRECT 0x200 /* bypass page cache on read */
198 #define PNODE_WDIRECT 0x400 /* bypass page cache on write */
200 #define PNODE_METACACHE_ATIME 0x10 /* cache atime metadata */
201 #define PNODE_METACACHE_CTIME 0x20 /* cache atime metadata */
202 #define PNODE_METACACHE_MTIME 0x40 /* cache atime metadata */
203 #define PNODE_METACACHE_SIZE 0x80 /* cache atime metadata */
204 #define PNODE_METACACHE_MASK 0xf0
207 struct genfs_node pn_gnode
; /* genfs glue */
213 puffs_cookie_t pn_cookie
; /* userspace pnode cookie */
214 struct vnode
*pn_vp
; /* backpointer to vnode */
215 uint32_t pn_stat
; /* node status */
217 struct selinfo pn_sel
; /* for selecting on the node */
218 short pn_revents
; /* available events */
221 struct timespec pn_mc_atime
;
222 struct timespec pn_mc_ctime
;
223 struct timespec pn_mc_mtime
;
226 voff_t pn_serversize
;
228 struct lockf
* pn_lockf
;
230 kmutex_t pn_sizemtx
; /* size modification mutex */
232 int pn_cn_timeout
; /* path cache */
233 int pn_cn_grace
; /* grace time before reclaim */
234 int pn_va_timeout
; /* attribute cache */
235 struct vattr
* pn_va_cache
; /* attribute cache */
236 struct vnode
* pn_parent
; /* parent cache */
239 typedef void (*parkdone_fn
)(struct puffs_mount
*, struct puffs_req
*, void *);
241 struct puffs_msgpark
;
242 void puffs_msgif_init(void);
243 void puffs_msgif_destroy(void);
244 int puffs_msgmem_alloc(size_t, struct puffs_msgpark
**, void **, int);
245 void puffs_msgmem_release(struct puffs_msgpark
*);
247 void puffs_sop_thread(void *);
249 void puffs_msg_setfaf(struct puffs_msgpark
*);
250 void puffs_msg_setdelta(struct puffs_msgpark
*, size_t);
251 void puffs_msg_setinfo(struct puffs_msgpark
*, int, int, puffs_cookie_t
);
252 void puffs_msg_setcall(struct puffs_msgpark
*, parkdone_fn
, void *);
254 void puffs_msg_enqueue(struct puffs_mount
*, struct puffs_msgpark
*);
255 int puffs_msg_wait(struct puffs_mount
*, struct puffs_msgpark
*);
256 int puffs_msg_wait2(struct puffs_mount
*, struct puffs_msgpark
*,
257 struct puffs_node
*, struct puffs_node
*);
259 void puffs_msg_sendresp(struct puffs_mount
*, struct puffs_req
*, int);
261 int puffs_getvnode(struct mount
*, puffs_cookie_t
, enum vtype
,
262 voff_t
, dev_t
, struct vnode
**);
263 int puffs_newnode(struct mount
*, struct vnode
*, struct vnode
**,
264 puffs_cookie_t
, struct componentname
*,
266 void puffs_putvnode(struct vnode
*);
268 void puffs_releasenode(struct puffs_node
*);
269 void puffs_referencenode(struct puffs_node
*);
271 #define PUFFS_NOSUCHCOOKIE (-1)
272 int puffs_cookie2vnode(struct puffs_mount
*, puffs_cookie_t
,
274 void puffs_makecn(struct puffs_kcn
*, struct puffs_kcred
*,
275 const struct componentname
*, int);
276 void puffs_credcvt(struct puffs_kcred
*, kauth_cred_t
);
278 void puffs_parkdone_asyncbioread(struct puffs_mount
*,
279 struct puffs_req
*, void *);
280 void puffs_parkdone_asyncbiowrite(struct puffs_mount
*,
281 struct puffs_req
*, void *);
282 void puffs_parkdone_poll(struct puffs_mount
*, struct puffs_req
*, void *);
284 void puffs_mp_reference(struct puffs_mount
*);
285 void puffs_mp_release(struct puffs_mount
*);
287 void puffs_gop_size(struct vnode
*, off_t
, off_t
*, int);
288 void puffs_gop_markupdate(struct vnode
*, int);
290 void puffs_senderr(struct puffs_mount
*, int, int, const char *,
293 bool puffs_compat_outgoing(struct puffs_req
*, struct puffs_req
**, ssize_t
*);
294 void puffs_compat_incoming(struct puffs_req
*, struct puffs_req
*);
296 void puffs_updatenode(struct puffs_node
*, int, voff_t
);
297 #define PUFFS_UPDATEATIME 0x01
298 #define PUFFS_UPDATECTIME 0x02
299 #define PUFFS_UPDATEMTIME 0x04
300 #define PUFFS_UPDATESIZE 0x08
302 void puffs_userdead(struct puffs_mount
*);
304 extern int (**puffs_vnodeop_p
)(void *);
307 int puffs_msgif_getout(void *, size_t, int, uint8_t **, size_t *, void **);
308 void puffs_msgif_releaseout(void *, void *, int);
309 int puffs_msgif_dispatch(void *, struct putter_hdr
*);
310 size_t puffs_msgif_waitcount(void *);
311 int puffs_msgif_close(void *);
314 checkerr(struct puffs_mount
*pmp
, int error
, const char *str
)
317 if (error
< 0 || error
> ELAST
) {
318 puffs_senderr(pmp
, PUFFS_ERR_ERROR
, error
, str
, NULL
);
325 #define PUFFS_MSG_VARS(type, a) \
326 struct puffs_##type##msg_##a *a##_msg; \
327 struct puffs_msgpark *park_##a = NULL
329 #define PUFFS_MSG_ALLOC(type, a) \
330 puffs_msgmem_alloc(sizeof(struct puffs_##type##msg_##a), \
331 &park_##a, (void *)& a##_msg, 1)
333 #define PUFFS_MSG_RELEASE(a) \
335 if (park_##a) puffs_msgmem_release(park_##a); \
336 } while (/*CONSTCOND*/0)
338 #define PUFFS_MSG_ENQUEUEWAIT_NOERROR(pmp, park) \
340 puffs_msg_enqueue(pmp, park); \
341 puffs_msg_wait(pmp, park); \
342 } while (/*CONSTCOND*/0)
344 #define PUFFS_MSG_ENQUEUEWAIT2_NOERROR(pmp, park, vp1, vp2) \
346 puffs_msg_enqueue(pmp, park); \
347 puffs_msg_wait2(pmp, park, vp1, vp2); \
348 } while (/*CONSTCOND*/0)
350 #define PUFFS_MSG_ENQUEUEWAIT(pmp, park, var) \
352 puffs_msg_enqueue(pmp, park); \
353 var = puffs_msg_wait(pmp, park); \
354 } while (/*CONSTCOND*/0)
356 #define PUFFS_MSG_ENQUEUEWAIT2(pmp, park, vp1, vp2, var) \
358 puffs_msg_enqueue(pmp, park); \
359 var = puffs_msg_wait2(pmp, park, vp1, vp2); \
360 } while (/*CONSTCOND*/0)
362 #endif /* _PUFFS_SYS_H_ */