kernel: Hide the sysctl.debug sysctl in the SYSCTL_DEBUG kernel option.
[dragonfly.git] / sys / vfs / puffs / puffs_sys.h
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/systm.h>
37 #include <sys/condvar.h>
38 #include <sys/lock.h>
39 #include <sys/lockf.h>
40 #include <sys/malloc.h>
41 #include <sys/select.h>
42 #include <sys/queue.h>
43
44 #include <vfs/puffs/puffs_msgif.h>
45
46 MALLOC_DECLARE(M_PUFFS);
47
48 extern struct vop_ops puffs_vnode_vops;
49 extern struct vop_ops puffs_fifo_vops;
50
51 #ifdef DEBUG
52 #ifndef PUFFSDEBUG
53 #define PUFFSDEBUG
54 #endif
55 #endif
56
57 #ifdef PUFFSDEBUG
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
61 #else
62 #define DPRINTF(x)
63 #define DPRINTF_VERBOSE(x)
64 #endif
65
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)
71
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)
75
76 #define ALLOPS(pmp) (pmp->pmp_flags & PUFFS_KFLAG_ALLOPS)
77 #define EXISTSOP(pmp, op) \
78  (ALLOPS(pmp) || ((pmp)->pmp_vnopmask[PUFFS_VN_##op]))
79
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)
84
85 #define PUFFS_WCACHEINFO(pmp)   0
86
87 struct puffs_newcookie {
88         puffs_cookie_t  pnc_cookie;
89
90         LIST_ENTRY(puffs_newcookie) pnc_entries;
91 };
92
93 enum puffs_sopreqtype {
94         PUFFS_SOPREQSYS_EXIT,
95         PUFFS_SOPREQ_FLUSH,
96         PUFFS_SOPREQ_UNMOUNT,
97 };
98
99 struct puffs_sopreq {
100         union {
101                 struct puffs_req preq;
102                 struct puffs_flush pf;
103         } psopr_u;
104
105         enum puffs_sopreqtype psopr_sopreq;
106         TAILQ_ENTRY(puffs_sopreq) psopr_entries;
107 };
108 #define psopr_preq psopr_u.preq
109 #define psopr_pf psopr_u.pf
110
111 TAILQ_HEAD(puffs_wq, puffs_msgpark);
112 LIST_HEAD(puffs_node_hashlist, puffs_node);
113 struct puffs_mount {
114         struct lock                     pmp_lock;
115
116         struct puffs_kargs              pmp_args;
117 #define pmp_flags pmp_args.pa_flags
118 #define pmp_vnopmask pmp_args.pa_vnopmask
119
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;
124
125         struct puffs_wq                 pmp_msg_replywait;
126
127         struct puffs_node_hashlist      *pmp_pnodehash;
128         int                             pmp_npnodehash;
129
130         LIST_HEAD(, puffs_newcookie)    pmp_newcookie;
131
132         struct mount                    *pmp_mp;
133
134         struct vnode                    *pmp_root;
135         puffs_cookie_t                  pmp_root_cookie;
136         enum vtype                      pmp_root_vtype;
137         vsize_t                         pmp_root_vsize;
138         dev_t                           pmp_root_rdev;
139
140         struct putter_instance          *pmp_pi;
141
142         unsigned int                    pmp_refcount;
143         struct cv                       pmp_refcount_cv;
144
145         struct cv                       pmp_unmounting_cv;
146         uint8_t                         pmp_unmounting;
147
148         uint8_t                         pmp_status;
149         uint8_t                         pmp_suspend;
150
151         uint8_t                         *pmp_curput;
152         size_t                          pmp_curres;
153         void                            *pmp_curopaq;
154
155         uint64_t                        pmp_nextmsgid;
156
157         struct lock                     pmp_sopmtx;
158         struct cv                       pmp_sopcv;
159         int                             pmp_sopthrcount;
160         TAILQ_HEAD(, puffs_sopreq)      pmp_sopreqs;
161 };
162
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? */
167
168
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 */
173
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
179
180 struct puffs_node {
181         struct lock     pn_mtx;
182         int             pn_refcount;
183
184         puffs_cookie_t  pn_cookie;      /* userspace pnode cookie       */
185         struct vnode    *pn_vp;         /* backpointer to vnode         */
186         uint32_t        pn_stat;        /* node status                  */
187
188 #ifdef XXXDF
189         struct selinfo  pn_sel;         /* for selecting on the node    */
190 #endif
191         short           pn_revents;     /* available events             */
192
193         /* metacache */
194         struct timespec pn_mc_atime;
195         struct timespec pn_mc_ctime;
196         struct timespec pn_mc_mtime;
197         u_quad_t        pn_mc_size;
198
199         voff_t          pn_serversize;
200
201         struct lockf    pn_lockf;
202
203         LIST_ENTRY(puffs_node) pn_hashent;
204 };
205
206 typedef void (*parkdone_fn)(struct puffs_mount *, struct puffs_req *, void *);
207
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 *);
213
214 void    puffs_sop_thread(void *);
215
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 *);
220
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 *);
225
226 void    puffs_msg_sendresp(struct puffs_mount *, struct puffs_req *, int);
227
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 *);
233
234 void    puffs_releasenode(struct puffs_node *);
235 void    puffs_referencenode(struct puffs_node *);
236
237 #define PUFFS_NOSUCHCOOKIE (-1)
238 int     puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t, int,
239                            struct vnode **);
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 *);
243
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 *);
249
250 void    puffs_mp_reference(struct puffs_mount *);
251 void    puffs_mp_release(struct puffs_mount *);
252
253 void    puffs_gop_size(struct vnode *, off_t, off_t *, int);
254 void    puffs_gop_markupdate(struct vnode *, int);
255
256 void    puffs_senderr(struct puffs_mount *, int, int, const char *,
257                       puffs_cookie_t);
258
259 void    puffs_updatenode(struct puffs_node *, int);
260 #define PUFFS_UPDATEATIME       0x01
261 #define PUFFS_UPDATECTIME       0x02
262 #define PUFFS_UPDATEMTIME       0x04
263
264 int     puffs_meta_setsize(struct vnode *, off_t, int);
265
266 void    puffs_userdead(struct puffs_mount *);
267
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);
273
274
275 /* for putter */
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 *);
281
282 static __inline off_t
283 puffs_meta_getsize(struct vnode *vp)
284 {
285         struct puffs_node *pn = VPTOPP(vp);
286
287         if ((pn->pn_stat & PNODE_METACACHE_SIZE) != 0)
288                 return pn->pn_mc_size;
289         return pn->pn_serversize;
290 }
291
292 static __inline int
293 checkerr(struct puffs_mount *pmp, int error, const char *str)
294 {
295
296         if (error < 0 || error > ELAST) {
297                 puffs_senderr(pmp, PUFFS_ERR_ERROR, error, str, NULL);
298                 error = EPROTO;
299         }
300
301         return error;
302 }
303
304 #define PUFFS_MSG_VARS(type, a)                                         \
305         struct puffs_##type##msg_##a *a##_msg;                          \
306         struct puffs_msgpark *park_##a = NULL
307
308 #define PUFFS_MSG_ALLOC(type, a)                                        \
309         puffs_msgmem_alloc(sizeof(struct puffs_##type##msg_##a),        \
310             &park_##a, (void *)& a##_msg, 1)
311
312 #define PUFFS_MSG_RELEASE(a)                                            \
313 do {                                                                    \
314         if (park_##a) puffs_msgmem_release(park_##a);                   \
315 } while (/*CONSTCOND*/0)
316
317 #define PUFFS_MSG_ENQUEUEWAIT(pmp, park, var)                           \
318 do {                                                                    \
319         puffs_msg_enqueue(pmp, park);                                   \
320         var = puffs_msg_wait(pmp, park);                                \
321 } while (/*CONSTCOND*/0)
322
323 #define PUFFS_MSG_ENQUEUEWAIT2(pmp, park, vp1, vp2, var)                \
324 do {                                                                    \
325         puffs_msg_enqueue(pmp, park);                                   \
326         var = puffs_msg_wait2(pmp, park, vp1, vp2);                     \
327 } while (/*CONSTCOND*/0)
328
329 #endif /* _PUFFS_SYS_H_ */