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. The additional call to open results in a node having one extra reference on release.
The Linux version of fuse.h states the following for create. * Create and open a file * * If the file does not exist, first create it with the specified * mode, and then open it. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. * * Introduced in version 2.5 The VOP_CREATE(9) function does not behave like this so we either need to simulate it within fuse or fall back to mknod() and open(). Note that fuse mknod DOES allow the creation of regular files so doesn't map completely 1:1 to OpenBSDs mknod(2). Linux has the atomic_open system call, which maps 1:1 to fuse create. The following patch is the first pass at changing the behaviour of fusefs_create so that it maps 1:1 to fuse mknod. If this approach is accepted, we should consider lowering FUSE_VERSION in fuse.h to 24 so that file systems can check the supported fuse version at compile time to determine whether create is available. The only port that currently does not implement mknod is fuse-zip. It should not be difficult to patch this. An alternative and more complicated patch is to modify fusefs_create to store the file handle returned by the file system in the same way that fusefs_open does and then not open the file again. The downside of this is that fusefs_create does not receive the open flags from the vn_open vfs system call so cannot pass these onto the fuse file system. Let me know if you would like to see this alternative patch. 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 -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 8 Nov 2017 13:38:04 -0000 @@ -891,13 +891,13 @@ 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; @@ -908,7 +908,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.26 diff -u -p -r1.26 fuse_ops.c --- lib/libfuse/fuse_ops.c 7 Sep 2016 17:53:35 -0000 1.26 +++ lib/libfuse/fuse_ops.c 8 Nov 2017 13:38:05 -0000 @@ -598,8 +598,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;