1 /*        $NetBSD: puffs_priv.h,v 1.46 2022/01/22 07:35:26 pho Exp $  */
2 
3 /*
4  * Copyright (c) 2006, 2007, 2008 Antti Kantee.  All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef _PUFFS_PRIVATE_H_
29 #define _PUFFS_PRIVATE_H_
30 
31 #include <sys/types.h>
32 #include <fs/puffs/puffs_msgif.h>
33 
34 #include <pthread.h>
35 #include <puffs.h>
36 #include <ucontext.h>
37 
38 extern pthread_mutex_t pu_lock;
39 #define PU_LOCK() pthread_mutex_lock(&pu_lock)
40 #define PU_UNLOCK() pthread_mutex_unlock(&pu_lock)
41 
42 #define PU_CMAP(pu, c) (pu->pu_cmap ? pu->pu_cmap(pu,c) : (struct puffs_node*)c)
43 
44 struct puffs_framectrl {
45           puffs_framev_readframe_fn rfb;
46           puffs_framev_writeframe_fn wfb;
47           puffs_framev_cmpframe_fn cmpfb;
48           puffs_framev_gotframe_fn gotfb;
49           puffs_framev_fdnotify_fn fdnotfn;
50 };
51 
52 struct puffs_fctrl_io {
53           struct puffs_framectrl *fctrl;
54 
55           int io_fd;
56           int stat;
57 
58           int rwait;
59           int wwait;
60 
61           struct puffs_framebuf *cur_in;
62 
63           TAILQ_HEAD(, puffs_framebuf) snd_qing;  /* queueing to be sent */
64           TAILQ_HEAD(, puffs_framebuf) res_qing;  /* q'ing for rescue */
65           LIST_HEAD(, puffs_fbevent) ev_qing;     /* q'ing for events */
66 
67           LIST_ENTRY(puffs_fctrl_io) fio_entries;
68 };
69 #define FIO_WR                0x01
70 #define FIO_WRGONE  0x02
71 #define FIO_RDGONE  0x04
72 #define FIO_DEAD    0x08
73 #define FIO_ENABLE_R          0x10
74 #define FIO_ENABLE_W          0x20
75 
76 #define FIO_EN_WRITE(fio)                                   \
77     (!(fio->stat & FIO_WR)                                  \
78       && ((!TAILQ_EMPTY(&fio->snd_qing)                     \
79             && (fio->stat & FIO_ENABLE_W))                  \
80          || fio->wwait))
81 
82 #define FIO_RM_WRITE(fio)                         \
83     ((fio->stat & FIO_WR)                         \
84       && (((TAILQ_EMPTY(&fio->snd_qing)           \
85         || (fio->stat & FIO_ENABLE_W) == 0))      \
86           && (fio->wwait == 0)))
87 
88 
89 /*
90  * usermount: describes one file system instance
91  */
92 struct puffs_usermount {
93           struct puffs_ops    pu_ops;
94 
95           int                           pu_fd;
96           size_t                        pu_maxreqlen;
97 
98           uint32_t            pu_flags;
99           int                           pu_cc_stackshift;
100 
101           ucontext_t                    pu_mainctx;
102 #define PUFFS_CCMAXSTORE 32
103           int                           pu_cc_nstored;
104 
105           int                           pu_kq;
106           int                           pu_state;
107 #define PU_STATEMASK          0x00ff
108 #define PU_INLOOP   0x0100
109 #define PU_ASYNCFD  0x0200
110 #define PU_HASKQ    0x0400
111 #define PU_PUFFSDAEMON        0x0800
112 #define PU_MAINRESTORE        0x1000
113 #define PU_DONEXIT  0x2000
114 #define PU_SETSTATE(pu, s) (pu->pu_state = (s) | (pu->pu_state & ~PU_STATEMASK))
115 #define PU_SETSFLAG(pu, s) (pu->pu_state |= (s))
116 #define PU_GETSFLAG(pu, s) (pu->pu_state & (s))
117 #define PU_CLRSFLAG(pu, s) \
118     (pu->pu_state = ((pu->pu_state & ~(s)) | (pu->pu_state & PU_STATEMASK)))
119           int                           pu_dpipe[2];
120 
121           struct puffs_node   *pu_pn_root;
122 
123           LIST_HEAD(, puffs_node)       pu_pnodelst;
124 
125           LIST_HEAD(, puffs_cc)         pu_ccmagazin;
126           TAILQ_HEAD(, puffs_cc)        pu_lazyctx;
127           TAILQ_HEAD(, puffs_cc)        pu_sched;
128 
129           pu_cmap_fn                    pu_cmap;
130 
131           pu_pathbuild_fn               pu_pathbuild;
132           pu_pathtransform_fn pu_pathtransform;
133           pu_pathcmp_fn                 pu_pathcmp;
134           pu_pathfree_fn                pu_pathfree;
135           pu_namemod_fn                 pu_namemod;
136 
137           pu_errnotify_fn               pu_errnotify;
138 
139           pu_prepost_fn                 pu_oppre;
140           pu_prepost_fn                 pu_oppost;
141 
142           struct puffs_framectrl        pu_framectrl[2];
143 #define PU_FRAMECTRL_FS   0
144 #define PU_FRAMECTRL_USER 1
145           LIST_HEAD(, puffs_fctrl_io) pu_ios;
146           LIST_HEAD(, puffs_fctrl_io) pu_ios_rmlist;
147           struct kevent                 *pu_evs;
148           size_t                        pu_nevs;
149 
150           puffs_ml_loop_fn    pu_ml_lfn;
151           struct timespec               pu_ml_timeout;
152           struct timespec               *pu_ml_timep;
153 
154           struct puffs_kargs  *pu_kargp;
155 
156           uint64_t            pu_nextreq;
157           void                          *pu_privdata;
158 };
159 
160 /* call context */
161 
162 struct puffs_cc;
163 typedef void (*puffs_ccfunc)(struct puffs_cc *);
164 
165 struct puffs_cc {
166           struct puffs_usermount        *pcc_pu;
167           struct puffs_framebuf         *pcc_pb;
168 
169           /* real cc */
170           union {
171                     struct {
172                               ucontext_t          uc;                 /* "continue"       */
173                               ucontext_t          uc_ret;             /* "yield"          */
174                     } real;
175                     struct {
176                               puffs_ccfunc        func;
177                               void                *farg;
178                     } fake;
179           } pcc_u;
180 
181           pid_t                         pcc_pid;
182           lwpid_t                       pcc_lid;
183 
184           int                           pcc_flags;
185 
186           TAILQ_ENTRY(puffs_cc)         pcc_schedent;
187           LIST_ENTRY(puffs_cc)          pcc_rope;
188 };
189 #define pcc_uc                pcc_u.real.uc
190 #define pcc_uc_ret  pcc_u.real.uc_ret
191 #define pcc_func    pcc_u.fake.func
192 #define pcc_farg    pcc_u.fake.farg
193 #define PCC_DONE    0x01
194 #define PCC_BORROWED          0x02
195 #define PCC_HASCALLER         0x04
196 #define PCC_MLCONT  0x08
197 
198 struct puffs_newinfo {
199           void                **pni_cookie;
200           enum vtype          *pni_vtype;
201           voff_t              *pni_size;
202           dev_t               *pni_rdev;
203           struct vattr        *pni_va;
204           struct timespec     *pni_va_ttl;
205           struct timespec     *pni_cn_ttl;
206 };
207 
208 #define PUFFS_MAKEKCRED(to, from)                                               \
209           /*LINTED: tnilxnaht, the cast is ok */                                \
210           const struct puffs_kcred *to = (const void *)from
211 #define PUFFS_MAKECRED(to, from)                                                \
212           /*LINTED: tnilxnaht, the cast is ok */                                \
213           const struct puffs_cred *to = (const void *)from
214 #define PUFFS_KCREDTOCRED(to, from)                                             \
215           /*LINTED: tnilxnaht, the cast is ok */                                \
216           to = (void *)from
217 
218 __BEGIN_DECLS
219 
220 void      puffs__framev_input(struct puffs_usermount *, struct puffs_framectrl *,
221                                  struct puffs_fctrl_io *);
222 int       puffs__framev_output(struct puffs_usermount *, struct puffs_framectrl*,
223                                   struct puffs_fctrl_io *);
224 void      puffs__framev_exit(struct puffs_usermount *);
225 void      puffs__framev_readclose(struct puffs_usermount *,
226                                      struct puffs_fctrl_io *, int);
227 void      puffs__framev_writeclose(struct puffs_usermount *,
228                                         struct puffs_fctrl_io *, int);
229 void      puffs__framev_notify(struct puffs_fctrl_io *, int);
230 void      *puffs__framebuf_getdataptr(struct puffs_framebuf *);
231 int       puffs__framev_addfd_ctrl(struct puffs_usermount *, int, int,
232                                          struct puffs_framectrl *);
233 void      puffs__framebuf_moveinfo(struct puffs_framebuf *,
234                                          struct puffs_framebuf *);
235 
236 void      puffs__theloop(struct puffs_cc *);
237 void      puffs__ml_dispatch(struct puffs_usermount *, struct puffs_framebuf *);
238 
239 int       puffs__cc_create(struct puffs_usermount *, puffs_ccfunc,
240                                struct puffs_cc **);
241 void      puffs__cc_cont(struct puffs_cc *);
242 void      puffs__cc_destroy(struct puffs_cc *, int);
243 void      puffs__cc_setcaller(struct puffs_cc *, pid_t, lwpid_t);
244 void      puffs__goto(struct puffs_cc *);
245 int       puffs__cc_savemain(struct puffs_usermount *);
246 int       puffs__cc_restoremain(struct puffs_usermount *);
247 void      puffs__cc_exit(struct puffs_usermount *);
248 
249 int       puffs__fsframe_read(struct puffs_usermount *, struct puffs_framebuf *,
250                                   int, int *);
251 int       puffs__fsframe_write(struct puffs_usermount *, struct puffs_framebuf *,
252                                   int, int *);
253 int       puffs__fsframe_cmp(struct puffs_usermount *, struct puffs_framebuf *,
254                                  struct puffs_framebuf *, int *);
255 void      puffs__fsframe_gotframe(struct puffs_usermount *,
256                                       struct puffs_framebuf *);
257 
258 uint64_t  puffs__nextreq(struct puffs_usermount *pu);
259 
260 __END_DECLS
261 
262 #endif /* _PUFFS_PRIVATE_H_ */
263