Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Sep 2005 17:08:14 GMT
From:      soc-chenk <soc-chenk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 83408 for review
Message-ID:  <200509111708.j8BH8E3c060295@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=83408

Change 83408 by soc-chenk@soc-chenk_leavemealone on 2005/09/11 17:07:48

	Code state tagged as "version 0.01.1

Affected files ...

.. //depot/projects/soc2005/fuse4bsd2/COPYRIGHT#1 add
.. //depot/projects/soc2005/fuse4bsd2/Changelog#1 add
.. //depot/projects/soc2005/fuse4bsd2/README#2 edit
.. //depot/projects/soc2005/fuse4bsd2/fuse_module/Makefile#2 edit
.. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#2 edit
.. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse_subr.c#1 add
.. //depot/projects/soc2005/fuse4bsd2/mount_fusefs/mount_fusefs.c#2 edit

Differences ...

==== //depot/projects/soc2005/fuse4bsd2/README#2 (text+ko) ====

@@ -1,21 +1,162 @@
-This is a FreeBSD kernel module to support the Fuse userspace virtual
-filesystem framework (http://fuse.sourceforge.net).
+Fuse module for FreeBSD.
+
+Fuse is an userspace filesystem framework, originally for Linux,
+see http://fuse.sourceforge.net.
+
+This distributions contains a port of Fuse to FreeBSD.
+
+Mainly this consists of writing a compatible kernel module for FreeBSD.
+The userspace part is pretty portable. You'll find here a patch to get
+that compiled, and brief instruvctions to get that running.
+
+The module was written for and tested with CURRENT, aka FreeBSD-7.0.
+I'd guess it will work fine with RELENG 6 too, but currently its not usable
+with 5.x (or lower) versions.
+
+Waht can be considered as a public homepage for the project is 
+
+   http://wikitest.freebsd.org/moin.cgi/FuseFilesystem
+
+see updtates, further info there. Get in contact with me at
+soc-chenk@freebsd.org.
+
+Installation
+
+I'll describe here the installation of the core Fuse components and a Fuse
+based filesystem, sshfs, which lets you mount a machine remotely by means
+of an ssh conncetion.
+
+I'll describe a non-privileged installation.
+
+Downloads
+
+You need to get a bunch of things.
+
+  * Fuse itself. Get Fuse 2.4.0-pre1 from their homepage, 
+      http://fuse.sourceforge.net
+
+  * This module. The latest version is available via Darcs, you can fetch it by
+    the 
+
+      darcs get http://creo.hu/~csaba/darcs-repos/fuse4bsd
+
+    command. These instructions are appropriate for the version in place (with
+    which this README ships).
+
+  * Fuse sshfs. The latest release (1.2) will do, fetch the sshfs-fuse package from
+    [WWW]http://sourceforge.net/projects/fuse.
+
+Compilation
+
+Let's start with the module.
+
+  * From your Fuse distribuiton copy over kernel/fuse_kernel.h as
+    fuse_module/fuse_kernel.h.orig.
+
+  * Type make. If you want normal quantity of debug output, use
+    DEBUG2G=1, if you want tons of debug output, use DEBUG=1.
+
+Now go for the fuse userspace.
+
+  * We will assume that you have my module at ../fuse4bsd
+
+  * Apply the patch with
+
+     patch -Np1 < ../fuse4bsd/fuselib/fuselib-2.4.0-pre1.diff
+
+  * Do
+
+     cp ../fuse4bsd/fuselib/fusermount.c util/ &&
+     cp ../fuse4bsd/fuse_module/fuse_kernel.h include/ &&
+     cp ../fuse4bsd/fuse_module/linux_compat.h include/
+
+    (the first command replaces fusermount.c with a trimmed down version
+    without the mount support code, and the other two dynamically customize the
+    header file defining the kernel-userland interface; as these are needed in
+    the module as well, they are handled separately from the userspace patch).
+
+  * We will do a non-privileged install, I'll use ~/meta/fuse-2.4.0-pre1 as the
+    prefix. Configure fuse with
+
+     /configure --prefix ~/meta/fuse-2.4.0-pre1 --disable-kernel-module MOUNT_FUSE_PATH=/tmp
+
+  * Now type
+
+     make &&
+     ln -s /usr/bin/true chown &&
+     ln -s /usr/bin/true mknod &&
+     ln -s /usr/bin/true chmod &&
+     env PATH=`pwd`:$PATH make install
+
+
+You have successfully installed fuse libs. Go on to sshfs.
+
+  * Edit sshfs.c: add a #include <sys/socket.h> line to its includes.
+
+  * Type
+      env PKG_CONFIG_PATH=~/meta/fuse-2.4.0-pre1/lib/pkgconfig/ ./configure &&
+      make
+
+Congratulations, you have all components prepared!
+
+In the following, you'll need to act as superuser, or enable the vfs.usermount 
+sysctl. 
+
+First, of course, load fuse_module/fuse.ko (for this you definitely need to be a
+superuser). 
+
+Then pick your favourite ssh accessible account (though maybe you'd better
+stick to servers running OpenSSH -- I've seen commits in sshfs' CVS for better
+interoperability with other servers, which show there might occur problems with
+them), say, it's foo@bar.baz.
+
+Firing up a Fuse daemon
+
+... sshfs, more concretely.
+
+Go to sshfs' directory. Type something along the following line:
+
+env PATH=$PATH:~csaba/meta/fuse-2.4.0-pre1/bin/ \
+ LD_LIBRARY_PATH=~csaba/meta/fuse-2.4.0-pre1/lib/ \
+ ./sshfs foo@bar.baz / -d
+
+Note that common Fuse arguments include the mountpoint -- in our case, that's
+just ignored, but required nevertheless --, and "-d" which doesn't let the
+daemon fork to background and enables debug messages.
+
+Mounting a Fuse filesystem
+
+Mounting is nnpfs style, in contrast to Linux Fuse style.
+
+In Linux, when you start a Fuse daemon, it first connects to the (unique) Fuse
+device, and then calls the mount system call with the appropriate parameters,
+so as a user, you can't separate the stages of Fuse mounting.
+
+In FreeBSD, you first start the daemon as above, then it gets a shiny fresh new
+dedicated fuse device (like /dev/fuse0), and you have to do the mounting
+manually, like
+
+mount_fusefs /dev/fuse0 /mnt/fuse
+
+(Find mount_fusefs in the mount_fusefs/ subdir of the fuse4bsd source tree.
+If you run it without arguments, it prints the available options.)
+
+You can ask: how to find out the device number? If you start your first daemon,
+by all chance it will be /dev/fuse0. But in general, you can do a fstat /dev/
+fuse* to see which device is in use.
 
-It's not yet ready, but you can test those parts which has already been
-completed.
+If you mounted it successfully, you can use the filesystem.
 
-See http://wikitest.freebsd.org/moin.cgi/FuseFilesystem for more info.
+It supports common POSIX fucntionality (mmap is read-only).
 
-Some of the stuff needed for compiling the userspace component for
-FreeBSD (those ones namely which don't require active development, just
-synchronization with Fuse sources from time to time) are available from
+When you finished, umount it with the "-f" siwtch.
 
-http://creo.hu/~csaba/projects/fuse4bsd
+It's a bug that you have to use that, but harmless... in the 95%
+percent of cases. If you had intensive I/O which has been interrupted,
+then there will remain dirty buffers, and in this case forced umount
+may result in a panic.
 
-The latest version of this module is available from the FreeBSD Perforce
-server (htpp://perforce.freebsd.org) at the path 
-//depot/projects/soc2005/fuse4bsd/, and by Darcs, via the
+Any feedbakc is highly welcome.
 
-darcs get http://creo.hu/~csaba/darcs-repos/fuse4bsd
+Csaba Henk
 
-command. 

==== //depot/projects/soc2005/fuse4bsd2/fuse_module/Makefile#2 (text+ko) ====

@@ -1,4 +1,4 @@
-SRCS=fuse.c
+SRCS=fuse.c fuse_subr.c
 
 .if defined(FMASTER)
 SRCS+= fmaster.c

==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#2 (text+ko) ====

@@ -21,7 +21,6 @@
 #include <sys/stat.h>
 #include <sys/unistd.h> /* pathconf */
 #include <sys/filedesc.h> /* open */
-//#include <sys/ucred.h> /* open */
 #include <sys/file.h> /* open */
 #include <sys/fcntl.h> /* open */
 #include <sys/dirent.h> /* readdir */
@@ -32,13 +31,7 @@
 #include <vm/vm_extern.h>  
 #include <vm/vnode_pager.h>
 
-//#include <vm/vnode_pager.h>
 #include <vm/vm_object.h>
-//#include <vm/vm_page.h>
-//#include <vm/vm_pager.h>
-//#include <vm/vm_map.h>
-//#include <vm/vnode_pager.h>
-//extern int vnode_pbuf_freecnt;
 
 #include "fuse.h"
 
@@ -1186,7 +1179,7 @@
 	if (! fdip->tick)	
 		fdip->tick = ticket_fetch(fdip->data);
 
-	FUSE_DIMALLOC2(&fdip->tick->msgn.msg, fdip->finh, fdip->indata, fdip->iosize);
+	FUSE_DIMALLOC(&fdip->tick->msgn.msg, fdip->finh, fdip->indata, fdip->iosize);
 	fuse_setup_ihead(fdip->finh, fdip->tick, nid, op, td, cred);
 }
 
@@ -1353,6 +1346,11 @@
 	int err = 0;
 
 	DEBUG("sending FORGET with %llu lookups\n", nlookup);
+#if 0 & _DEBUG2G
+	DEBUG2G("=============>\n");
+	kdb_backtrace();
+	DEBUG2G("<=============\n");
+#endif
 	fdip->iosize = sizeof(*ffi);
 
 	if (fdip->tick) {
@@ -1457,6 +1455,7 @@
 	.vfs_root    = fuse_root,
 	.vfs_statfs  = fuse_statfs,
 	//.vfs_vget    = fuse_vget,
+	//.vfs_sync    = vfs_stdsync,
 };
 
 #if __FreeBSD_version >= 600000
@@ -1623,9 +1622,24 @@
 		return (ENXIO);
 	}
 
