 490e0de548
			
		
	
	
		490e0de548
		
	
	
	
	
		
			
			Import libpuffs and our port of libpuffs. The port was done as part of GSoC 2011 FUSE project, done by Evgeniy Ivanov. The librefuse import did not require any porting efforts. Libpuffs has been modified to understand our VFS-FS protocol and translate between that and PUFFS. As an example that it works, fuse-ntfs-3g from pkgsrc can be compiled and used to mount ntfs partitions: mount -t ntfs-3g <device> <mountpoint> FUSE only works with the asynchronous version of VFS. See <docs/UPDATING> on how to run AVFS. This patch further includes some changes to mount(1) and mount(2) so it's possible to use file systems provided by pkgsrc (note: manual modifications to /etc/system.conf are still needed. There has been made an exception for fuse-ntfs-3g, so it already as an entry).
		
			
				
	
	
		
			277 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*	$NetBSD: puffs_priv.h,v 1.41 2008/08/11 16:23:37 pooka 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 <ucontext.h>
 | |
| 
 | |
| /* FIXME: fs/puffs/puffs_msgif.h? */
 | |
| #include "puffs_msgif.h"
 | |
| #include "puffs.h"
 | |
| 
 | |
| /* XXX: MINIX */
 | |
| #define IGN_PERM            0
 | |
| #define CHK_PERM            1
 | |
| #define SU_UID          ((uid_t) 0)     /* super_user's uid_t */
 | |
| 
 | |
| /* XXX: MINIX */
 | |
| #define ATIME            002    /* set if atime field needs updating */
 | |
| #define CTIME            004    /* set if ctime field needs updating */
 | |
| #define MTIME            010    /* set if mtime field needs updating */
 | |
| 
 | |
| #define REQ_READ_SUPER   28
 | |
| 
 | |
| #ifdef PUFFS_WITH_THREADS
 | |
| #include <pthread.h>
 | |
| 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()
 | |
| #define PU_UNLOCK()
 | |
| #endif
 | |
| 
 | |
| #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_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;
 | |
| 	LIST_HEAD(, puffs_node)	pu_pnode_removed_lst;
 | |
| 
 | |
| 	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_nfds;
 | |
| 
 | |
| 	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;
 | |
| };
 | |
| 
 | |
| #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 *);
 | |
| 
 | |
| __END_DECLS
 | |
| 
 | |
| #define NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
 | |
| 
 | |
| #endif /* _PUFFS_PRIVATE_H_ */
 |