summaryrefslogtreecommitdiffstats
path: root/sys/miscfs
diff options
context:
space:
mode:
authorsyl <syl@openbsd.org>2013-10-07 18:04:53 +0000
committersyl <syl@openbsd.org>2013-10-07 18:04:53 +0000
commit4c526d156a9a014b3df288eeedf67c51a310449c (patch)
tree7c6bc55676d2d6777d9788abf1a13a632ad6cc9d /sys/miscfs
parenttypo (diff)
downloadwireguard-openbsd-4c526d156a9a014b3df288eeedf67c51a310449c.tar.xz
wireguard-openbsd-4c526d156a9a014b3df288eeedf67c51a310449c.zip
Rework fuseread() and fusewrite().
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/fuse/fuse_device.c141
-rw-r--r--sys/miscfs/fuse/fuse_file.c6
-rw-r--r--sys/miscfs/fuse/fuse_lookup.c6
-rw-r--r--sys/miscfs/fuse/fuse_vnops.c51
-rw-r--r--sys/miscfs/fuse/fusebuf.c3
5 files changed, 86 insertions, 121 deletions
diff --git a/sys/miscfs/fuse/fuse_device.c b/sys/miscfs/fuse/fuse_device.c
index c0ab0ff11a0..21c7c4aa6aa 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.5 2013/08/10 00:12:44 syl Exp $ */
+/* $OpenBSD: fuse_device.c,v 1.6 2013/10/07 18:04:53 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -273,11 +273,8 @@ fuseread(dev_t dev, struct uio *uio, int ioflag)
struct fuse_d *fd;
struct fusebuf *fbuf;
struct fb_hdr hdr;
+ void *tmpaddr;
int error = 0;
- char *F_dat;
- int remain;
- int size;
- size_t len;
fd = fuse_lookup(minor(dev));
if (fd == NULL)
@@ -291,49 +288,28 @@ fuseread(dev_t dev, struct uio *uio, int ioflag)
}
fbuf = SIMPLEQ_FIRST(&fd->fd_fbufs_in);
- /*
- * If it was not taken by last read
- * fetch the fb_hdr.
- */
- len = sizeof(struct fb_hdr);
- if (fbuf->fb_resid == -1) {
- /* we get the whole header or nothing */
- if (uio->uio_resid < len)
- return (EINVAL);
-
- memcpy(&hdr, &fbuf->fb_hdr, sizeof(hdr));
- bzero(&hdr.fh_next, sizeof(hdr.fh_next));
- error = uiomove(&hdr, len, uio);
- if (error)
- goto end;
-
-#ifdef FUSE_DEBUG
- fuse_dump_buff((char *)fbuf, len);
-#endif
- fbuf->fb_resid = 0;
- }
-
- /* fetch F_dat if there is something present */
- if ((fbuf->fb_len > 0) && uio->uio_resid) {
- size = MIN(fbuf->fb_len - fbuf->fb_resid, uio->uio_resid);
- F_dat = (char *)&fbuf->F_dat;
+ /* We get the whole fusebuf or nothing */
+ if (uio->uio_resid != FUSEBUFSIZE)
+ return (EINVAL);
- error = uiomove(&F_dat[fbuf->fb_resid], size, uio);
- if (error)
- goto end;
+ /* Do not send kernel pointers */
+ memcpy(&hdr.fh_next, &fbuf->fb_next, sizeof(fbuf->fb_next));
+ bzero(&fbuf->fb_next, sizeof(fbuf->fb_next));
+ tmpaddr = fbuf->fb_dat;
+ fbuf->fb_dat = NULL;
+ error = uiomove(fbuf, FUSEBUFSIZE, uio);
+ if (error)
+ goto end;
#ifdef FUSE_DEBUG
- fuse_dump_buff(&F_dat[fbuf->fb_resid], size);
+ fuse_dump_buff((char *)fbuf, FUSEBUFSIZE);
#endif
- fbuf->fb_resid += size;
- }
+ /* Restore kernel pointers */
+ memcpy(&fbuf->fb_next, &hdr.fh_next, sizeof(fbuf->fb_next));
+ fbuf->fb_dat = tmpaddr;
- remain = (fbuf->fb_len - fbuf->fb_resid);
-
- /*
- * fbuf moves from a simpleq to another
- */
- if (remain == 0) {
+ /* Remove the fbuf if it does not contains data */
+ if (fbuf->fb_len == 0) {
SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
stat_fbufs_in--;
SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_wait, fbuf, fb_next);
@@ -357,74 +333,67 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
if (fd == NULL)
return (ENXIO);
- if (uio->uio_resid < sizeof(hdr)) {
+ /* We get the whole fusebuf or nothing */
+ if (uio->uio_resid != FUSEBUFSIZE)
return (EINVAL);
- }
- /*
- * get out header
- */
if ((error = uiomove(&hdr, sizeof(hdr), uio)) != 0)
return (error);
+ /* looking for uuid in fd_fbufs_wait */
SIMPLEQ_FOREACH(fbuf, &fd->fd_fbufs_wait, fb_next) {
if (fbuf->fb_uuid == hdr.fh_uuid)
break;
lastfbuf = fbuf;
}
+ if (fbuf == NULL)
+ return (EINVAL);
-#ifdef FUSE_DEBUG
- fuse_dump_buff((char *)&hdr, sizeof(hdr));
-#endif
-
- if (fbuf != NULL) {
- fbuf->fb_len = hdr.fh_len;
- fbuf->fb_err = hdr.fh_err;
- fbuf->fb_ino = hdr.fh_ino;
+ /* Update fb_hdr */
+ fbuf->fb_len = hdr.fh_len;
+ fbuf->fb_err = hdr.fh_err;
+ fbuf->fb_ino = hdr.fh_ino;
- if (uio->uio_resid != hdr.fh_len ||
- (uio->uio_resid != 0 && hdr.fh_err) ||
- SIMPLEQ_EMPTY(&fd->fd_fbufs_wait)) {
- printf("corrupted fuse header or queue empty\n");
- return (EINVAL);
- }
+ /* Check for corrupted fbufs */
+ if ((fbuf->fb_len && fbuf->fb_err) ||
+ SIMPLEQ_EMPTY(&fd->fd_fbufs_wait)) {
+ printf("corrupted fuse header or queue empty\n");
+ error = EINVAL;
+ goto end;
+ }
- if (uio->uio_resid > 0 && fbuf->fb_len > 0) {
- error = uiomove(&fbuf->F_dat, fbuf->fb_len, uio);
- if (error)
- return error;
+ /* Get the missing datas from the fbuf */
+ error = uiomove(&fbuf->FD, uio->uio_resid, uio);
+ if (error)
+ return error;
+ fbuf->fb_dat = NULL;
#ifdef FUSE_DEBUG
- fuse_dump_buff((char *)&fbuf->F_dat, fbuf->fb_len);
+ fuse_dump_buff((char *)fbuf, FUSEBUFSIZE);
#endif
- }
-
- if (!error) {
- switch (fbuf->fb_type) {
- case FBT_INIT:
- fd->fd_fmp->sess_init = 1;
- break ;
- case FBT_DESTROY:
- fd->fd_fmp = NULL;
- break ;
- }
- wakeup(fbuf);
- }
-
- /* the fbuf could not be the HEAD fbuf */
+ switch (fbuf->fb_type) {
+ case FBT_INIT:
+ fd->fd_fmp->sess_init = 1;
+ break ;
+ case FBT_DESTROY:
+ fd->fd_fmp = NULL;
+ break ;
+ }
+end:
+ /* Remove the fbuf if it does not contains data */
+ if (fbuf->fb_len == 0) {
if (fbuf == SIMPLEQ_FIRST(&fd->fd_fbufs_wait))
SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
else
SIMPLEQ_REMOVE_AFTER(&fd->fd_fbufs_wait, lastfbuf,
fb_next);
stat_fbufs_wait--;
-
if (fbuf->fb_type == FBT_INIT)
pool_put(&fusefs_fbuf_pool, fbuf);
-
- } else
- error = EINVAL;
+ else
+ wakeup(fbuf);
+ }
return (error);
}
diff --git a/sys/miscfs/fuse/fuse_file.c b/sys/miscfs/fuse/fuse_file.c
index faceacd1291..5c79a07de18 100644
--- a/sys/miscfs/fuse/fuse_file.c
+++ b/sys/miscfs/fuse/fuse_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_file.c,v 1.2 2013/08/10 00:12:45 syl Exp $ */
+/* $OpenBSD: fuse_file.c,v 1.3 2013/10/07 18:04:53 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -31,7 +31,7 @@ fusefs_file_open(struct fusefs_mnt *fmp, struct fusefs_node *ip,
struct fusebuf *fbuf;
int error = 0;
- fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number,
+ fbuf = fb_setup(0, ip->ufs_ino.i_number,
((isdir) ? FBT_OPENDIR : FBT_OPEN), p);
fbuf->fb_io_flags = flags;
@@ -55,7 +55,7 @@ fusefs_file_close(struct fusefs_mnt *fmp, struct fusefs_node * ip,
struct fusebuf *fbuf;
int error = 0;
- fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number,
+ fbuf = fb_setup(0, ip->ufs_ino.i_number,
((isdir) ? FBT_RELEASEDIR : FBT_RELEASE), p);
fbuf->fb_io_fd = ip->fufh[fufh_type].fh_id;
fbuf->fb_io_flags = flags;
diff --git a/sys/miscfs/fuse/fuse_lookup.c b/sys/miscfs/fuse/fuse_lookup.c
index 45b762c70ab..357fe50f488 100644
--- a/sys/miscfs/fuse/fuse_lookup.c
+++ b/sys/miscfs/fuse/fuse_lookup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_lookup.c,v 1.4 2013/08/10 00:12:45 syl Exp $ */
+/* $OpenBSD: fuse_lookup.c,v 1.5 2013/10/07 18:04:53 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -75,8 +75,8 @@ fusefs_lookup(void *v)
nid = dp->ufs_ino.i_number;
} else {
/* got a real entry */
- fbuf = fb_setup(FUSEFDSIZE + cnp->cn_namelen + 1,
- dp->ufs_ino.i_number, FBT_LOOKUP, p);
+ fbuf = fb_setup(cnp->cn_namelen + 1, dp->ufs_ino.i_number,
+ FBT_LOOKUP, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
diff --git a/sys/miscfs/fuse/fuse_vnops.c b/sys/miscfs/fuse/fuse_vnops.c
index 4ac8fb93794..23b1e482ccd 100644
--- a/sys/miscfs/fuse/fuse_vnops.c
+++ b/sys/miscfs/fuse/fuse_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vnops.c,v 1.5 2013/09/17 19:07:11 syl Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.6 2013/10/07 18:04:53 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -235,7 +235,7 @@ fusefs_access(void *v)
if ((ap->a_mode & VEXEC) != 0)
mask |= 0x1;
- fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number, FBT_ACCESS, p);
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_ACCESS, p);
fbuf->fb_io_mode = mask;
error = fb_queue(fmp->dev, fbuf);
@@ -329,8 +329,7 @@ fusefs_setattr(void *v)
if (!fmp->sess_init || (fmp->undef_op & UNDEF_SETATTR))
return (ENXIO);
- fbuf = fb_setup(FUSEFDSIZE + sizeof(*io), ip->ufs_ino.i_number,
- FBT_SETATTR, p);
+ fbuf = fb_setup(sizeof(*io), ip->ufs_ino.i_number, FBT_SETATTR, p);
io = fbtod(fbuf, struct fb_io *);
io->fi_flags = 0;
@@ -466,8 +465,8 @@ fusefs_link(void *v)
if (!fmp->sess_init || (fmp->undef_op & UNDEF_LINK))
goto out1;
- fbuf = fb_setup(FUSEFDSIZE + cnp->cn_namelen + 1,
- dip->ufs_ino.i_number, FBT_LINK, p);
+ fbuf = fb_setup(cnp->cn_namelen + 1, dip->ufs_ino.i_number,
+ FBT_LINK, p);
fbuf->fb_io_ino = ip->ufs_ino.i_number;
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
@@ -519,8 +518,8 @@ fusefs_symlink(void *v)
len = strlen(target) + 1;
- fbuf = fb_setup(FUSEFDSIZE + len + cnp->cn_namelen + 1,
- dp->ufs_ino.i_number, FBT_SYMLINK, p);
+ fbuf = fb_setup(len + cnp->cn_namelen + 1, dp->ufs_ino.i_number,
+ FBT_SYMLINK, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -578,8 +577,7 @@ fusefs_readdir(void *v)
return (EINVAL);
while (uio->uio_resid > 0) {
- fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number, FBT_READDIR,
- p);
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READDIR, p);
if (ip->fufh[FUFH_RDONLY].fh_type == FUFH_INVALID) {
/* TODO open the file */
@@ -588,7 +586,7 @@ fusefs_readdir(void *v)
}
fbuf->fb_io_fd = ip->fufh[FUFH_RDONLY].fh_id;
fbuf->fb_io_off = uio->uio_offset;
- fbuf->fb_io_len = MIN(uio->uio_resid, FUSELEN);
+ fbuf->fb_io_len = MIN(uio->uio_resid, FUSEBUFMAXSIZE);
error = fb_queue(fmp->dev, fbuf);
@@ -598,12 +596,12 @@ fusefs_readdir(void *v)
}
/*ack end of readdir */
- if (fbdatsize(fbuf) == 0) {
+ if (fbuf->fb_len == 0) {
pool_put(&fusefs_fbuf_pool, fbuf);
break;
}
- if ((error = uiomove(fbuf->fb_dat, fbdatsize(fbuf), uio))) {
+ if ((error = uiomove(fbuf->fb_dat, fbuf->fb_len, uio))) {
pool_put(&fusefs_fbuf_pool, fbuf);
break;
}
@@ -678,7 +676,7 @@ fusefs_readlink(void *v)
goto out;
}
- error = uiomove(fbuf->fb_dat, fbdatsize(fbuf), uio);
+ error = uiomove(fbuf->fb_dat, fbuf->fb_len, uio);
pool_put(&fusefs_fbuf_pool, fbuf);
out:
return (error);
@@ -760,8 +758,8 @@ fusefs_create(void *v)
goto out;
}
- fbuf = fb_setup(FUSEFDSIZE + cnp->cn_namelen + 1,
- ip->ufs_ino.i_number, FBT_CREATE, p);
+ fbuf = fb_setup(cnp->cn_namelen + 1, ip->ufs_ino.i_number,
+ FBT_CREATE, p);
fbuf->fb_io_mode = mode;
fbuf->fb_io_flags = O_CREAT | O_RDWR;
@@ -830,9 +828,9 @@ fusefs_read(void *v)
return (EINVAL);
while (uio->uio_resid > 0) {
- fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number, FBT_READ, p);
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READ, p);
- size = MIN(uio->uio_resid, FUSELEN);
+ size = MIN(uio->uio_resid, FUSEBUFMAXSIZE);
fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_RDONLY);
fbuf->fb_io_off = uio->uio_offset;
fbuf->fb_io_len = size;
@@ -842,11 +840,11 @@ fusefs_read(void *v)
if (error)
break;
- error = uiomove(fbuf->fb_dat, MIN(size, fbdatsize(fbuf)), uio);
+ error = uiomove(fbuf->fb_dat, MIN(size, fbuf->fb_len), uio);
if (error)
break;
- if (fbdatsize(fbuf) < size)
+ if (fbuf->fb_len < size)
break;
pool_put(&fusefs_fbuf_pool, fbuf);
@@ -879,9 +877,8 @@ fusefs_write(void *v)
return (error);
while (uio->uio_resid > 0) {
- len = MIN(uio->uio_resid, FUSELEN);
- fbuf = fb_setup(FUSEFDSIZE + len, ip->ufs_ino.i_number,
- FBT_WRITE, p);
+ len = MIN(uio->uio_resid, FUSEBUFMAXSIZE);
+ fbuf = fb_setup(len, ip->ufs_ino.i_number, FBT_WRITE, p);
fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_WRONLY);
fbuf->fb_io_off = uio->uio_offset;
@@ -1008,7 +1005,7 @@ abortit:
goto abortit;
}
- fbuf = fb_setup(FUSEFDSIZE + fcnp->cn_namelen + tcnp->cn_namelen + 2,
+ fbuf = fb_setup(fcnp->cn_namelen + tcnp->cn_namelen + 2,
dp->ufs_ino.i_number, FBT_RENAME, p);
memcpy(fbuf->fb_dat, fcnp->cn_nameptr, fcnp->cn_namelen);
@@ -1067,7 +1064,7 @@ fusefs_mkdir(void *v)
goto out;
}
- fbuf = fb_setup(FUSEFDSIZE + cnp->cn_namelen + 1, ip->ufs_ino.i_number,
+ fbuf = fb_setup(cnp->cn_namelen + 1, ip->ufs_ino.i_number,
FBT_MKDIR, p);
fbuf->fb_io_mode = MAKEIMODE(vap->va_type, vap->va_mode);
@@ -1135,7 +1132,7 @@ fusefs_rmdir(void *v)
VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
- fbuf = fb_setup(FUSEFDSIZE + cnp->cn_namelen + 1, dp->ufs_ino.i_number,
+ fbuf = fb_setup(cnp->cn_namelen + 1, dp->ufs_ino.i_number,
FBT_RMDIR, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -1191,7 +1188,7 @@ fusefs_remove(void *v)
goto out;
}
- fbuf = fb_setup(FUSEFDSIZE + cnp->cn_namelen + 1, dp->ufs_ino.i_number,
+ fbuf = fb_setup(cnp->cn_namelen + 1, dp->ufs_ino.i_number,
FBT_UNLINK, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
diff --git a/sys/miscfs/fuse/fusebuf.c b/sys/miscfs/fuse/fusebuf.c
index 9c4a217d983..4c9aae7b6e7 100644
--- a/sys/miscfs/fuse/fusebuf.c
+++ b/sys/miscfs/fuse/fusebuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fusebuf.c,v 1.2 2013/08/10 00:12:45 syl Exp $ */
+/* $OpenBSD: fusebuf.c,v 1.3 2013/10/07 18:04:53 syl Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -41,7 +41,6 @@ fb_setup(size_t len, ino_t ino, int op, struct proc *p)
fbuf->fb_uuid = arc4random();
fbuf->fb_type = op;
fbuf->fb_ino = ino;
- fbuf->fb_resid = -1;
return (fbuf);
}