-	MALLOC(fmnt, struct fuse_mnt_data *, sizeof(*fmnt), M_FUSEFS, M_WAITOK);
+	MALLOC(fmnt, struct fuse_mnt_data *, sizeof(*fmnt), M_FUSEFS, M_WAITOK| M_ZERO);
 	fmnt->fdev = fdev;
 
+	vfs_flagopt(opts, "allow_other", &fmnt->mntopts, FUSEFS_DAEMON_CAN_SPY); 
+	if (fmnt->mntopts & FUSEFS_DAEMON_CAN_SPY && suser(td)) {
+		uprintf("only root can use \"allow_other\"\n");
+		free(fmnt, M_FUSEFS);
+		return (EPERM);
+	}
+	vfs_flagopt(opts, "direct_io", &fmnt->mntopts, FUSEFS_DIRECTIO); 
+	vfs_flagopt(opts, "kernel_cache", &fmnt->mntopts, FUSEFS_KEEPCACHE); 
+#if ! REALTIME_TRACK_UNPRIVPROCDBG
+	fmnt->mntopts &= ~FUSEFS_UNPRIVPROCDBG;
+	fmnt->mntopts |= get_unprivileged_proc_debug(td) ? FUSEFS_UNPRIVPROCDBG : 0;
+#endif
+
+	DEBUG2G("mntopts 0x%x\n", fmnt->mntopts);
+
 	sx_slock(slock);
 
 	/* Sanity + permission checks */ 
