1 /* $NetBSD: puffs_sys.h,v 1.77 2011/01/11 14:04:54 kefren 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/systm.h>
37 #include <sys/condvar.h>
39 #include <sys/lockf.h>
40 #include <sys/malloc.h>
41 #include <sys/select.h>
42 #include <sys/queue.h>
44 #include <vfs/puffs/puffs_msgif.h>
46 MALLOC_DECLARE(M_PUFFS);
48 extern struct vop_ops puffs_vnode_vops;
49 extern struct vop_ops puffs_fifo_vops;
58 extern int puffsdebug; /* puffs_subr.c */
59 #define DPRINTF(x) if (puffsdebug > 0) kprintf x
60 #define DPRINTF_VERBOSE(x) if (puffsdebug > 1) kprintf x
63 #define DPRINTF_VERBOSE(x)
66 #define MPTOPUFFSMP(mp) ((struct puffs_mount *)((mp)->mnt_data))
67 #define PMPTOMP(pmp) (pmp->pmp_mp)
68 #define VPTOPP(vp) ((struct puffs_node *)(vp)->v_data)
69 #define VPTOPNC(vp) (((struct puffs_node *)(vp)->v_data)->pn_cookie)
70 #define VPTOPUFFSMP(vp) MPTOPUFFSMP((vp)->v_mount)
72 /* we don't pass the kernel overlay to userspace */
73 #define PUFFS_TOFHSIZE(s) ((s)==0 ? (s) : (s)+4)
74 #define PUFFS_FROMFHSIZE(s) ((s)==0 ? (s) : (s)-4)
76 #define ALLOPS(pmp) (pmp->pmp_flags & PUFFS_KFLAG_ALLOPS)
77 #define EXISTSOP(pmp, op) \
78 (ALLOPS(pmp) || ((pmp)->pmp_vnopmask[PUFFS_VN_##op]))
80 #define PUFFS_USE_NAMECACHE(pmp) \
81 (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_NAME) == 0)
82 #define PUFFS_USE_PAGECACHE(pmp) \
83 (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_PAGE) == 0)
85 #define PUFFS_WCACHEINFO(pmp) 0
87 struct puffs_newcookie {
88 puffs_cookie_t pnc_cookie;
90 LIST_ENTRY(puffs_newcookie) pnc_entries;
93 enum puffs_sopreqtype {
101 struct puffs_req preq;
102 struct puffs_flush pf;
105 enum puffs_sopreqtype psopr_sopreq;
106 TAILQ_ENTRY(puffs_sopreq) psopr_entries;
108 #define psopr_preq psopr_u.preq
109 #define psopr_pf psopr_u.pf
111 TAILQ_HEAD(puffs_wq, puffs_msgpark);
112 LIST_HEAD(puffs_node_hashlist, puffs_node);
114 struct lock pmp_lock;
116 struct puffs_kargs pmp_args;
117 #define pmp_flags pmp_args.pa_flags
118 #define pmp_vnopmask pmp_args.pa_vnopmask
120 struct puffs_wq pmp_msg_touser;
121 int pmp_msg_touser_count;
122 struct cv pmp_msg_waiter_cv;
123 size_t pmp_msg_maxsize;
125 struct puffs_wq pmp_msg_replywait;
127 struct puffs_node_hashlist *pmp_pnodehash;
130 LIST_HEAD(, puffs_newcookie) pmp_newcookie;
132 struct mount *pmp_mp;
134 struct vnode *pmp_root;
135 puffs_cookie_t pmp_root_cookie;
136 enum vtype pmp_root_vtype;
137 vsize_t pmp_root_vsize;
140 struct putter_instance *pmp_pi;
142 unsigned int pmp_refcount;
143 struct cv pmp_refcount_cv;
145 struct cv pmp_unmounting_cv;
146 uint8_t pmp_unmounting;
155 uint64_t pmp_nextmsgid;
157 struct lock pmp_sopmtx;
160 TAILQ_HEAD(, puffs_sopreq) pmp_sopreqs;
163 #define PUFFSTAT_BEFOREINIT 0
164 #define PUFFSTAT_MOUNTING 1
165 #define PUFFSTAT_RUNNING 2
166 #define PUFFSTAT_DYING 3 /* Do you want your possessions identified? */
169 #define PNODE_NOREFS 0x01 /* no backend reference */
170 #define PNODE_DYING 0x02 /* NOREFS + inactive */
171 #define PNODE_FAF 0x04 /* issue all operations as FAF */
172 #define PNODE_DOINACT 0x08 /* if inactive-on-demand, call inactive */
174 #define PNODE_METACACHE_ATIME 0x10 /* cache atime metadata */
175 #define PNODE_METACACHE_CTIME 0x20 /* cache atime metadata */
176 #define PNODE_METACACHE_MTIME 0x40 /* cache atime metadata */
177 #define PNODE_METACACHE_SIZE 0x80 /* cache atime metadata */
178 #define PNODE_METACACHE_MASK 0xf0
184 puffs_cookie_t pn_cookie; /* userspace pnode cookie */
185 struct vnode *pn_vp; /* backpointer to vnode */
186 uint32_t pn_stat; /* node status */
189 struct selinfo pn_sel; /* for selecting on the node */
191 short pn_revents; /* available events */
194 struct timespec pn_mc_atime;
195 struct timespec pn_mc_ctime;
196 struct timespec pn_mc_mtime;
199 voff_t pn_serversize;
201 struct lockf pn_lockf;
203 LIST_ENTRY(puffs_node) pn_hashent;
206 typedef void (*parkdone_fn)(struct puffs_mount *, struct puffs_req *, void *);
208 struct puffs_msgpark;
209 void puffs_msgif_init(void);
210 void puffs_msgif_destroy(void);
211 int puffs_msgmem_alloc(size_t, struct puffs_msgpark **, void **, int);
212 void puffs_msgmem_release(struct puffs_msgpark *);
214 void puffs_sop_thread(void *);
216 void puffs_msg_setfaf(struct puffs_msgpark *);
217 void puffs_msg_setdelta(struct puffs_msgpark *, size_t);
218 void puffs_msg_setinfo(struct puffs_msgpark *, int, int, puffs_cookie_t);
219 void puffs_msg_setcall(struct puffs_msgpark *, parkdone_fn, void *);
221 void puffs_msg_enqueue(struct puffs_mount *, struct puffs_msgpark *);
222 int puffs_msg_wait(struct puffs_mount *, struct puffs_msgpark *);
223 int puffs_msg_wait2(struct puffs_mount *, struct puffs_msgpark *,
224 struct puffs_node *, struct puffs_node *);
226 void puffs_msg_sendresp(struct puffs_mount *, struct puffs_req *, int);
228 int puffs_getvnode(struct mount *, puffs_cookie_t, enum vtype,
229 voff_t, struct vnode **);
230 int puffs_newnode(struct mount *, struct vnode *, struct vnode **,
231 puffs_cookie_t, enum vtype);
232 void puffs_putvnode(struct vnode *);
234 void puffs_releasenode(struct puffs_node *);
235 void puffs_referencenode(struct puffs_node *);
237 #define PUFFS_NOSUCHCOOKIE (-1)
238 int puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t, int,
240 void puffs_makecn(struct puffs_kcn *, struct puffs_kcred *,
241 const struct namecache *, struct ucred *);
242 void puffs_credcvt(struct puffs_kcred *, struct ucred *);
244 void puffs_parkdone_asyncbioread(struct puffs_mount *,
245 struct puffs_req *, void *);
246 void puffs_parkdone_asyncbiowrite(struct puffs_mount *,
247 struct puffs_req *, void *);
248 void puffs_parkdone_poll(struct puffs_mount *, struct puffs_req *, void *);
250 void puffs_mp_reference(struct puffs_mount *);
251 void puffs_mp_release(struct puffs_mount *);
253 void puffs_gop_size(struct vnode *, off_t, off_t *, int);
254 void puffs_gop_markupdate(struct vnode *, int);
256 void puffs_senderr(struct puffs_mount *, int, int, const char *,
259 void puffs_updatenode(struct puffs_node *, int);
260 #define PUFFS_UPDATEATIME 0x01
261 #define PUFFS_UPDATECTIME 0x02
262 #define PUFFS_UPDATEMTIME 0x04
264 int puffs_meta_setsize(struct vnode *, off_t, int);
266 void puffs_userdead(struct puffs_mount *);
268 int puffs_directread(struct vnode *, struct uio *, int, struct ucred *);
269 int puffs_directwrite(struct vnode *, struct uio *, int, struct ucred *);
270 int puffs_bioread(struct vnode *, struct uio *, int, struct ucred *);
271 int puffs_biowrite(struct vnode *, struct uio *, int, struct ucred *);
272 int puffs_doio(struct vnode *vp, struct bio *bio, struct thread *td);
276 int puffs_msgif_getout(void *, size_t, int, uint8_t **, size_t *, void **);
277 void puffs_msgif_releaseout(void *, void *, int);
278 int puffs_msgif_dispatch(void *, struct putter_hdr *);
279 size_t puffs_msgif_waitcount(void *);
280 int puffs_msgif_close(void *);
282 static __inline off_t
283 puffs_meta_getsize(struct vnode *vp)
285 struct puffs_node *pn = VPTOPP(vp);
287 if ((pn->pn_stat & PNODE_METACACHE_SIZE) != 0)
288 return pn->pn_mc_size;
289 return pn->pn_serversize;
293 checkerr(struct puffs_mount *pmp, int error, const char *str)
296 if (error < 0 || error > ELAST) {
297 puffs_senderr(pmp, PUFFS_ERR_ERROR, error, str, NULL);
304 #define PUFFS_MSG_VARS(type, a) \
305 struct puffs_##type##msg_##a *a##_msg; \
306 struct puffs_msgpark *park_##a = NULL
308 #define PUFFS_MSG_ALLOC(type, a) \
309 puffs_msgmem_alloc(sizeof(struct puffs_##type##msg_##a), \
310 &park_##a, (void *)& a##_msg, 1)
312 #define PUFFS_MSG_RELEASE(a) \
314 if (park_##a) puffs_msgmem_release(park_##a); \
315 } while (/*CONSTCOND*/0)
317 #define PUFFS_MSG_ENQUEUEWAIT(pmp, park, var) \
319 puffs_msg_enqueue(pmp, park); \
320 var = puffs_msg_wait(pmp, park); \
321 } while (/*CONSTCOND*/0)
323 #define PUFFS_MSG_ENQUEUEWAIT2(pmp, park, vp1, vp2, var) \
325 puffs_msg_enqueue(pmp, park); \
326 var = puffs_msg_wait2(pmp, park, vp1, vp2); \
327 } while (/*CONSTCOND*/0)
329 #endif /* _PUFFS_SYS_H_ */