Home | History | Annotate | Line # | Download | only in puffs
      1 /*	$NetBSD: puffs_sys.h,v 1.91 2019/01/27 02:08:43 pgoyette 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/select.h>
     37 #include <sys/kauth.h>
     38 #include <sys/mutex.h>
     39 #include <sys/queue.h>
     40 #include <sys/pool.h>
     41 
     42 #include <fs/puffs/puffs_msgif.h>
     43 
     44 #include <miscfs/genfs/genfs_node.h>
     45 
     46 extern int (**puffs_vnodeop_p)(void *);
     47 extern int (**puffs_specop_p)(void *);
     48 extern int (**puffs_fifoop_p)(void *);
     49 
     50 extern const struct vnodeopv_desc puffs_vnodeop_opv_desc;
     51 extern const struct vnodeopv_desc puffs_specop_opv_desc;
     52 extern const struct vnodeopv_desc puffs_fifoop_opv_desc;
     53 extern const struct vnodeopv_desc puffs_msgop_opv_desc;
     54 
     55 extern struct pool puffs_pnpool;
     56 extern struct pool puffs_vapool;
     57 
     58 #ifdef DEBUG
     59 #ifndef PUFFSDEBUG
     60 #define PUFFSDEBUG
     61 #endif
     62 #endif
     63 
     64 #ifdef PUFFSDEBUG
     65 extern int puffsdebug; /* puffs_subr.c */
     66 #define DPRINTF(x) do { \
     67 		if (puffsdebug > 0) printf x; \
     68 	} while (/*CONSTCOND*/0)
     69 #define DPRINTF_VERBOSE(x) do { \
     70 		if (puffsdebug > 1) printf x; \
     71 	} while (/*CONSTCOND*/0)
     72 #else
     73 #define DPRINTF(x) ((void)0)
     74 #define DPRINTF_VERBOSE(x) ((void)0)
     75 #endif
     76 
     77 #define MPTOPUFFSMP(mp) ((struct puffs_mount *)((mp)->mnt_data))
     78 #define PMPTOMP(pmp) (pmp->pmp_mp)
     79 #define VPTOPP(vp) ((struct puffs_node *)(vp)->v_data)
     80 #define VPTOPNC(vp) (((struct puffs_node *)(vp)->v_data)->pn_cookie)
     81 #define VPTOPUFFSMP(vp) ((struct puffs_mount*)((struct puffs_node*)vp->v_data))
     82 
     83 /* we don't pass the kernel overlay to userspace */
     84 #define PUFFS_TOFHSIZE(s) ((s)==0 ? (s) : (s)+4)
     85 #define PUFFS_FROMFHSIZE(s) ((s)==0 ? (s) : (s)-4)
     86 
     87 #define ALLOPS(pmp) (pmp->pmp_flags & PUFFS_KFLAG_ALLOPS)
     88 #define EXISTSOP(pmp, op) \
     89  (ALLOPS(pmp) || ((pmp)->pmp_vnopmask[PUFFS_VN_##op]))
     90 
     91 #define PUFFS_USE_NAMECACHE(pmp)	\
     92     (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_NAME) == 0)
     93 #define PUFFS_USE_PAGECACHE(pmp)	\
     94     (((pmp)->pmp_flags & PUFFS_KFLAG_NOCACHE_PAGE) == 0)
     95 #define PUFFS_USE_FULLPNBUF(pmp)	\
     96     ((pmp)->pmp_flags & PUFFS_KFLAG_LOOKUP_FULLPNBUF)
     97 #define PUFFS_USE_FS_TTL(pmp)	\
     98     ((pmp)->pmp_flags & PUFFS_KFLAG_CACHE_FS_TTL)
     99 #define PUFFS_USE_DOTDOTCACHE(pmp)	\
    100     ((pmp)->pmp_flags & PUFFS_KFLAG_CACHE_DOTDOT)
    101 #define PUFFS_USE_METAFLUSH(pmp)	\
    102     (((pmp)->pmp_flags & PUFFS_KFLAG_NOFLUSH_META) == 0)
    103 
    104 #define PUFFS_WCACHEINFO(pmp)	(__USE(pmp), 0)
    105 
    106 struct puffs_newcookie {
    107 	puffs_cookie_t	pnc_cookie;
    108 
    109 	LIST_ENTRY(puffs_newcookie) pnc_entries;
    110 };
    111 
    112 #define PUFFS_SOPREQ_EXPIRE_TIMEOUT 1000
    113 extern int puffs_sopreq_expire_timeout;
    114 
    115 enum puffs_sopreqtype {
    116 	PUFFS_SOPREQSYS_EXIT,
    117 	PUFFS_SOPREQ_FLUSH,
    118 	PUFFS_SOPREQ_UNMOUNT,
    119 	PUFFS_SOPREQ_EXPIRE,
    120 };
    121 
    122 struct puffs_sopreq {
    123 	union {
    124 		struct puffs_req preq;
    125 		struct puffs_flush pf;
    126 		puffs_cookie_t ck;
    127 	} psopr_u;
    128 
    129 	enum puffs_sopreqtype psopr_sopreq;
    130 	TAILQ_ENTRY(puffs_sopreq) psopr_entries;
    131 	int psopr_at;
    132 };
    133 #define psopr_preq psopr_u.preq
    134 #define psopr_pf psopr_u.pf
    135 #define psopr_ck psopr_u.ck
    136 
    137 TAILQ_HEAD(puffs_wq, puffs_msgpark);
    138 LIST_HEAD(puffs_node_hashlist, puffs_node);
    139 struct puffs_mount {
    140 	kmutex_t	 		pmp_lock;
    141 
    142 	struct puffs_kargs		pmp_args;
    143 #define pmp_flags pmp_args.pa_flags
    144 #define pmp_vnopmask pmp_args.pa_vnopmask
    145 
    146 	struct puffs_wq			pmp_msg_touser;
    147 	int				pmp_msg_touser_count;
    148 	kcondvar_t			pmp_msg_waiter_cv;
    149 	size_t				pmp_msg_maxsize;
    150 
    151 	struct puffs_wq			pmp_msg_replywait;
    152 
    153 	struct mount			*pmp_mp;
    154 
    155 	struct vnode			*pmp_root;
    156 	puffs_cookie_t			pmp_root_cookie;
    157 	enum vtype			pmp_root_vtype;
    158 	vsize_t				pmp_root_vsize;
    159 	dev_t				pmp_root_rdev;
    160 
    161 	struct putter_instance		*pmp_pi;
    162 
    163 	unsigned int			pmp_refcount;
    164 	kcondvar_t			pmp_refcount_cv;
    165 
    166 	kcondvar_t			pmp_unmounting_cv;
    167 	uint8_t				pmp_unmounting;
    168 
    169 	uint8_t				pmp_status;
    170 	uint8_t				pmp_suspend;
    171 
    172 	uint8_t				*pmp_curput;
    173 	size_t				pmp_curres;
    174 	void				*pmp_curopaq;
    175 
    176 	uint64_t			pmp_nextmsgid;
    177 
    178 	kmutex_t			pmp_sopmtx;
    179 	kcondvar_t			pmp_sopcv;
    180 	int				pmp_sopthrcount;
    181 	TAILQ_HEAD(, puffs_sopreq)	pmp_sopfastreqs;
    182 	TAILQ_HEAD(, puffs_sopreq)	pmp_sopnodereqs;
    183 	bool				pmp_docompat;
    184 };
    185 
    186 #define PUFFSTAT_BEFOREINIT	0
    187 #define PUFFSTAT_MOUNTING	1
    188 #define PUFFSTAT_RUNNING	2
    189 #define PUFFSTAT_DYING		3 /* Do you want your possessions identified? */
    190 
    191 
    192 #define PNODE_NOREFS	0x001	/* no backend reference			*/
    193 #define PNODE_DYING	0x002	/* NOREFS + inactive			*/
    194 #define PNODE_FAF	0x004	/* issue all operations as FAF		*/
    195 #define PNODE_DOINACT 	0x008	/* if inactive-on-demand, call inactive */
    196 #define PNODE_SOPEXP	0x100	/* Node reclaim postponed in sop thread	*/
    197 #define PNODE_RDIRECT	0x200	/* bypass page cache on read		*/
    198 #define PNODE_WDIRECT	0x400	/* bypass page cache on write		*/
    199 
    200 #define PNODE_METACACHE_ATIME	0x10	/* cache atime metadata */
    201 #define PNODE_METACACHE_CTIME	0x20	/* cache atime metadata */
    202 #define PNODE_METACACHE_MTIME	0x40	/* cache atime metadata */
    203 #define PNODE_METACACHE_SIZE	0x80	/* cache atime metadata */
    204 #define PNODE_METACACHE_MASK	0xf0
    205 
    206 struct puffs_node {
    207 	struct genfs_node pn_gnode;	/* genfs glue			*/
    208 
    209 	kmutex_t	pn_mtx;
    210 	int		pn_refcount;
    211 	int		pn_nlookup;
    212 
    213 	puffs_cookie_t	pn_cookie;	/* userspace pnode cookie	*/
    214 	struct vnode	*pn_vp;		/* backpointer to vnode		*/
    215 	uint32_t	pn_stat;	/* node status			*/
    216 
    217 	struct selinfo	pn_sel;		/* for selecting on the node	*/
    218 	short		pn_revents;	/* available events		*/
    219 
    220 	/* metacache */
    221 	struct timespec	pn_mc_atime;
    222 	struct timespec	pn_mc_ctime;
    223 	struct timespec	pn_mc_mtime;
    224 	u_quad_t	pn_mc_size;
    225 
    226 	voff_t		pn_serversize;
    227 
    228 	struct lockf *	pn_lockf;
    229 
    230 	kmutex_t	pn_sizemtx;	/* size modification mutex	*/
    231 
    232 	int		pn_cn_timeout;	/* path cache */
    233 	int		pn_cn_grace;	/* grace time before reclaim */
    234 	int		pn_va_timeout;	/* attribute cache */
    235 	struct vattr *	pn_va_cache;	/* attribute cache */
    236 	struct vnode *  pn_parent;	/* parent cache */
    237 };
    238 
    239 typedef void (*parkdone_fn)(struct puffs_mount *, struct puffs_req *, void *);
    240 
    241 struct puffs_msgpark;
    242 void	puffs_msgif_init(void);
    243 void	puffs_msgif_destroy(void);
    244 int	puffs_msgmem_alloc(size_t, struct puffs_msgpark **, void **, int);
    245 void	puffs_msgmem_release(struct puffs_msgpark *);
    246 
    247 void	puffs_sop_thread(void *);
    248 
    249 void	puffs_msg_setfaf(struct puffs_msgpark *);
    250 void	puffs_msg_setdelta(struct puffs_msgpark *, size_t);
    251 void	puffs_msg_setinfo(struct puffs_msgpark *, int, int, puffs_cookie_t);
    252 void	puffs_msg_setcall(struct puffs_msgpark *, parkdone_fn, void *);
    253 
    254 void	puffs_msg_enqueue(struct puffs_mount *, struct puffs_msgpark *);
    255 int	puffs_msg_wait(struct puffs_mount *, struct puffs_msgpark *);
    256 int	puffs_msg_wait2(struct puffs_mount *, struct puffs_msgpark *,
    257 			struct puffs_node *, struct puffs_node *);
    258 
    259 void	puffs_msg_sendresp(struct puffs_mount *, struct puffs_req *, int);
    260 
    261 int	puffs_getvnode(struct mount *, puffs_cookie_t, enum vtype,
    262 		       voff_t, dev_t, struct vnode **);
    263 int	puffs_newnode(struct mount *, struct vnode *, struct vnode **,
    264 		      puffs_cookie_t, struct componentname *,
    265 		      enum vtype, dev_t);
    266 void	puffs_putvnode(struct vnode *);
    267 
    268 void	puffs_releasenode(struct puffs_node *);
    269 void	puffs_referencenode(struct puffs_node *);
    270 
    271 #define PUFFS_NOSUCHCOOKIE (-1)
    272 int	puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t,
    273 			   struct vnode **);
    274 void	puffs_makecn(struct puffs_kcn *, struct puffs_kcred *,
    275 		     const struct componentname *, int);
    276 void	puffs_credcvt(struct puffs_kcred *, kauth_cred_t);
    277 
    278 void	puffs_parkdone_asyncbioread(struct puffs_mount *,
    279 				    struct puffs_req *, void *);
    280 void	puffs_parkdone_asyncbiowrite(struct puffs_mount *,
    281 				     struct puffs_req *, void *);
    282 void	puffs_parkdone_poll(struct puffs_mount *, struct puffs_req *, void *);
    283 
    284 void	puffs_mp_reference(struct puffs_mount *);
    285 void	puffs_mp_release(struct puffs_mount *);
    286 
    287 void	puffs_gop_size(struct vnode *, off_t, off_t *, int);
    288 void	puffs_gop_markupdate(struct vnode *, int);
    289 
    290 void	puffs_senderr(struct puffs_mount *, int, int, const char *,
    291 		      puffs_cookie_t);
    292 
    293 int	puffs_compat_outgoing(struct puffs_req *, struct puffs_req**, ssize_t*);
    294 void	puffs_compat_incoming(struct puffs_req *, struct puffs_req *);
    295 
    296 void	puffs_updatenode(struct puffs_node *, int, voff_t);
    297 #define PUFFS_UPDATEATIME	0x01
    298 #define PUFFS_UPDATECTIME	0x02
    299 #define PUFFS_UPDATEMTIME	0x04
    300 #define PUFFS_UPDATESIZE	0x08
    301 
    302 void	puffs_userdead(struct puffs_mount *);
    303 
    304 extern int (**puffs_vnodeop_p)(void *);
    305 
    306 /* for putter */
    307 int	puffs_msgif_getout(void *, size_t, int, uint8_t **, size_t *, void **);
    308 void	puffs_msgif_releaseout(void *, void *, int);
    309 int	puffs_msgif_dispatch(void *, struct putter_hdr *);
    310 size_t	puffs_msgif_waitcount(void *);
    311 int	puffs_msgif_close(void *);
    312 
    313 static __inline int
    314 checkerr(struct puffs_mount *pmp, int error, const char *str)
    315 {
    316 
    317 	if (error < 0 || error > ELAST) {
    318 		puffs_senderr(pmp, PUFFS_ERR_ERROR, error, str, NULL);
    319 		error = EPROTO;
    320 	}
    321 
    322 	return error;
    323 }
    324 
    325 #define PUFFS_MSG_VARS(type, a)						\
    326 	struct puffs_##type##msg_##a *a##_msg;				\
    327 	struct puffs_msgpark *park_##a = NULL
    328 
    329 #define PUFFS_MSG_ALLOC(type, a)					\
    330 	puffs_msgmem_alloc(sizeof(struct puffs_##type##msg_##a),	\
    331 	    &park_##a, (void *)& a##_msg, 1)
    332 
    333 #define PUFFS_MSG_RELEASE(a) 						\
    334 do {									\
    335 	if (park_##a) puffs_msgmem_release(park_##a);			\
    336 } while (/*CONSTCOND*/0)
    337 
    338 #define PUFFS_MSG_ENQUEUEWAIT_NOERROR(pmp, park)			\
    339 do {									\
    340 	puffs_msg_enqueue(pmp, park);					\
    341 	puffs_msg_wait(pmp, park);					\
    342 } while (/*CONSTCOND*/0)
    343 
    344 #define PUFFS_MSG_ENQUEUEWAIT2_NOERROR(pmp, park, vp1, vp2)		\
    345 do {									\
    346 	puffs_msg_enqueue(pmp, park);					\
    347 	puffs_msg_wait2(pmp, park, vp1, vp2);				\
    348 } while (/*CONSTCOND*/0)
    349 
    350 #define PUFFS_MSG_ENQUEUEWAIT(pmp, park, var)				\
    351 do {									\
    352 	puffs_msg_enqueue(pmp, park);					\
    353 	var = puffs_msg_wait(pmp, park);				\
    354 } while (/*CONSTCOND*/0)
    355 
    356 #define PUFFS_MSG_ENQUEUEWAIT2(pmp, park, vp1, vp2, var)		\
    357 do {									\
    358 	puffs_msg_enqueue(pmp, park);					\
    359 	var = puffs_msg_wait2(pmp, park, vp1, vp2);			\
    360 } while (/*CONSTCOND*/0)
    361 
    362 /*
    363  * compat50 init/fini
    364  */
    365 
    366 void puffs_50_init(void);
    367 void puffs_50_fini(void);
    368 
    369 #endif /* _PUFFS_SYS_H_ */
    370