summaryrefslogtreecommitdiff
path: root/lib/libpuffs/puffs_priv.h
blob: 8e08e79e7cfced7369cf5e8950a74ca45ea9d201 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/*	$NetBSD: puffs_priv.h,v 1.45 2012/04/18 00:57:22 manu Exp $	*/

/*
 * Copyright (c) 2006, 2007, 2008 Antti Kantee.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _PUFFS_PRIVATE_H_
#define _PUFFS_PRIVATE_H_

#include <sys/types.h>
#include <fs/puffs/puffs_msgif.h>

#if !defined(__minix)
#include <pthread.h>
#endif /* !defined(__minix) */
#include <puffs.h>
#include <ucontext.h>

#if !defined(__minix)
extern pthread_mutex_t pu_lock;
#define PU_LOCK() pthread_mutex_lock(&pu_lock)
#define PU_UNLOCK() pthread_mutex_unlock(&pu_lock)
#else
#define PU_LOCK() /* nothing */
#define PU_UNLOCK()  /* nothing */
#endif /* !defined(__minix) */

#define PU_CMAP(pu, c) (pu->pu_cmap ? pu->pu_cmap(pu,c) : (struct puffs_node*)c)

struct puffs_framectrl {
	puffs_framev_readframe_fn rfb;
	puffs_framev_writeframe_fn wfb;
	puffs_framev_cmpframe_fn cmpfb;
	puffs_framev_gotframe_fn gotfb;
	puffs_framev_fdnotify_fn fdnotfn;
};

struct puffs_fctrl_io {
	struct puffs_framectrl *fctrl;

	int io_fd;
	int stat;

	int rwait;
	int wwait;

	struct puffs_framebuf *cur_in;

	TAILQ_HEAD(, puffs_framebuf) snd_qing;	/* queueing to be sent */
	TAILQ_HEAD(, puffs_framebuf) res_qing;	/* q'ing for rescue */
	LIST_HEAD(, puffs_fbevent) ev_qing;	/* q'ing for events */

	LIST_ENTRY(puffs_fctrl_io) fio_entries;
};
#define FIO_WR		0x01
#define FIO_WRGONE	0x02
#define FIO_RDGONE	0x04
#define FIO_DEAD	0x08
#define FIO_ENABLE_R	0x10
#define FIO_ENABLE_W	0x20

#define FIO_EN_WRITE(fio)				\
    (!(fio->stat & FIO_WR)				\
      && ((!TAILQ_EMPTY(&fio->snd_qing)			\
            && (fio->stat & FIO_ENABLE_W))		\
         || fio->wwait))

#define FIO_RM_WRITE(fio)			\
    ((fio->stat & FIO_WR)			\
      && (((TAILQ_EMPTY(&fio->snd_qing)		\
        || (fio->stat & FIO_ENABLE_W) == 0))	\
	&& (fio->wwait == 0)))


/*
 * usermount: describes one file system instance
 */
struct puffs_usermount {
	struct puffs_ops	pu_ops;

	int			pu_fd;
	size_t			pu_maxreqlen;

	uint32_t		pu_flags;
	int			pu_cc_stackshift;

	ucontext_t		pu_mainctx;
#define PUFFS_CCMAXSTORE 32
	int			pu_cc_nstored;

	int			pu_kq;
	int			pu_state;
#define PU_STATEMASK	0x00ff
#define PU_INLOOP	0x0100
#define PU_ASYNCFD	0x0200
#define PU_HASKQ	0x0400
#define PU_PUFFSDAEMON	0x0800
#define PU_MAINRESTORE	0x1000
#define PU_DONEXIT	0x2000
#define PU_SETSTATE(pu, s) (pu->pu_state = (s) | (pu->pu_state & ~PU_STATEMASK))
#define PU_SETSFLAG(pu, s) (pu->pu_state |= (s))
#define PU_CLRSFLAG(pu, s) \
    (pu->pu_state = ((pu->pu_state & ~(s)) | (pu->pu_state & PU_STATEMASK)))
	int			pu_dpipe[2];

	struct puffs_node	*pu_pn_root;

	LIST_HEAD(, puffs_node)	pu_pnodelst;
#if defined(__minix)
	LIST_HEAD(, puffs_node)	pu_pnode_removed_lst;
#endif /* defined(__minix) */

	LIST_HEAD(, puffs_cc)	pu_ccmagazin;
	TAILQ_HEAD(, puffs_cc)	pu_lazyctx;
	TAILQ_HEAD(, puffs_cc)	pu_sched;

	pu_cmap_fn		pu_cmap;

	pu_pathbuild_fn		pu_pathbuild;
	pu_pathtransform_fn	pu_pathtransform;
	pu_pathcmp_fn		pu_pathcmp;
	pu_pathfree_fn		pu_pathfree;
	pu_namemod_fn		pu_namemod;

	pu_errnotify_fn		pu_errnotify;

	pu_prepost_fn		pu_oppre;
	pu_prepost_fn		pu_oppost;

