From: helg Date: Thu, 30 Nov 2017 11:29:03 +0000 (+0000) Subject: vn_open(9) does not pass the open(2) flags to VOP_CREATE(9) so we can't X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=eedad28e9275b1a1371be362f2e010287ee21920;p=openbsd vn_open(9) does not pass the open(2) flags to VOP_CREATE(9) so we can't support FBT_CREATE. Fall back to FBT_MKNOD + FBT_OPEN so that a valid sequence of FUSE messages is sent to the file system when creating files. input from mpi@, otto@ --- diff --git a/lib/libfuse/fuse_ops.c b/lib/libfuse/fuse_ops.c index e91b1fa4790..395ce28573b 100644 --- a/lib/libfuse/fuse_ops.c +++ b/lib/libfuse/fuse_ops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse_ops.c,v 1.27 2017/11/17 15:45:17 helg Exp $ */ +/* $OpenBSD: fuse_ops.c,v 1.28 2017/11/30 11:29:03 helg Exp $ */ /* * Copyright (c) 2013 Sylvestre Gallon * @@ -579,53 +579,6 @@ ifuse_ops_write(struct fuse *f, struct fusebuf *fbuf) return (0); } -static int -ifuse_ops_create(struct fuse *f, struct fusebuf *fbuf) -{ - struct fuse_file_info ffi; - struct fuse_vnode *vn; - uint32_t mode; - - char *realname; - - DPRINTF("Opcode:\tcreate\n"); - DPRINTF("Inode:\t%llu\n", (unsigned long long)fbuf->fb_ino); - - bzero(&ffi, sizeof(ffi)); - ffi.flags = fbuf->fb_io_flags; - mode = fbuf->fb_io_mode; - - vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino); - if (vn == NULL) { - fbuf->fb_err = -errno; - free(fbuf->fb_dat); - return (0); - } - - free(fbuf->fb_dat); - realname = build_realname(f, vn->ino); - if (realname == NULL) { - fbuf->fb_err = -errno; - return (0); - } - - if (f->op.create) - fbuf->fb_err = f->op.create(realname, mode, &ffi); - else if (f->op.mknod) - fbuf->fb_err = f->op.mknod(realname, S_IFREG | mode, 0); - else - fbuf->fb_err = -ENOSYS; - - if (!fbuf->fb_err) { - fbuf->fb_err = update_attr(f, &fbuf->fb_attr, realname, vn); - fbuf->fb_ino = fbuf->fb_attr.st_ino; - fbuf->fb_io_mode = fbuf->fb_attr.st_mode; - } - free(realname); - - return (0); -} - static int ifuse_ops_mkdir(struct fuse *f, struct fusebuf *fbuf) { @@ -1125,9 +1078,6 @@ ifuse_exec_opcode(struct fuse *f, struct fusebuf *fbuf) case FBT_ACCESS: ret = ifuse_ops_access(f, fbuf); break; - case FBT_CREATE: - ret = ifuse_ops_create(f, fbuf); - break; case FBT_SYMLINK: ret = ifuse_ops_symlink(f, fbuf); break; diff --git a/share/man/man9/fb_setup.9 b/share/man/man9/fb_setup.9 index d39f3340fad..87fac07e95c 100644 --- a/share/man/man9/fb_setup.9 +++ b/share/man/man9/fb_setup.9 @@ -1,4 +1,4 @@ -.\" $OpenBSD: fb_setup.9,v 1.6 2016/08/30 16:45:54 natano Exp $ +.\" $OpenBSD: fb_setup.9,v 1.7 2017/11/30 11:29:03 helg Exp $ .\" .\" Copyright (c) 2013 Sylvestre Gallon .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 30 2016 $ +.Dd $Mdocdate: November 30 2017 $ .Dt FB_SETUP 9 .Os .Sh NAME @@ -184,8 +184,6 @@ The fusebuf is a close dir operation. The fusebuf is a dir sync operation. .It Dv FBT_ACCESS The fusebuf is an access operation. -.It Dv FBT_CREATE -The fusebuf is a create file operation. .It Dv FBT_DESTROY The fusebuf closes the FUSE connection. .El @@ -210,7 +208,7 @@ Used by the getattr and setattr calls. .It Fa FD_io Contains all fields commonly used by FUSE client callbacks to provide information to FUSE vnops. -It is used by access, readdir, release, releasedir, read, write, create, +It is used by access, readdir, release, releasedir, read, write, mkdir, and setattr. .El .Pp diff --git a/sys/miscfs/fuse/fuse_vnops.c b/sys/miscfs/fuse/fuse_vnops.c index 80585d0e8d5..81146b99b76 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.36 2017/11/27 22:55:17 helg Exp $ */ +/* $OpenBSD: fuse_vnops.c,v 1.37 2017/11/30 11:29:03 helg Exp $ */ /* * Copyright (c) 2012-2013 Sylvestre Gallon * @@ -211,7 +211,7 @@ fusefs_open(void *v) struct fusefs_node *ip; struct fusefs_mnt *fmp; enum fufh_type fufh_type = FUFH_RDONLY; - int flags = O_RDONLY; + int flags; int error; int isdir; @@ -226,22 +226,22 @@ fusefs_open(void *v) if (ap->a_vp->v_type == VDIR) isdir = 1; else { - if ((ap->a_mode & FREAD) && (ap->a_mode & FWRITE)) { + if ((ap->a_mode & FREAD) && (ap->a_mode & FWRITE)) fufh_type = FUFH_RDWR; - flags = O_RDWR; - } else if (ap->a_mode & (FWRITE)) { + else if (ap->a_mode & (FWRITE)) fufh_type = FUFH_WRONLY; - flags = O_WRONLY; - } } /* already open i think all is ok */ if (ip->fufh[fufh_type].fh_type != FUFH_INVALID) return (0); + /* + * The file has already been created and/or truncated so FUSE dictates + * that no creation and truncation flags are passed to open. + */ + flags = OFLAGS(ap->a_mode) & ~(O_CREAT|O_EXCL|O_TRUNC); error = fusefs_file_open(fmp, ip, fufh_type, flags, isdir, ap->a_p); - if (error) - return (error); return (error); } @@ -904,16 +904,15 @@ fusefs_create(void *v) goto out; } - if (fmp->undef_op & UNDEF_CREATE) { + if (fmp->undef_op & UNDEF_MKNOD) { error = ENOSYS; goto out; } fbuf = fb_setup(cnp->cn_namelen + 1, ip->ufs_ino.i_number, - FBT_CREATE, p); + FBT_MKNOD, p); fbuf->fb_io_mode = mode; - fbuf->fb_io_flags = O_CREAT | O_RDWR; memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen); fbuf->fb_dat[cnp->cn_namelen] = '\0'; @@ -921,7 +920,7 @@ fusefs_create(void *v) error = fb_queue(fmp->dev, fbuf); if (error) { if (error == ENOSYS) - fmp->undef_op |= UNDEF_CREATE; + fmp->undef_op |= UNDEF_MKNOD; fb_delete(fbuf); goto out; diff --git a/sys/sys/fusebuf.h b/sys/sys/fusebuf.h index 83f0e83bb80..76bb73e559b 100644 --- a/sys/sys/fusebuf.h +++ b/sys/sys/fusebuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fusebuf.h,v 1.11 2016/08/30 16:45:54 natano Exp $ */ +/* $OpenBSD: fusebuf.h,v 1.12 2017/11/30 11:29:03 helg Exp $ */ /* * Copyright (c) 2013 Sylvestre Gallon * Copyright (c) 2013 Martin Pieuchot @@ -126,7 +126,6 @@ struct fusebuf { #define FBT_RELEASEDIR 22 #define FBT_FSYNCDIR 23 #define FBT_ACCESS 24 -#define FBT_CREATE 25 #define FBT_DESTROY 26 #define FBT_RECLAIM 27