diff options
author | 2013-10-07 18:04:53 +0000 | |
---|---|---|
committer | 2013-10-07 18:04:53 +0000 | |
commit | 4c526d156a9a014b3df288eeedf67c51a310449c (patch) | |
tree | 7c6bc55676d2d6777d9788abf1a13a632ad6cc9d /sys/miscfs | |
parent | typo (diff) | |
download | wireguard-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.c | 141 | ||||
-rw-r--r-- | sys/miscfs/fuse/fuse_file.c | 6 | ||||
-rw-r--r-- | sys/miscfs/fuse/fuse_lookup.c | 6 | ||||
-rw-r--r-- | sys/miscfs/fuse/fuse_vnops.c | 51 | ||||
-rw-r--r-- | sys/miscfs/fuse/fusebuf.c | 3 |
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); } |