	struct puffs_framectrl	pu_framectrl[2];
#define PU_FRAMECTRL_FS   0
#define PU_FRAMECTRL_USER 1
	LIST_HEAD(, puffs_fctrl_io) pu_ios;
	LIST_HEAD(, puffs_fctrl_io) pu_ios_rmlist;
	struct kevent		*pu_evs;
	size_t			pu_nevs;

	puffs_ml_loop_fn	pu_ml_lfn;
	struct timespec		pu_ml_timeout;
	struct timespec		*pu_ml_timep;

	struct puffs_kargs	*pu_kargp;

	uint64_t		pu_nextreq;
	void			*pu_privdata;
};

/* call context */

struct puffs_cc;
typedef void (*puffs_ccfunc)(struct puffs_cc *);

struct puffs_cc {
	struct puffs_usermount	*pcc_pu;
	struct puffs_framebuf	*pcc_pb;

	/* real cc */
	union {
		struct {
			ucontext_t	uc;		/* "continue"	*/
			ucontext_t	uc_ret;		/* "yield" 	*/
		} real;
		struct {
			puffs_ccfunc	func;
			void		*farg;
		} fake;
	} pcc_u;

	pid_t			pcc_pid;
	lwpid_t			pcc_lid;

	int			pcc_flags;

	TAILQ_ENTRY(puffs_cc)	pcc_schedent;
	LIST_ENTRY(puffs_cc)	pcc_rope;
};
#define pcc_uc		pcc_u.real.uc
#define pcc_uc_ret 	pcc_u.real.uc_ret
#define pcc_func	pcc_u.fake.func
#define pcc_farg	pcc_u.fake.farg
#define PCC_DONE	0x01
#define PCC_BORROWED	0x02
#define PCC_HASCALLER	0x04
#define PCC_MLCONT	0x08

struct puffs_newinfo {
	void		**pni_cookie;
	enum vtype	*pni_vtype;
	voff_t		*pni_size;
	dev_t		*pni_rdev;
	struct vattr	*pni_va;
	struct timespec	*pni_va_ttl;
	struct timespec	*pni_cn_ttl;
};

#define PUFFS_MAKEKCRED(to, from)					\
	/*LINTED: tnilxnaht, the cast is ok */				\
	const struct puffs_kcred *to = (const void *)from
#define PUFFS_MAKECRED(to, from)					\
	/*LINTED: tnilxnaht, the cast is ok */				\
	const struct puffs_cred *to = (const void *)from
#define PUFFS_KCREDTOCRED(to, from)					\
	/*LINTED: tnilxnaht, the cast is ok */				\
	to = (void *)from

__BEGIN_DECLS

void	puffs__framev_input(struct puffs_usermount *, struct puffs_framectrl *,
			   struct puffs_fctrl_io *);
int	puffs__framev_output(struct puffs_usermount *, struct puffs_framectrl*,
			    struct puffs_fctrl_io *);
void	puffs__framev_exit(struct puffs_usermount *);
void	puffs__framev_readclose(struct puffs_usermount *,
			       struct puffs_fctrl_io *, int);
void	puffs__framev_writeclose(struct puffs_usermount *,
				struct puffs_fctrl_io *, int);
void	puffs__framev_notify(struct puffs_fctrl_io *, int);
void	*puffs__framebuf_getdataptr(struct puffs_framebuf *);
int	puffs__framev_addfd_ctrl(struct puffs_usermount *, int, int,
				 struct puffs_framectrl *);
void	puffs__framebuf_moveinfo(struct puffs_framebuf *,
				 struct puffs_framebuf *);

void	puffs__theloop(struct puffs_cc *);
void	puffs__ml_dispatch(struct puffs_usermount *, struct puffs_framebuf *);

int	puffs__cc_create(struct puffs_usermount *, puffs_ccfunc,
			 struct puffs_cc **);
void	puffs__cc_cont(struct puffs_cc *);
void	puffs__cc_destroy(struct puffs_cc *, int);
void	puffs__cc_setcaller(struct puffs_cc *, pid_t, lwpid_t);
void	puffs__goto(struct puffs_cc *);
int	puffs__cc_savemain(struct puffs_usermount *);
int	puffs__cc_restoremain(struct puffs_usermount *);
void	puffs__cc_exit(struct puffs_usermount *);

int	puffs__fsframe_read(struct puffs_usermount *, struct puffs_framebuf *,
			    int, int *);
int	puffs__fsframe_write(struct puffs_usermount *, struct puffs_framebuf *,
			    int, int *);
int	puffs__fsframe_cmp(struct puffs_usermount *, struct puffs_framebuf *,
			   struct puffs_framebuf *, int *);
void	puffs__fsframe_gotframe(struct puffs_usermount *,
			        struct puffs_framebuf *);

uint64_t	puffs__nextreq(struct puffs_usermount *pu);

#if defined(__minix)
int lpuffs_pump(void);
void lpuffs_init(struct puffs_usermount *);
void lpuffs_debug(const char *format, ...)
	__attribute__((__format__(__printf__, 1, 2)));
#endif /* defined(__minix) */

__END_DECLS

#endif /* _PUFFS_PRIVATE_H_ */