On Fri, 10 Nov 2017 09:09:32 +0100
Martin Pieuchot <m...@openbsd.org> wrote:

> On 09/11/17(Thu) 01:20, Helg Bredow wrote:
> > > On 08/11/17(Wed) 14:12, Helg Bredow wrote:
> > > > There is a bug when creating a file in fuse-exfat and then deleting it
> > > > again without first unmounting the file system. The reason for this is
> > > > that fuse-exfat maintains strict reference counts and fuse currently
> > > > calls the file system create and open functions when it should only
> > > > call create. 
> > > > [...]
> > > 
[...]
> 
> In the end that's your call.  Nobody understand the problem, what you
> say is "we are not linux".  Which we already know.  And you're pushing
> for a diff which works saying that the best solution.  It believe it
> fixes the problem so go for it.

I now this caused some confusion but I believe the patch below is the
correct solution. Here's the mapping of file system calls so it's clear.

vfs         | fuse
============+========
atomic_open | create
create      | mknod
mknod       | mknod
open        | open

encfs and fuse-exfat now work.
curlftsfs now returns an error on file append since it doesn't support
it.

I've contacted the developer of fuse-zip and he's adding mknod()
support.

ok?


Index: sys/miscfs/fuse/fuse_vnops.c
===================================================================
RCS file: /cvs/src/sys/miscfs/fuse/fuse_vnops.c,v
retrieving revision 1.33
diff -u -p -p -u -r1.33 fuse_vnops.c
--- sys/miscfs/fuse/fuse_vnops.c        7 Sep 2016 17:53:35 -0000       1.33
+++ sys/miscfs/fuse/fuse_vnops.c        18 Nov 2017 01:58:34 -0000
@@ -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,24 +226,27 @@ 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);
 
+       /* no creation and truncation flags are passed to open */
+       flags = OFLAGS(ap->a_mode);
+       flags &= ~O_CREAT;
+       flags &= ~O_EXCL;
+       flags &= ~O_TRUNC;
+
        error = fusefs_file_open(fmp, ip, fufh_type, flags, isdir, ap->a_p);
        if (error)
                return (error);
 
-       return (error);
+       return (0);
 }
 
 int
@@ -891,16 +894,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';
@@ -908,7 +910,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: lib/libfuse/fuse_ops.c
===================================================================
RCS file: /cvs/src/lib/libfuse/fuse_ops.c,v
retrieving revision 1.27
diff -u -p -p -u -r1.27 fuse_ops.c
--- lib/libfuse/fuse_ops.c      17 Nov 2017 15:45:17 -0000      1.27
+++ lib/libfuse/fuse_ops.c      18 Nov 2017 01:58:34 -0000
@@ -579,6 +579,8 @@ ifuse_ops_write(struct fuse *f, struct f
        return (0);
 }
 
+#if 0
+/* fuse create requires the kernel to support atomic_open() */
 static int
 ifuse_ops_create(struct fuse *f, struct fusebuf *fbuf)
 {
@@ -611,8 +613,6 @@ ifuse_ops_create(struct fuse *f, struct 
 
        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;
 
@@ -625,6 +625,7 @@ ifuse_ops_create(struct fuse *f, struct 
 
        return (0);
 }
+#endif
 
 static int
 ifuse_ops_mkdir(struct fuse *f, struct fusebuf *fbuf)
@@ -1125,9 +1126,11 @@ ifuse_exec_opcode(struct fuse *f, struct
        case FBT_ACCESS:
                ret = ifuse_ops_access(f, fbuf);
                break;
+#if 0
        case FBT_CREATE:
                ret = ifuse_ops_create(f, fbuf);
                break;
+#endif
        case FBT_SYMLINK:
                ret = ifuse_ops_symlink(f, fbuf);
                break;

Reply via email to