summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsyl <syl@openbsd.org>2013-06-21 21:30:38 +0000
committersyl <syl@openbsd.org>2013-06-21 21:30:38 +0000
commitf76a189da23ef70a4f8374bb21feb4fe452911d5 (patch)
treea166b5b8b1b127d8850687863919051df26951d7
parentstatic-linked binaries'r'us (diff)
downloadwireguard-openbsd-f76a189da23ef70a4f8374bb21feb4fe452911d5.tar.xz
wireguard-openbsd-f76a189da23ef70a4f8374bb21feb4fe452911d5.zip
Make fuse device clonable.
ok tedu@
-rw-r--r--etc/MAKEDEV.common8
-rw-r--r--lib/libfuse/fuse.c56
-rw-r--r--sys/miscfs/fuse/fuse_device.c234
-rw-r--r--sys/miscfs/fuse/fuse_vfsops.c20
-rw-r--r--sys/sys/conf.h4
-rw-r--r--sys/sys/mount.h4
6 files changed, 157 insertions, 169 deletions
diff --git a/etc/MAKEDEV.common b/etc/MAKEDEV.common
index 15afa161ea7..307a8830e34 100644
--- a/etc/MAKEDEV.common
+++ b/etc/MAKEDEV.common
@@ -1,4 +1,4 @@
-vers(a, {-$OpenBSD: MAKEDEV.common,v 1.65 2013/06/15 23:09:36 halex Exp $-})dnl
+vers(a, {-$OpenBSD: MAKEDEV.common,v 1.66 2013/06/21 21:30:38 syl Exp $-})dnl
dnl
dnl Copyright (c) 2001-2006 Todd T. Fries <todd@OpenBSD.org>
dnl
@@ -170,7 +170,7 @@ target(all, gpr, 0)dnl
target(all, ptm)dnl
target(all, hotplug)dnl
target(all, pppx)dnl
-target(all, fuse, 0, 1, 2, 3)dnl
+target(all, fuse)dnl
dnl
_mkdev(all, {-all-}, {-dnl
show_target(all)dnl
@@ -208,8 +208,8 @@ __devitem(cd, {-cd*-}, ATAPI and SCSI CD-ROM drives)dnl
_mkdev(cd, cd*, {-dodisk2 cd $U major_cd_b major_cd_c $U 0{--}ifstep(cd)-})dnl
__devitem(bthub, {-bthub*-}, Bluetooth Hubs)dnl
_mcdev(bthub, bthub*, bthub, {-major_bthub_c-})dnl
-__devitem(fuse, fuse*, Userland Filesystem, fuse 4)dnl
-_mcdev(fuse, fuse*, fuse, {-major_fuse_c-}, 600)dnl
+__devitem(fuse, fuse, Userland Filesystem, fuse 4)dnl
+_mcdev(fuse, fuse, fuse, {-major_fuse_c-}, 600)dnl
__devitem(ch, {-ch*-}, SCSI media changers)dnl
_mcdev(ch, ch*, ch, {-major_ch_c-}, 660, operator)dnl
__devitem(uk, uk*, Unknown SCSI devices)dnl
diff --git a/lib/libfuse/fuse.c b/lib/libfuse/fuse.c
index c2aa93b57fb..6c5b2e2d74e 100644
--- a/lib/libfuse/fuse.c
+++ b/lib/libfuse/fuse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse.c,v 1.6 2013/06/14 20:49:06 syl Exp $ */
+/* $OpenBSD: fuse.c,v 1.7 2013/06/21 21:30:38 syl Exp $ */
/*
* Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -96,18 +96,12 @@ fuse_loop(struct fuse *fuse)
return (0);
}
-#define DEVPATH "/dev/"
-#define FUSEDEV DEVPATH "fuse"
-
struct fuse_chan *
fuse_mount(const char *dir, unused struct fuse_args *args)
{
struct fusefs_args fargs;
struct fuse_chan *fc;
- struct stat st;
- char busnode[16];
- dev_t minor;
- int i;
+ const char *errcause;
fc = calloc(1, sizeof(*fc));
if (fc == NULL)
@@ -117,41 +111,25 @@ fuse_mount(const char *dir, unused struct fuse_args *args)
if (fc->dir == NULL)
goto bad;
- for (i = 0; i < 8 ; i++) {
- minor = -1;
- snprintf(busnode, sizeof(busnode), FUSEDEV "%d", i);
-
- DPRINTF("trying %s\n", busnode);
- if ((fc->fd = open(busnode, O_RDWR)) < 0) {
- if (errno == EBUSY)
- DPRINTF("device %s already opened\n", busnode);
- else if (errno != ENOENT && errno != ENXIO)
- DPRINTF("could not open %s\n", busnode);
- continue;
- }
-
- if (fstat(fc->fd, &st) != 0)
- goto bad;
-
- minor = st.st_rdev;
- break;
- }
-
- if (minor == -1) {
- fprintf(stderr, "%s: Cannot find a suitable fuse device\n",
- __func__);
+ if ((fc->fd = open("/dev/fuse0", O_RDWR)) < 0) {
+ perror(__func__);
goto bad;
}
- fargs.dev = minor;
+ fargs.fd = fc->fd;
if (mount(MOUNT_FUSEFS, dir, 0, &fargs)) {
- if (errno == EOPNOTSUPP)
- fprintf(stderr,
- "%s: %s: FS not supported by kernel\n", __func__,
- dir);
- else
- perror("fuse_mount failure:");
-
+ switch (errno) {
+ case EMFILE:
+ errcause = "mount table full";
+ break;
+ case EOPNOTSUPP:
+ errcause = "filesystem not supported by kernel";
+ break;
+ default:
+ errcause = strerror(errno);
+ break;
+ }
+ fprintf(stderr, "%s on %s: %s\n", __func__, dir, errcause);
goto bad;
}
diff --git a/sys/miscfs/fuse/fuse_device.c b/sys/miscfs/fuse/fuse_device.c
index 2962488549e..ee2ad9c860c 100644
--- a/sys/miscfs/fuse/fuse_device.c
+++ b/sys/miscfs/fuse/fuse_device.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_device.c,v 1.2 2013/06/12 22:55:02 tedu Exp $ */
+/* $OpenBSD: fuse_device.c,v 1.3 2013/06/21 21:30:38 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -27,40 +27,36 @@
#include "fusefs_node.h"
#include "fusefs.h"
-#define FUSE_UNIT(dev) (minor(dev))
-#define FUSE_DEV2SC(a) (&fuse_softc[FUSE_UNIT(a)])
-#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
-
#ifdef FUSE_DEBUG
-#define DPRINTF(fmt, arg...) printf("%s: " fmt, DEVNAME(sc), ##arg)
+#define DPRINTF(fmt, arg...) printf("%s: " fmt, "fuse", ##arg)
#else
#define DPRINTF(fmt, arg...)
#endif
SIMPLEQ_HEAD(fusebuf_head, fusebuf);
-struct fuse_softc {
- struct fusefs_mnt *sc_fmp;
- struct device sc_dev;
- int sc_opened;
+struct fuse_d {
+ struct fusefs_mnt *fd_fmp;
+ int fd_unit;
- struct fusebuf_head sc_fbufs_in;
- struct fusebuf_head sc_fbufs_wait;
+ /*fusebufs queues*/
+ struct fusebuf_head fd_fbufs_in;
+ struct fusebuf_head fd_fbufs_wait;
/* kq fields */
- struct selinfo sc_rsel;
+ struct selinfo fd_rsel;
+ LIST_ENTRY(fuse_d) fd_list;
};
-#define FUSE_OPEN 1
-#define FUSE_CLOSE 0
-#define FUSE_DONE 2
-
-struct fuse_softc *fuse_softc;
-static int numfuse = 0;
int stat_fbufs_in = 0;
int stat_fbufs_wait = 0;
int stat_opened_fusedev = 0;
+LIST_HEAD(, fuse_d) fuse_d_list;
+struct fuse_d *fuse_create(int);
+struct fuse_d *fuse_lookup(int);
+void fuse_destroy(dev_t dev, struct fuse_d *fd);
+
void fuseattach(int);
int fuseopen(dev_t, int, int, struct proc *);
int fuseclose(dev_t, int, int, struct proc *);
@@ -118,6 +114,41 @@ fuse_dump_buff(char *buff, int len)
}
#endif
+struct fuse_d *
+fuse_lookup(int unit)
+{
+ struct fuse_d *fd;
+
+ LIST_FOREACH(fd, &fuse_d_list, fd_list)
+ if (fd->fd_unit == unit)
+ return (fd);
+ return (NULL);
+}
+
+struct fuse_d *
+fuse_create(int unit)
+{
+ struct fuse_d *fd;
+
+ if ((fd = fuse_lookup(unit)) != NULL)
+ return (NULL);
+
+ fd = malloc(sizeof(*fd), M_DEVBUF, M_WAITOK | M_ZERO);
+ fd->fd_unit = unit;
+ SIMPLEQ_INIT(&fd->fd_fbufs_in);
+ SIMPLEQ_INIT(&fd->fd_fbufs_wait);
+ LIST_INSERT_HEAD(&fuse_d_list, fd, fd_list);
+ return (fd);
+}
+
+void
+fuse_destroy(dev_t dev, struct fuse_d *fd)
+{
+ LIST_REMOVE(fd, fd_list);
+ fuse_device_cleanup(dev, NULL);
+ free(fd, M_DEVBUF);
+}
+
/*
* if fbuf == NULL cleanup all msgs else remove fbuf from
* sc_fbufs_in and sc_fbufs_wait.
@@ -125,20 +156,19 @@ fuse_dump_buff(char *buff, int len)
void
fuse_device_cleanup(dev_t dev, struct fusebuf *fbuf)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
struct fusebuf *f;
- if (FUSE_UNIT(dev) >= numfuse)
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
return;
- sc = FUSE_DEV2SC(dev);
- sc->sc_fmp = NULL;
-
+ fd->fd_fmp = NULL;
/* clear FIFO IN*/
- while ((f = SIMPLEQ_FIRST(&sc->sc_fbufs_in))) {
+ while ((f = SIMPLEQ_FIRST(&fd->fd_fbufs_in))) {
if (fbuf == f || fbuf == NULL) {
DPRINTF("cleanup unprocessed msg in sc_fbufs_in\n");
- SIMPLEQ_REMOVE_HEAD(&sc->sc_fbufs_in, fb_next);
+ SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
stat_fbufs_in--;
if (fbuf == NULL)
pool_put(&fusefs_fbuf_pool, f);
@@ -146,10 +176,10 @@ fuse_device_cleanup(dev_t dev, struct fusebuf *fbuf)
}
/* clear FIFO WAIT*/
- while ((f = SIMPLEQ_FIRST(&sc->sc_fbufs_wait))) {
+ while ((f = SIMPLEQ_FIRST(&fd->fd_fbufs_wait))) {
if (fbuf == f || fbuf == NULL) {
DPRINTF("umount unprocessed msg in sc_fbufs_wait\n");
- SIMPLEQ_REMOVE_HEAD(&sc->sc_fbufs_wait, fb_next);
+ SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
stat_fbufs_wait--;
if (fbuf == NULL)
pool_put(&fusefs_fbuf_pool, f);
@@ -160,94 +190,66 @@ fuse_device_cleanup(dev_t dev, struct fusebuf *fbuf)
void
fuse_device_queue_fbuf(dev_t dev, struct fusebuf *fbuf)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
- if (FUSE_UNIT(dev) >= numfuse)
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
return;
- sc = FUSE_DEV2SC(dev);
- SIMPLEQ_INSERT_TAIL(&sc->sc_fbufs_in, fbuf, fb_next);
+ SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_in, fbuf, fb_next);
stat_fbufs_in++;
- selwakeup(&sc->sc_rsel);
+ selwakeup(&fd->fd_rsel);
}
void
fuse_device_set_fmp(struct fusefs_mnt *fmp)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
- if (FUSE_UNIT(fmp->dev) >= numfuse)
+ fd = fuse_lookup(minor(fmp->dev));
+ if (fd == NULL)
return;
- sc = FUSE_DEV2SC(fmp->dev);
- sc->sc_fmp = fmp;
+ fd->fd_fmp = fmp;
}
void
fuseattach(int num)
{
- char *mem;
- u_long size;
- int i;
-
- if (num <= 0)
- return;
- size = num * sizeof(struct fuse_softc);
- mem = malloc(size, M_FUSEFS, M_NOWAIT | M_ZERO);
-
- if (mem == NULL) {
- printf("fuse: WARNING no memory for fuse device\n");
- return;
- }
- fuse_softc = (struct fuse_softc *)mem;
- for (i = 0; i < num; i++) {
- struct fuse_softc *sc = &fuse_softc[i];
-
- SIMPLEQ_INIT(&sc->sc_fbufs_in);
- SIMPLEQ_INIT(&sc->sc_fbufs_wait);
- sc->sc_dev.dv_unit = i;
- snprintf(sc->sc_dev.dv_xname, sizeof(sc->sc_dev.dv_xname),
- "fuse%d", i);
- device_ref(&sc->sc_dev);
- }
- numfuse = num;
+ LIST_INIT(&fuse_d_list);
}
int
fuseopen(dev_t dev, int flags, int fmt, struct proc * p)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
- if (FUSE_UNIT(dev) >= numfuse)
- return (ENXIO);
-
- sc = FUSE_DEV2SC(dev);
+ if (flags & O_EXCL)
+ return (EBUSY); /* No exclusive opens */
- if (sc->sc_opened != FUSE_CLOSE || sc->sc_fmp)
+ if ((fd = fuse_create(minor(dev))) == NULL)
return (EBUSY);
- sc->sc_opened = FUSE_OPEN;
stat_opened_fusedev++;
-
return (0);
}
int
fuseclose(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
- if (FUSE_UNIT(dev) >= numfuse)
- return (ENXIO);
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
+ return (EINVAL);
- sc = FUSE_DEV2SC(dev);
- if (sc->sc_fmp) {
+ if (fd->fd_fmp) {
printf("libfuse close the device without umount\n");
- sc->sc_fmp->sess_init = 0;
- sc->sc_fmp = NULL;
+ fd->fd_fmp->sess_init = 0;
+ fd->fd_fmp = NULL;
}
- sc->sc_opened = FUSE_CLOSE;
+ fuse_destroy(dev, fd);
stat_opened_fusedev--;
return (0);
}
@@ -255,13 +257,8 @@ fuseclose(dev_t dev, int flags, int fmt, struct proc *p)
int
fuseioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
- struct fuse_softc *sc;
int error = 0;
- if (FUSE_UNIT(dev) >= numfuse)
- return (ENXIO);
-
- sc = FUSE_DEV2SC(dev);
switch (cmd) {
default:
DPRINTF("bad ioctl number %d\n", cmd);
@@ -274,7 +271,7 @@ fuseioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
int
fuseread(dev_t dev, struct uio *uio, int ioflag)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
struct fusebuf *fbuf;
int error = 0;
char *F_dat;
@@ -282,20 +279,17 @@ fuseread(dev_t dev, struct uio *uio, int ioflag)
int size;
size_t len;
- if (FUSE_UNIT(dev) >= numfuse)
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
return (ENXIO);
- sc = FUSE_DEV2SC(dev);
- if (sc->sc_opened != FUSE_OPEN)
- return (ENODEV);
-
- if (SIMPLEQ_EMPTY(&sc->sc_fbufs_in)) {
+ if (SIMPLEQ_EMPTY(&fd->fd_fbufs_in)) {
if (ioflag & O_NONBLOCK)
return (EAGAIN);
goto end;
}
- fbuf = SIMPLEQ_FIRST(&sc->sc_fbufs_in);
+ fbuf = SIMPLEQ_FIRST(&fd->fd_fbufs_in);
/*
* If it was not taken by last read
@@ -339,9 +333,9 @@ fuseread(dev_t dev, struct uio *uio, int ioflag)
* fbuf moves from a simpleq to another
*/
if (remain == 0) {
- SIMPLEQ_REMOVE_HEAD(&sc->sc_fbufs_in, fb_next);
+ SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
stat_fbufs_in--;
- SIMPLEQ_INSERT_TAIL(&sc->sc_fbufs_wait, fbuf, fb_next);
+ SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_wait, fbuf, fb_next);
stat_fbufs_wait++;
}
@@ -353,15 +347,15 @@ int
fusewrite(dev_t dev, struct uio *uio, int ioflag)
{
struct fusebuf *lastfbuf;
- struct fuse_softc *sc;
+ struct fuse_d *fd;
struct fusebuf *fbuf;
struct fb_hdr hdr;
int error = 0;
- if (FUSE_UNIT(dev) >= numfuse)
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
return (ENXIO);
- sc = FUSE_DEV2SC(dev);
if (uio->uio_resid < sizeof(hdr)) {
return (EINVAL);
}
@@ -372,7 +366,7 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
if ((error = uiomove(&hdr, sizeof(hdr), uio)) != 0)
return (error);
- SIMPLEQ_FOREACH(fbuf, &sc->sc_fbufs_wait, fb_next) {
+ SIMPLEQ_FOREACH(fbuf, &fd->fd_fbufs_wait, fb_next) {
if (fbuf->fb_uuid == hdr.fh_uuid) {
DPRINTF("catch unique %lu\n", fbuf->fb_uuid);
break;
@@ -390,7 +384,7 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
if (uio->uio_resid != hdr.fh_len ||
(uio->uio_resid != 0 && hdr.fh_err) ||
- SIMPLEQ_EMPTY(&sc->sc_fbufs_wait)) {
+ SIMPLEQ_EMPTY(&fd->fd_fbufs_wait)) {
printf("corrupted fuse header or queue empty\n");
return (EINVAL);
}
@@ -407,10 +401,10 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
if (!error) {
switch (fbuf->fb_type) {
case FBT_INIT:
- sc->sc_fmp->sess_init = 1;
+ fd->fd_fmp->sess_init = 1;
break ;
case FBT_DESTROY:
- sc->sc_fmp = NULL;
+ fd->fd_fmp = NULL;
break ;
}
@@ -418,10 +412,10 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
}
/* the fbuf could not be the HEAD fbuf */
- if (fbuf == SIMPLEQ_FIRST(&sc->sc_fbufs_wait))
- SIMPLEQ_REMOVE_HEAD(&sc->sc_fbufs_wait, fb_next);
+ if (fbuf == SIMPLEQ_FIRST(&fd->fd_fbufs_wait))
+ SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
else
- SIMPLEQ_REMOVE_AFTER(&sc->sc_fbufs_wait, lastfbuf,
+ SIMPLEQ_REMOVE_AFTER(&fd->fd_fbufs_wait, lastfbuf,
fb_next);
stat_fbufs_wait--;
@@ -437,15 +431,15 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
int
fusepoll(dev_t dev, int events, struct proc *p)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
int revents = 0;
- if (FUSE_UNIT(dev) >= numfuse)
- return (ENXIO);
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
+ return (EINVAL);
- sc = FUSE_DEV2SC(dev);
if (events & (POLLIN | POLLRDNORM))
- if (!SIMPLEQ_EMPTY(&sc->sc_fbufs_in))
+ if (!SIMPLEQ_EMPTY(&fd->fd_fbufs_in))
revents |= events & (POLLIN | POLLRDNORM);
if (events & (POLLOUT | POLLWRNORM))
@@ -453,7 +447,7 @@ fusepoll(dev_t dev, int events, struct proc *p)
if (revents == 0)
if (events & (POLLIN | POLLRDNORM))
- selrecord(p, &sc->sc_rsel);
+ selrecord(p, &fd->fd_rsel);
return (revents);
}
@@ -461,27 +455,27 @@ fusepoll(dev_t dev, int events, struct proc *p)
int
fusekqfilter(dev_t dev, struct knote *kn)
{
- struct fuse_softc *sc;
+ struct fuse_d *fd;
struct klist *klist;
- if (FUSE_UNIT(dev) >= numfuse)
- return (ENXIO);
+ fd = fuse_lookup(minor(dev));
+ if (fd == NULL)
+ return (EINVAL);
- sc = FUSE_DEV2SC(dev);
switch (kn->kn_filter) {
case EVFILT_READ:
- klist = &sc->sc_rsel.si_note;
+ klist = &fd->fd_rsel.si_note;
kn->kn_fop = &fuse_rd_filtops;
break;
case EVFILT_WRITE:
- klist = &sc->sc_rsel.si_note;
+ klist = &fd->fd_rsel.si_note;
kn->kn_fop = &fuse_seltrue_filtops;
break;
default:
return (EINVAL);
}
- kn->kn_hook = sc;
+ kn->kn_hook = fd;
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
@@ -491,8 +485,8 @@ fusekqfilter(dev_t dev, struct knote *kn)
void
filt_fuse_rdetach(struct knote *kn)
{
- struct fuse_softc *sc = kn->kn_hook;
- struct klist *klist = &sc->sc_rsel.si_note;
+ struct fuse_d *fd = kn->kn_hook;
+ struct klist *klist = &fd->fd_rsel.si_note;
SLIST_REMOVE(klist, kn, knote, kn_selnext);
}
@@ -500,10 +494,10 @@ filt_fuse_rdetach(struct knote *kn)
int
filt_fuse_read(struct knote *kn, long hint)
{
- struct fuse_softc *sc = kn->kn_hook;
+ struct fuse_d *fd = kn->kn_hook;
int event = 0;
- if (!SIMPLEQ_EMPTY(&sc->sc_fbufs_in))
+ if (!SIMPLEQ_EMPTY(&fd->fd_fbufs_in))
event = 1;
return (event);
diff --git a/sys/miscfs/fuse/fuse_vfsops.c b/sys/miscfs/fuse/fuse_vfsops.c
index fd6059c5780..2a1317395b4 100644
--- a/sys/miscfs/fuse/fuse_vfsops.c
+++ b/sys/miscfs/fuse/fuse_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vfsops.c,v 1.4 2013/06/12 22:55:02 tedu Exp $ */
+/* $OpenBSD: fuse_vfsops.c,v 1.5 2013/06/21 21:30:38 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -16,9 +16,13 @@
*/
#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/pool.h>
+#include <sys/proc.h>
+#include <sys/specdev.h>
#include <sys/statvfs.h>
#include <sys/sysctl.h>
#include <sys/vnode.h>
@@ -69,6 +73,8 @@ fusefs_mount(struct mount *mp, const char *path, void *data,
struct fusefs_mnt *fmp;
struct fusebuf *fbuf;
struct fusefs_args args;
+ struct vnode *vp;
+ struct file *fp;
int error;
if (mp->mnt_flag & MNT_UPDATE)
@@ -78,10 +84,20 @@ fusefs_mount(struct mount *mp, const char *path, void *data,
if (error)
return (error);
+ if ((fp = fd_getfile(p->p_fd, args.fd)) == NULL)
+ return (EBADF);
+
+ if (fp->f_type != DTYPE_VNODE)
+ return (EINVAL);
+
+ vp = fp->f_data;
+ if (vp->v_type != VCHR)
+ return (EBADF);
+
fmp = malloc(sizeof(*fmp), M_FUSEFS, M_WAITOK | M_ZERO);
fmp->mp = mp;
fmp->sess_init = 0;
- fmp->dev = args.dev;
+ fmp->dev = vp->v_rdev;
mp->mnt_data = fmp;
mp->mnt_flag |= MNT_LOCAL;
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 6fbd86742a2..cb317613f70 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.123 2013/06/11 16:42:17 deraadt Exp $ */
+/* $OpenBSD: conf.h,v 1.124 2013/06/21 21:30:38 syl Exp $ */
/* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */
/*-
@@ -514,7 +514,7 @@ extern struct cdevsw cdevsw[];
dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
dev_init(c,n,write), dev_init(c,n,ioctl), \
(dev_type_stop((*))) enodev, 0, dev_init(c,n,poll), \
- (dev_type_mmap((*))) enodev, 0, 0, dev_init(c,n,kqfilter) }
+ (dev_type_mmap((*))) enodev, 0, D_CLONE, dev_init(c,n,kqfilter) }
#endif
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index e8e02549873..f967f3f519f 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.h,v 1.112 2013/06/11 19:01:20 beck Exp $ */
+/* $OpenBSD: mount.h,v 1.113 2013/06/21 21:30:38 syl Exp $ */
/* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */
/*
@@ -264,7 +264,7 @@ struct procfs_args {
struct fusefs_args {
char *name;
char *url;
- dev_t dev;
+ int fd;
int flags;
};