@@ -1644,7 +1658,7 @@
 	}
 
 	if ((! err) && suser(td)) {
-		if (td->td_ucred->cr_ruid != data->daemoncred->cr_ruid) {
+		if (td->td_ucred->cr_uid != data->daemoncred->cr_uid) {
 			err = EPERM;
 			uprintf("attempt to mount other user's daemon\n");
 		}
@@ -1729,7 +1743,10 @@
 		flags |= FORCECLOSE;
 
 #if _DEBUG
-	vn_printf(((struct fuse_mnt_data *)mp->mnt_data)->rvp, DEBLABEL "root node before execution\n");
+	//vn_printf(((struct fuse_mnt_data *)mp->mnt_data)->rvp, DEBLABEL "root node before execution\n");
+	DEBUG2G("=============>\n");
+	kdb_backtrace();
+	DEBUG2G("<=============\n");
 #endif
 	/* Flush files -> vflush */
 	/* There is 1 extra root vnode reference (mp->mnt_data). */
@@ -1890,6 +1907,7 @@
 }
 
 
+
 /******************
  *
  * >>> Vnode ops
@@ -1990,6 +2008,12 @@
 	struct thread *td = ap->a_td;
 
 	DEBUG("pfft...\n");
+#if _DEBUG
+	DEBUG2G("=============>\n");
+	kdb_backtrace();
+	vn_printf(vp, " ");
+	DEBUG2G("<=============\n");
+#endif
 	fuse_filehandle_gc(vp, td, NULL);		
 	vnode_destroy_vobject(vp);
 	return (fuse_recyc_backend(vp, td));
@@ -2004,6 +2028,12 @@
 	int err;
 
 	DEBUG("getting at vnode of ino %d\n", VTOI(vp));
+#if _DEBUG
+	DEBUG2G("=============>\n");
+	kdb_backtrace();
+	vn_printf(vp, " ");
+	DEBUG2G("<=============\n");
+#endif
 
 	fuse_filehandle_gc(vp, td, NULL);		
 
@@ -2107,37 +2137,43 @@
 	struct ucred *cred = ap->a_cred;
 	struct thread *td = ap->a_td;
 
+	struct fuse_mnt_data *fmnt = vp->v_mount->mnt_data;
 	struct fuse_dispatcher fdi;
 	int err = 0;
 
 	if ((err = fdisp_simple_putget(&fdi, FUSE_GETATTR, vp, td, cred)))
 		return (err);
 
-
-
 	 /* XXX we discard timeout related info,
  	  * just go for the attributes */
 	fat2vat(vp->v_mount, &((struct fuse_attr_out *)fdi.answ)->attr, vap);
 	
 	ticket_drop(fdi.tick);
 
-#if ! DAEMON_CAN_SPY
-	/* The default policy is to forbid a user from using the filesystem,
-	 * if she is *more* privileged than the daemon. This is to protect
-	 * the power user from the daemon spying on her I/O operations.
-	 * Yes, it is a crude and blunt protection...
-	 * XXX there should be a sysctl interface to this. Ideally not just a
-	 * "daemon can spy bit", but some clever data which determines in a
-	 * compact but flexible way whose daemon can spy on whom.
-	 */
+	if (! (fmnt->mntopts & FUSEFS_DAEMON_CAN_SPY)) {
+		/* The policy is to forbid a user from using the filesystem,
+		 * if she is *more* privileged than the daemon. This is to protect
+		 * the power user from the daemon spying on her I/O operations.
+		 * Yes, it is a crude and blunt protection...
+		 * XXX there should be a sysctl interface to this. Ideally not just a
+		 * "daemon can spy bit", but some clever data which determines in a
+		 * compact but flexible way whose daemon can spy on whom.
+		 */
 
-	if (cr_cansee(fusedev_get_data(fdi.fdev)->daemoncred, cred)) {
-		sx_sunlock(fdi.slock);
-		uprintf("Your access is blocked in order to prevent the fuse daemon spying on you\n");
-		return (EPERM);
+		//DEBUG2G("mntopts 0x%x\n", ((struct fuse_mnt_data *)vp->v_mount->mnt_data)->mntopts);	
+		if (cr_candebug(
+#if REALTIME_TRACK_UNPRIVPROCDBG
+		                get_unprivileged_proc_debug(td),
+#else
+				((struct fuse_mnt_data *)vp->v_mount->mnt_data)->mntopts & FUSEFS_UNPRIVPROCDBG, 
+#endif
+		                fusedev_get_data(fdi.fdev)->daemoncred, cred))
+		{
+			sx_sunlock(fdi.slock);
+			uprintf("Your access is blocked in order to prevent the fuse daemon spying on you\n (consider mounting with \"allow_other\")\n");
+			return (EPERM);
+		}
 	}
-#endif
-
 	sx_sunlock(fdi.slock);
 
 	if (vp->v_type != vap->va_type) {
@@ -2633,6 +2669,7 @@
 static int
 fuse_standard_metrics(struct vnode *vp, struct thread *td, struct ucred *cred, int mode, struct fuse_filehandle *fufh, void *param) 
 {
+	DEBUG2G("fufh->mode, %x mode %x\n", fufh->mode, mode);
 	if (fufh->cred->cr_uid == cred->cr_uid &&
 	    fufh->cred->cr_rgid == cred->cr_rgid &&
 	    fufh->pid == td->td_proc->p_pid &&
@@ -2711,7 +2748,7 @@
 	struct vnode *vp = ap->a_vp;
 	int fdidx = ap->a_fdidx;
 	struct ucred *cred = ap->a_cred;
-	int mode = OFLAGS(ap->a_mode);
+	int mode = ap->a_mode;
 
 	struct fuse_filehandle *fufh;
 	struct fuse_vnode_data *fvdat = vp->v_data;
@@ -2724,6 +2761,7 @@
 	int err = 0;
 	struct file *fp = NULL;
 	int keep_cache;
+	struct fuse_mnt_data *fmnt = vp->v_mount->mnt_data; 
 
 	if (! vp->v_object)
 		/* The "if" here is just to avoid needless getattr'ing */
@@ -2753,12 +2791,13 @@
 	if (! fp)
 		panic("nonneg file desc passed to us but no file there");
 
+	DEBUG2G("fp->f_flag 0x%x, open mode %d\n", fp->f_flag, mode);
 	fdi.iosize = sizeof(*foi);
 	if ((err = fdisp_prepare_all(&fdi, (vp->v_type == VDIR) ? FUSE_OPENDIR : FUSE_OPEN, vp, td, cred)))
 		return (err);
 
 	foi = fdi.indata;
-	foi->flags = mode;
+	foi->flags = OFLAGS(mode);
 
 	if ((err = fdisp_wait_answ(&fdi)))
 		return (err);
@@ -2768,14 +2807,41 @@
 
 	fufh->fh_id = foo->fh;
 
+#if 0
+	/* 
+	 * We ignore the following flags sent from userspace, as they are in
+	 * fact mount options... just for some bizarre reason in Linux they
+	 * are kept at the daemon an she sends them down all the time.
+	 *
+	 * Well, that bizarre reason might be that this way daemons can
+	 * interpret/evaluate/override mount options. Yet you shouldn't
+	 * worry too mich about that happenning, as its accessible only
+	 * via the low-level API (filesystem writers are not encouraged to
+	 * fiddle with it).
+	 *
+	 * This implementation gives the mount opts to the mount util, which in turn
+	 * passes them to the kernel, not to the daemon, so our mount info
+	 * is authoritative, not the flags as seen by the daemon. So we ignore
+	 * them.
+	 */ 
+	
 	if (foo->open_flags & FOPEN_DIRECT_IO)
 		fp->f_flag |= O_DIRECT;
 
 	keep_cache = foo->open_flags & FOPEN_KEEP_CACHE;
+#endif
 
 	ticket_drop(fdi.tick);
 	sx_sunlock(fdi.slock);
 	
+	fp->f_flag = mode;
+	if (fmnt->mntopts & FUSEFS_DIRECTIO)
+		fp->f_flag |= O_DIRECT;
+
+
+	DEBUG2G("fp->f_flag 0x%x\n", fp->f_flag);
+	keep_cache = fmnt->mntopts & FUSEFS_KEEPCACHE;
+
 #if DIRECTIO_FOR_DIRS
 	if (vp->v_type == VDIR) {
 		DEBUG("coloring file #%d\n", fdidx);
@@ -2900,7 +2966,7 @@
 
 	fri = fdi.indata;
 	fri->fh = fufh->fh_id;
-	fri->flags = flags;
+	fri->flags = OFLAGS(flags);
 
 	fuse_insert_callback(fdi.tick, NULL);
 	fuse_insert_message(fdi.tick);
@@ -2963,7 +3029,7 @@
 	fp->f_data = NULL;
 
 	if (fufh->useco == 0)
-		err = fuse_send_release(fp->f_vnode, td, NULL, fufh, OFLAGS(fp->f_flag) & ~O_EXCL);
+		err = fuse_send_release(fp->f_vnode, td, NULL, fufh, fp->f_flag & ~O_EXCL);
 
 	//DEBUG2G("closing vnode #%d, opencount now is %d\n", VTOI(fp->f_vnode), --(fvdat->opencount));
 	return (err);
@@ -3132,6 +3198,7 @@
 {
 	int err = 0;
 	struct fuse_filehandle *fufh = fp->f_data;
+	struct fuse_mnt_data *fmnt = fp->f_vnode->v_mount->mnt_data;
 
 	BREAK_IF_BAD(fp);
 
@@ -3141,7 +3208,16 @@
 	if ((flags & FOF_OFFSET) == 0)
 		uio->uio_offset = fp->f_offset;
 
-	if (fp->f_flag & O_DIRECT) {
+	DEBUG2G("fp->f_flag 0x%x\n", fp->f_flag);
+
+	/* The great idea is to use the directio mnt opt such that it just
+	 * controls the default mode of the file, later on it can be tuned
+         * by fcntl. Alas, that doesn't work -- the system always stripes
+	 * out the O_DIRECT bit from my customized flag. So we fall back 
+	 * to the hardcoded behaviour (similar to Linux's, btw).
+	 */
+	//if (fp->f_flag & O_DIRECT) {
+	if (fmnt->mntopts & FUSEFS_DIRECTIO) {
 		DEBUG2G("direct read of vnode %d via file handle %llu\n", VTOI(fp->f_vnode), fufh->fh_id);
 		err = fuse_read_directbackend(fp->f_vnode, fufh->fh_id, uio, cred, td, FUSE_READ, fuse_std_buffeater, NULL);
 	} else {
@@ -4366,6 +4442,7 @@
 {
 	struct fuse_filehandle *fufh = fp->f_data;
 	struct vattr va;
+	struct fuse_mnt_data *fmnt = fp->f_vnode->v_mount->mnt_data;
 	int err = 0;
 
 	BREAK_IF_BAD(fp);
@@ -4387,7 +4464,8 @@
 	} else if ((flags & FOF_OFFSET) == 0)
 		uio->uio_offset = fp->f_offset;
 
-	if (fp->f_flag & O_DIRECT) {
+	//if (fp->f_flag & O_DIRECT) {
+	if (fmnt->mntopts & FUSEFS_DIRECTIO) {
 		DEBUG2G("direct write of vnode %d via file handle %llu\n", VTOI(fp->f_vnode), fufh->fh_id);
 		err = fuse_write_directbackend(fp->f_vnode, fufh->fh_id, uio, cred, td);
 	} else {
@@ -4454,7 +4532,7 @@
 #if _DEBUG
 	vn_printf(vp, DEBLABEL "fuse_strategy: looking for fufh for vnode #%d, to read from block #%d\n", VTOI(vp), (int)bp->b_blkno);
 #endif
-	if (! (fufh = get_filehandle(vp, NULL, cred, bp->b_iocmd == BIO_READ ? O_RDONLY : O_WRONLY)))
+	if (! (fufh = get_filehandle(vp, NULL, cred, bp->b_iocmd == BIO_READ ? FREAD : FWRITE)))
 		err = EIO;
 
 	if (! err)
@@ -4608,7 +4686,7 @@
 {
 	struct fuse_vnode_data *fvdat = ap->a_vp->v_data;
 
-	printf("nodeid: %d, fh_counter: %d\n", VTOI(ap->a_vp), fvdat->fh_counter);
+	printf("nodeid: %d, fh_counter: %d, nlookup: %llu\n", VTOI(ap->a_vp), fvdat->fh_counter, fvdat->nlookup);
 	return (0);
 }
 

==== //depot/projects/soc2005/fuse4bsd2/mount_fusefs/mount_fusefs.c#2 (text+ko) ====

@@ -39,29 +39,30 @@
 
 #include "mntopts.h"
 
-struct mntopt mopts[] = {
-	MOPT_STDOPTS,
-	{ NULL }
-};
-
 void	usage(void);
 
 int
 main(int argc, char *argv[])
 {
-#if __FreeBSD_version >= 600000
 	struct iovec *iov;
-#else
-	struct iovec iov[6];
-#endif
 	int ch, mntflags, iovlen;
 	char *dev, *dir, mntpath[MAXPATHLEN];
 
+	iov = NULL;
+	iovlen = 0;
 	mntflags = 0;
 	while ((ch = getopt(argc, argv, "o:")) != -1) {
 		switch(ch) {
 		case 'o':
-			getmntopts(optarg, mopts, &mntflags, 0);
+			if (strcmp(optarg,"fspath")       &&
+			    strcmp(optarg,"from")         &&
+			    strcmp(optarg,"allow_other")  &&
+			    strcmp(optarg,"kernel_cache") &&
+			    strcmp(optarg,"direct_io")) {
+					usage();
+					return (1);
+			}
+			build_iovec(&iov, &iovlen, optarg, "", -1);
 			break;
 		case '?':
 		default:
@@ -86,30 +87,11 @@
 
 	/* Prepare the options vector for nmount(). build_iovec() is declared
 	 * in mntopts.h. */
-#if __FreeBSD_version >= 600000
-	iov = NULL;
-	iovlen = 0;
 	build_iovec(&iov, &iovlen, "fstype", "fusefs", -1);
 	build_iovec(&iov, &iovlen, "fspath", mntpath, -1);
 	build_iovec(&iov, &iovlen, "from", dev, -1);
 
-	if (nmount(iov, iovlen, mntflags) < 0)
-#else
-	iov[0].iov_base = "fstype";
-	iov[0].iov_len = sizeof("fstype");
-	iov[1].iov_base = "fusefs";
-	iov[1].iov_len = strlen(iov[1].iov_base) + 1;
-	iov[2].iov_base = "fspath";
-	iov[2].iov_len = sizeof("fspath");
-	iov[3].iov_base = mntpath;
-	iov[3].iov_len = strlen(mntpath) + 1;
-	iov[4].iov_base = "from";
-	iov[4].iov_len = sizeof("from");
-	iov[5].iov_base = dev;
-	iov[5].iov_len = strlen(dev) + 1;
-
-	if (nmount(iov, 6, mntflags) < 0)
-#endif
+	if (nmount(iov, iovlen, 0) < 0)
 		err(EX_OSERR, "%s", dev);
 
 	exit(0);
@@ -119,6 +101,9 @@
 usage(void)
 {
 	fprintf(stderr,
-	    "usage: mount_fusefs [-o options] special node\n");
+	    "usage: mount_fusefs [-o option...] special node\n"
+	    "known options: allow_other kernel_cache direct_io\n"
+	    "(multiple options require separate \"-o\"-s)\n");
+	   
 	exit(EX_USAGE);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509111708.j8BH8E3c060295>