vn_open(9) does not pass the open(2) flags to VOP_CREATE(9) so we can't
authorhelg <helg@openbsd.org>
Thu, 30 Nov 2017 11:29:03 +0000 (11:29 +0000)
committerhelg <helg@openbsd.org>
Thu, 30 Nov 2017 11:29:03 +0000 (11:29 +0000)
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@

lib/libfuse/fuse_ops.c
share/man/man9/fb_setup.9
sys/miscfs/fuse/fuse_vnops.c
sys/sys/fusebuf.h

index e91b1fa..395ce28 100644 (file)
@@ -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 <ccna.syl@gmail.com>
  *
@@ -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;
index d39f334..87fac07 100644 (file)
@@ -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 <ccna.syl@gmail.com>
 .\"
@@ -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
index 80585d0..81146b9 100644 (file)
@@ -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 <ccna.syl@gmail.com>
  *
@@ -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;
index 83f0e83..76bb73e 100644 (file)
@@ -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