xref: /minix3/lib/libpuffs/puffs_priv.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
184d9c625SLionel Sambuc /*	$NetBSD: puffs_priv.h,v 1.45 2012/04/18 00:57:22 manu Exp $	*/
2490e0de5SThomas Veerman 
3490e0de5SThomas Veerman /*
4490e0de5SThomas Veerman  * Copyright (c) 2006, 2007, 2008 Antti Kantee.  All Rights Reserved.
5490e0de5SThomas Veerman  *
6490e0de5SThomas Veerman  * Redistribution and use in source and binary forms, with or without
7490e0de5SThomas Veerman  * modification, are permitted provided that the following conditions
8490e0de5SThomas Veerman  * are met:
9490e0de5SThomas Veerman  * 1. Redistributions of source code must retain the above copyright
10490e0de5SThomas Veerman  *    notice, this list of conditions and the following disclaimer.
11490e0de5SThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
12490e0de5SThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
13490e0de5SThomas Veerman  *    documentation and/or other materials provided with the distribution.
14490e0de5SThomas Veerman  *
15490e0de5SThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16490e0de5SThomas Veerman  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17490e0de5SThomas Veerman  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18490e0de5SThomas Veerman  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19490e0de5SThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20490e0de5SThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21490e0de5SThomas Veerman  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22490e0de5SThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23490e0de5SThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24490e0de5SThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25490e0de5SThomas Veerman  * SUCH DAMAGE.
26490e0de5SThomas Veerman  */
27490e0de5SThomas Veerman 
28490e0de5SThomas Veerman #ifndef _PUFFS_PRIVATE_H_
29490e0de5SThomas Veerman #define _PUFFS_PRIVATE_H_
30490e0de5SThomas Veerman 
31490e0de5SThomas Veerman #include <sys/types.h>
3284d9c625SLionel Sambuc #include <fs/puffs/puffs_msgif.h>
3384d9c625SLionel Sambuc 
3484d9c625SLionel Sambuc #if !defined(__minix)
3584d9c625SLionel Sambuc #include <pthread.h>
3684d9c625SLionel Sambuc #endif /* !defined(__minix) */
3784d9c625SLionel Sambuc #include <puffs.h>
38490e0de5SThomas Veerman #include <ucontext.h>
39490e0de5SThomas Veerman 
40ba736c79SDavid van Moolenbroek #if !defined(__minix)
41490e0de5SThomas Veerman extern pthread_mutex_t pu_lock;
42490e0de5SThomas Veerman #define PU_LOCK() pthread_mutex_lock(&pu_lock)
43490e0de5SThomas Veerman #define PU_UNLOCK() pthread_mutex_unlock(&pu_lock)
44*0a6a1f1dSLionel Sambuc #else
4584d9c625SLionel Sambuc #define PU_LOCK() /* nothing */
4684d9c625SLionel Sambuc #define PU_UNLOCK()  /* nothing */
47*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) */
48490e0de5SThomas Veerman 
49490e0de5SThomas Veerman #define PU_CMAP(pu, c) (pu->pu_cmap ? pu->pu_cmap(pu,c) : (struct puffs_node*)c)
50490e0de5SThomas Veerman 
51490e0de5SThomas Veerman struct puffs_framectrl {
52490e0de5SThomas Veerman 	puffs_framev_readframe_fn rfb;
53490e0de5SThomas Veerman 	puffs_framev_writeframe_fn wfb;
54490e0de5SThomas Veerman 	puffs_framev_cmpframe_fn cmpfb;
55490e0de5SThomas Veerman 	puffs_framev_gotframe_fn gotfb;
56490e0de5SThomas Veerman 	puffs_framev_fdnotify_fn fdnotfn;
57490e0de5SThomas Veerman };
58490e0de5SThomas Veerman 
59490e0de5SThomas Veerman struct puffs_fctrl_io {
60490e0de5SThomas Veerman 	struct puffs_framectrl *fctrl;
61490e0de5SThomas Veerman 
62490e0de5SThomas Veerman 	int io_fd;
63490e0de5SThomas Veerman 	int stat;
64490e0de5SThomas Veerman 
65490e0de5SThomas Veerman 	int rwait;
66490e0de5SThomas Veerman 	int wwait;
67490e0de5SThomas Veerman 
68490e0de5SThomas Veerman 	struct puffs_framebuf *cur_in;
69490e0de5SThomas Veerman 
70490e0de5SThomas Veerman 	TAILQ_HEAD(, puffs_framebuf) snd_qing;	/* queueing to be sent */
71490e0de5SThomas Veerman 	TAILQ_HEAD(, puffs_framebuf) res_qing;	/* q'ing for rescue */
72490e0de5SThomas Veerman 	LIST_HEAD(, puffs_fbevent) ev_qing;	/* q'ing for events */
73490e0de5SThomas Veerman 
74490e0de5SThomas Veerman 	LIST_ENTRY(puffs_fctrl_io) fio_entries;
75490e0de5SThomas Veerman };
76490e0de5SThomas Veerman #define FIO_WR		0x01
77490e0de5SThomas Veerman #define FIO_WRGONE	0x02
78490e0de5SThomas Veerman #define FIO_RDGONE	0x04
79490e0de5SThomas Veerman #define FIO_DEAD	0x08
80490e0de5SThomas Veerman #define FIO_ENABLE_R	0x10
81490e0de5SThomas Veerman #define FIO_ENABLE_W	0x20
82490e0de5SThomas Veerman 
83490e0de5SThomas Veerman #define FIO_EN_WRITE(fio)				\
84490e0de5SThomas Veerman     (!(fio->stat & FIO_WR)				\
85490e0de5SThomas Veerman       && ((!TAILQ_EMPTY(&fio->snd_qing)			\
86490e0de5SThomas Veerman             && (fio->stat & FIO_ENABLE_W))		\
87490e0de5SThomas Veerman          || fio->wwait))
88490e0de5SThomas Veerman 
89490e0de5SThomas Veerman #define FIO_RM_WRITE(fio)			\
90490e0de5SThomas Veerman     ((fio->stat & FIO_WR)			\
91490e0de5SThomas Veerman       && (((TAILQ_EMPTY(&fio->snd_qing)		\
92490e0de5SThomas Veerman         || (fio->stat & FIO_ENABLE_W) == 0))	\
93490e0de5SThomas Veerman 	&& (fio->wwait == 0)))
94490e0de5SThomas Veerman 
95490e0de5SThomas Veerman 
96490e0de5SThomas Veerman /*
97490e0de5SThomas Veerman  * usermount: describes one file system instance
98490e0de5SThomas Veerman  */
99490e0de5SThomas Veerman struct puffs_usermount {
100490e0de5SThomas Veerman 	struct puffs_ops	pu_ops;
101490e0de5SThomas Veerman 
102490e0de5SThomas Veerman 	int			pu_fd;
103490e0de5SThomas Veerman 	size_t			pu_maxreqlen;
104490e0de5SThomas Veerman 
105490e0de5SThomas Veerman 	uint32_t		pu_flags;
106490e0de5SThomas Veerman 	int			pu_cc_stackshift;
107490e0de5SThomas Veerman 
108490e0de5SThomas Veerman 	ucontext_t		pu_mainctx;
109490e0de5SThomas Veerman #define PUFFS_CCMAXSTORE 32
110490e0de5SThomas Veerman 	int			pu_cc_nstored;
111490e0de5SThomas Veerman 
112490e0de5SThomas Veerman 	int			pu_kq;
113490e0de5SThomas Veerman 	int			pu_state;
114490e0de5SThomas Veerman #define PU_STATEMASK	0x00ff
115490e0de5SThomas Veerman #define PU_INLOOP	0x0100
116490e0de5SThomas Veerman #define PU_ASYNCFD	0x0200
117490e0de5SThomas Veerman #define PU_HASKQ	0x0400
118490e0de5SThomas Veerman #define PU_PUFFSDAEMON	0x0800
119490e0de5SThomas Veerman #define PU_MAINRESTORE	0x1000
12084d9c625SLionel Sambuc #define PU_DONEXIT	0x2000
121490e0de5SThomas Veerman #define PU_SETSTATE(pu, s) (pu->pu_state = (s) | (pu->pu_state & ~PU_STATEMASK))
122490e0de5SThomas Veerman #define PU_SETSFLAG(pu, s) (pu->pu_state |= (s))
123490e0de5SThomas Veerman #define PU_CLRSFLAG(pu, s) \
12484d9c625SLionel Sambuc     (pu->pu_state = ((pu->pu_state & ~(s)) | (pu->pu_state & PU_STATEMASK)))
125490e0de5SThomas Veerman 	int			pu_dpipe[2];
126490e0de5SThomas Veerman 
127490e0de5SThomas Veerman 	struct puffs_node	*pu_pn_root;
128490e0de5SThomas Veerman 
129490e0de5SThomas Veerman 	LIST_HEAD(, puffs_node)	pu_pnodelst;
130ba736c79SDavid van Moolenbroek #if defined(__minix)
131490e0de5SThomas Veerman 	LIST_HEAD(, puffs_node)	pu_pnode_removed_lst;
13284d9c625SLionel Sambuc #endif /* defined(__minix) */
133490e0de5SThomas Veerman 
134490e0de5SThomas Veerman 	LIST_HEAD(, puffs_cc)	pu_ccmagazin;
135490e0de5SThomas Veerman 	TAILQ_HEAD(, puffs_cc)	pu_lazyctx;
136490e0de5SThomas Veerman 	TAILQ_HEAD(, puffs_cc)	pu_sched;
137490e0de5SThomas Veerman 
138490e0de5SThomas Veerman 	pu_cmap_fn		pu_cmap;
139490e0de5SThomas Veerman 
140490e0de5SThomas Veerman 	pu_pathbuild_fn		pu_pathbuild;
141490e0de5SThomas Veerman 	pu_pathtransform_fn	pu_pathtransform;
142490e0de5SThomas Veerman 	pu_pathcmp_fn		pu_pathcmp;
143490e0de5SThomas Veerman 	pu_pathfree_fn		pu_pathfree;
144490e0de5SThomas Veerman 	pu_namemod_fn		pu_namemod;
145490e0de5SThomas Veerman 
146490e0de5SThomas Veerman 	pu_errnotify_fn		pu_errnotify;
147490e0de5SThomas Veerman 
148490e0de5SThomas Veerman 	pu_prepost_fn		pu_oppre;
149490e0de5SThomas Veerman 	pu_prepost_fn		pu_oppost;
150490e0de5SThomas Veerman 
151490e0de5SThomas Veerman 	struct puffs_framectrl	pu_framectrl[2];
152490e0de5SThomas Veerman #define PU_FRAMECTRL_FS   0
153490e0de5SThomas Veerman #define PU_FRAMECTRL_USER 1
154490e0de5SThomas Veerman 	LIST_HEAD(, puffs_fctrl_io) pu_ios;
155490e0de5SThomas Veerman 	LIST_HEAD(, puffs_fctrl_io) pu_ios_rmlist;
156490e0de5SThomas Veerman 	struct kevent		*pu_evs;
15784d9c625SLionel Sambuc 	size_t			pu_nevs;
158490e0de5SThomas Veerman 
159490e0de5SThomas Veerman 	puffs_ml_loop_fn	pu_ml_lfn;
160490e0de5SThomas Veerman 	struct timespec		pu_ml_timeout;
161490e0de5SThomas Veerman 	struct timespec		*pu_ml_timep;
162490e0de5SThomas Veerman 
163490e0de5SThomas Veerman 	struct puffs_kargs	*pu_kargp;
164490e0de5SThomas Veerman 
165490e0de5SThomas Veerman 	uint64_t		pu_nextreq;
166490e0de5SThomas Veerman 	void			*pu_privdata;
167490e0de5SThomas Veerman };
168490e0de5SThomas Veerman 
169490e0de5SThomas Veerman /* call context */
170490e0de5SThomas Veerman 
171490e0de5SThomas Veerman struct puffs_cc;
172490e0de5SThomas Veerman typedef void (*puffs_ccfunc)(struct puffs_cc *);
173490e0de5SThomas Veerman 
174490e0de5SThomas Veerman struct puffs_cc {
175490e0de5SThomas Veerman 	struct puffs_usermount	*pcc_pu;
176490e0de5SThomas Veerman 	struct puffs_framebuf	*pcc_pb;
177490e0de5SThomas Veerman 
178490e0de5SThomas Veerman 	/* real cc */
179490e0de5SThomas Veerman 	union {
180490e0de5SThomas Veerman 		struct {
181490e0de5SThomas Veerman 			ucontext_t	uc;		/* "continue"	*/
182490e0de5SThomas Veerman 			ucontext_t	uc_ret;		/* "yield" 	*/
183490e0de5SThomas Veerman 		} real;
184490e0de5SThomas Veerman 		struct {
185490e0de5SThomas Veerman 			puffs_ccfunc	func;
186490e0de5SThomas Veerman 			void		*farg;
187490e0de5SThomas Veerman 		} fake;
188490e0de5SThomas Veerman 	} pcc_u;
189490e0de5SThomas Veerman 
190490e0de5SThomas Veerman 	pid_t			pcc_pid;
191490e0de5SThomas Veerman 	lwpid_t			pcc_lid;
192490e0de5SThomas Veerman 
193490e0de5SThomas Veerman 	int			pcc_flags;
194490e0de5SThomas Veerman 
195490e0de5SThomas Veerman 	TAILQ_ENTRY(puffs_cc)	pcc_schedent;
196490e0de5SThomas Veerman 	LIST_ENTRY(puffs_cc)	pcc_rope;
197490e0de5SThomas Veerman };
198490e0de5SThomas Veerman #define pcc_uc		pcc_u.real.uc
199490e0de5SThomas Veerman #define pcc_uc_ret 	pcc_u.real.uc_ret
200490e0de5SThomas Veerman #define pcc_func	pcc_u.fake.func
201490e0de5SThomas Veerman #define pcc_farg	pcc_u.fake.farg
202490e0de5SThomas Veerman #define PCC_DONE	0x01
203490e0de5SThomas Veerman #define PCC_BORROWED	0x02
204490e0de5SThomas Veerman #define PCC_HASCALLER	0x04
205490e0de5SThomas Veerman #define PCC_MLCONT	0x08
206490e0de5SThomas Veerman 
207490e0de5SThomas Veerman struct puffs_newinfo {
208490e0de5SThomas Veerman 	void		**pni_cookie;
209490e0de5SThomas Veerman 	enum vtype	*pni_vtype;
210490e0de5SThomas Veerman 	voff_t		*pni_size;
211490e0de5SThomas Veerman 	dev_t		*pni_rdev;
21284d9c625SLionel Sambuc 	struct vattr	*pni_va;
21384d9c625SLionel Sambuc 	struct timespec	*pni_va_ttl;
21484d9c625SLionel Sambuc 	struct timespec	*pni_cn_ttl;
215490e0de5SThomas Veerman };
216490e0de5SThomas Veerman 
217490e0de5SThomas Veerman #define PUFFS_MAKEKCRED(to, from)					\
218490e0de5SThomas Veerman 	/*LINTED: tnilxnaht, the cast is ok */				\
219490e0de5SThomas Veerman 	const struct puffs_kcred *to = (const void *)from
220490e0de5SThomas Veerman #define PUFFS_MAKECRED(to, from)					\
221490e0de5SThomas Veerman 	/*LINTED: tnilxnaht, the cast is ok */				\
222490e0de5SThomas Veerman 	const struct puffs_cred *to = (const void *)from
223490e0de5SThomas Veerman #define PUFFS_KCREDTOCRED(to, from)					\
224490e0de5SThomas Veerman 	/*LINTED: tnilxnaht, the cast is ok */				\
225490e0de5SThomas Veerman 	to = (void *)from
226490e0de5SThomas Veerman 
227490e0de5SThomas Veerman __BEGIN_DECLS
228490e0de5SThomas Veerman 
229490e0de5SThomas Veerman void	puffs__framev_input(struct puffs_usermount *, struct puffs_framectrl *,
230490e0de5SThomas Veerman 			   struct puffs_fctrl_io *);
231490e0de5SThomas Veerman int	puffs__framev_output(struct puffs_usermount *, struct puffs_framectrl*,
232490e0de5SThomas Veerman 			    struct puffs_fctrl_io *);
233490e0de5SThomas Veerman void	puffs__framev_exit(struct puffs_usermount *);
234490e0de5SThomas Veerman void	puffs__framev_readclose(struct puffs_usermount *,
235490e0de5SThomas Veerman 			       struct puffs_fctrl_io *, int);
236490e0de5SThomas Veerman void	puffs__framev_writeclose(struct puffs_usermount *,
237490e0de5SThomas Veerman 				struct puffs_fctrl_io *, int);
238490e0de5SThomas Veerman void	puffs__framev_notify(struct puffs_fctrl_io *, int);
239490e0de5SThomas Veerman void	*puffs__framebuf_getdataptr(struct puffs_framebuf *);
240490e0de5SThomas Veerman int	puffs__framev_addfd_ctrl(struct puffs_usermount *, int, int,
241490e0de5SThomas Veerman 				 struct puffs_framectrl *);
242490e0de5SThomas Veerman void	puffs__framebuf_moveinfo(struct puffs_framebuf *,
243490e0de5SThomas Veerman 				 struct puffs_framebuf *);
244490e0de5SThomas Veerman 
245490e0de5SThomas Veerman void	puffs__theloop(struct puffs_cc *);
246490e0de5SThomas Veerman void	puffs__ml_dispatch(struct puffs_usermount *, struct puffs_framebuf *);
247490e0de5SThomas Veerman 
248490e0de5SThomas Veerman int	puffs__cc_create(struct puffs_usermount *, puffs_ccfunc,
249490e0de5SThomas Veerman 			 struct puffs_cc **);
250490e0de5SThomas Veerman void	puffs__cc_cont(struct puffs_cc *);
251490e0de5SThomas Veerman void	puffs__cc_destroy(struct puffs_cc *, int);
252490e0de5SThomas Veerman void	puffs__cc_setcaller(struct puffs_cc *, pid_t, lwpid_t);
253490e0de5SThomas Veerman void	puffs__goto(struct puffs_cc *);
254490e0de5SThomas Veerman int	puffs__cc_savemain(struct puffs_usermount *);
255490e0de5SThomas Veerman int	puffs__cc_restoremain(struct puffs_usermount *);
256490e0de5SThomas Veerman void	puffs__cc_exit(struct puffs_usermount *);
257490e0de5SThomas Veerman 
258490e0de5SThomas Veerman int	puffs__fsframe_read(struct puffs_usermount *, struct puffs_framebuf *,
259490e0de5SThomas Veerman 			    int, int *);
260490e0de5SThomas Veerman int	puffs__fsframe_write(struct puffs_usermount *, struct puffs_framebuf *,
261490e0de5SThomas Veerman 			    int, int *);
262490e0de5SThomas Veerman int	puffs__fsframe_cmp(struct puffs_usermount *, struct puffs_framebuf *,
263490e0de5SThomas Veerman 			   struct puffs_framebuf *, int *);
264490e0de5SThomas Veerman void	puffs__fsframe_gotframe(struct puffs_usermount *,
265490e0de5SThomas Veerman 			        struct puffs_framebuf *);
266490e0de5SThomas Veerman 
267ba736c79SDavid van Moolenbroek uint64_t	puffs__nextreq(struct puffs_usermount *pu);
268ba736c79SDavid van Moolenbroek 
269*0a6a1f1dSLionel Sambuc #if defined(__minix)
270ba736c79SDavid van Moolenbroek int lpuffs_pump(void);
271ba736c79SDavid van Moolenbroek void lpuffs_init(struct puffs_usermount *);
272ba736c79SDavid van Moolenbroek void lpuffs_debug(const char *format, ...)
273ba736c79SDavid van Moolenbroek 	__attribute__((__format__(__printf__, 1, 2)));
274*0a6a1f1dSLionel Sambuc #endif /* defined(__minix) */
275ba736c79SDavid van Moolenbroek 
276490e0de5SThomas Veerman __END_DECLS
277490e0de5SThomas Veerman 
278490e0de5SThomas Veerman #endif /* _PUFFS_PRIVATE_H_ */
279