From owner-svn-src-stable-12@freebsd.org Sun Sep 15 04:14:33 2019 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 83B54DEF94; Sun, 15 Sep 2019 04:14:33 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46WGGx3SWgz3RK8; Sun, 15 Sep 2019 04:14:33 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 415B128D9; Sun, 15 Sep 2019 04:14:33 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x8F4EXO5066723; Sun, 15 Sep 2019 04:14:33 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x8F4EVBa066714; Sun, 15 Sep 2019 04:14:31 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201909150414.x8F4EVBa066714@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Sun, 15 Sep 2019 04:14:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r352351 - in stable/12: . etc/mtree sbin/mount_fusefs share/man/man5 sys/fs/fuse sys/sys tests/sys/fs tests/sys/fs/fusefs X-SVN-Group: stable-12 X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: in stable/12: . etc/mtree sbin/mount_fusefs share/man/man5 sys/fs/fuse sys/sys tests/sys/fs tests/sys/fs/fusefs X-SVN-Commit-Revision: 352351 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Sep 2019 04:14:33 -0000 Author: asomers Date: Sun Sep 15 04:14:31 2019 New Revision: 352351 URL: https://svnweb.freebsd.org/changeset/base/352351 Log: MFC the new fusefs driver MFC r350665, r350990, r350992, r351039, r351042, r351061, r351066, r351113, r351560, r351961, r351963, r352021, r352025, r352230 r350665: fusefs: merge from projects/fuse2 This commit imports the new fusefs driver. It raises the protocol level from 7.8 to 7.23, fixes many bugs, adds a test suite for the driver, and adds many new features. New features include: * Optional kernel-side permissions checks (-o default_permissions) * Implement VOP_MKNOD, VOP_BMAP, and VOP_ADVLOCK * Allow interrupting FUSE operations * Support named pipes and unix-domain sockets in fusefs file systems * Forward UTIME_NOW during utimensat(2) to the daemon * kqueue support for /dev/fuse * Allow updating mounts with "mount -u" * Allow exporting fusefs file systems over NFS * Server-initiated invalidation of the name cache or data cache * Respect RLIMIT_FSIZE * Try to support servers as old as protocol 7.4 Performance enhancements include: * Implement FUSE's FOPEN_KEEP_CACHE and FUSE_ASYNC_READ flags * Cache file attributes * Cache lookup entries, both positive and negative * Server-selectable cache modes: writethrough, writeback, or uncached * Write clustering * Readahead * Use counter(9) for statistical reporting PR: 199934 216391 233783 234581 235773 235774 235775 PR: 236226 236231 236236 236291 236329 236381 236405 PR: 236327 236466 236472 236473 236474 236530 236557 PR: 236560 236844 237052 237181 237588 238565 Reviewed by: bcr (man pages) Reviewed by: cem, ngie, rpokala, glebius, kib, bde, emaste (post-commit review on project branch) Relnotes: yes Sponsored by: The FreeBSD Foundation Pull Request: https://reviews.freebsd.org/D21110 r350990: fusefs: add SVN Keywords to the test files Reported by: SVN pre-commit hooks MFC-With: r350665 Sponsored by: The FreeBSD Foundation r350992: fusefs: skip some tests when unsafe aio is disabled MFC-With: r350665 Sponsored by: The FreeBSD Foundation r351039: fusefs: fix intermittency in the default_permissions.Unlink.ok test The test needs to expect a FUSE_FORGET operation. Most of the time the test would pass anyway, because by chance FUSE_FORGET would arrive after the unmount. MFC-With: 350665 Sponsored by: The FreeBSD Foundation r351042: fusefs: Fix the size of fuse_getattr_in In FUSE protocol 7.9, the size of the FUSE_GETATTR request has increased. However, the fusefs driver is currently not sending the additional fields. In our implementation, the additional fields are always zero, so I there haven't been any test failures until now. But fusefs-lkl requires the request's length to be correct. Fix this bug, and also enhance the test suite to catch similar bugs. PR: 239830 MFC-With: 350665 Sponsored by: The FreeBSD Foundation r351061: fusefs: fix the 32-bit build after 351042 Reported by: jhb MFC-With: 351042 Sponsored by: The FreeBSD Foundation r351066: fusefs: fix conditional from r351061 The entirety of r351061 was a copy/paste error. I'm sorry I've been comitting so hastily. Reported by: rpokala Reviewed by: rpokala MFC-With: 351061 Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21265 r351113: fusefs: don't send the namespace during listextattr The FUSE_LISTXATTR operation always returns the full list of a file's extended attributes, in all namespaces. There's no way to filter the list server-side. However, currently FreeBSD's fusefs driver sends a namespace string with the FUSE_LISTXATTR request. That behavior was probably copied from fuse_vnop_getextattr, which has an attribute name argument. It's been there ever since extended attribute support was added in r324620. This commit removes it. Reviewed by: cem Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21280 r351560: fusefs: Fix some bugs regarding the size of the LISTXATTR list * A small error in r338152 let to the returned size always being exactly eight bytes too large. * The FUSE_LISTXATTR operation works like Linux's listxattr(2): if the caller does not provide enough space, then the server should return ERANGE rather than return a truncated list. That's true even though in FUSE's case the kernel doesn't provide space to the client at all; it simply requests a maximum size for the list. We previously weren't handling the case where the server returns ERANGE even though the kernel requested as much size as the server had told us it needs; that can happen due to a race. * We also need to ensure that a pathological server that always returns ERANGE no matter what size we request in FUSE_LISTXATTR won't cause an infinite loop in the kernel. As of this commit, it will instead cause an infinite loop that exits and enters the kernel on each iteration, allowing signals to be processed. Reviewed by: cem Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21287 r351961: Coverity fixes in fusefs(5) CID 1404532 fixes a signed vs unsigned comparison error in fuse_vnop_bmap. It could potentially have resulted in VOP_BMAP reporting too many consecutive blocks. CID 1404364 is much worse. It was an array access by an untrusted, user-provided variable. It could potentially have resulted in a malicious file system crashing the kernel or worse. Reported by: Coverity Reviewed by: emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21466 r351963: fusefs: coverity cleanup in the tests Address the following defects reported by Coverity: * Structurally dead code (CID 1404366): set m_quit before FAIL, not after * Unchecked return value of sysctlbyname (CID 1404321) * Unchecked return value of stat(2) (CID 1404471) * Unchecked return value of open(2) (CID 1404402, 1404529) * Unchecked return value of dup(2) (CID 1404478) * Buffer overflows. These are all false positives caused by the fact that Coverity thinks I'm using a buffer to store strings, when in fact I'm really just using it to store a byte array that happens to be initialized with a string. I'm changing the type from char to uint8_t in the hopes that it will placate Coverity. (CID 1404338, 1404350, 1404367, 1404376, 1404379, 1404381, 1404388, 1404403, 1404425, 1404433, 1404434, 1404474, 1404480, 1404484, 1404503, 1404505) * False positive file descriptor leak. I'm going to try to fix this with Coverity modeling, but I'll also change an EXPECT to ASSERT so we don't perform meaningless assertions after the failure. (CID 1404320, 1404324, 1404440, 1404445). * Unannotated file descriptor leak. This will be followed up by a Coverity modeling change. (CID 1404326, 1404334, 1404336, 1404357, 1404361, 1404372, 1404391, 1404395, 1404409, 1404430, 1404448, 1404451, 1404455, 1404457, 1404458, 1404460) * Uninitialized variables in C++ constructors (CID 1404327, 1404346). In the case of m_maxphys, this actually led to part of the FUSE_INIT's response being set to stack garbage during the WriteCluster::clustering test. * Uninitialized sun_len field in struct sockaddr_un (CID 1404330, 1404371, 1404429). Reported by: Coverity Reviewed by: emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21457 r352021: fusefs: suppress some Coverity resource leak CIDs in the tests The fusefs tests deliberately leak file descriptors. To do otherwise would add extra complications to the tests' mock FUSE server. This annotation should hopefully convince Coverity to shut up about the leaks. Reviewed by: uqs Sponsored by: The FreeBSD Foundation r352025: mount_fusefs: fix a segfault on memory allocation failure Reported by: Coverity Coverity CID: 1354188 Sponsored by: The FreeBSD Foundation r352230: fusefs: Fix iosize for FUSE_WRITE in 7.8 compat mode When communicating with a FUSE server that implements version 7.8 (or older) of the FUSE protocol, the FUSE_WRITE request structure is 16 bytes shorter than normal. The protocol version check wasn't applied universally, leading to an extra 16 bytes being sent to such servers. The extra bytes were allocated and bzero()d, so there was no information disclosure. Reviewed by: emaste MFC-With: r350665 Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21557 Added: stable/12/tests/sys/fs/fusefs/ - copied from r350665, head/tests/sys/fs/fusefs/ Deleted: stable/12/sys/fs/fuse/fuse_param.h Modified: stable/12/MAINTAINERS stable/12/UPDATING stable/12/etc/mtree/BSD.tests.dist stable/12/sbin/mount_fusefs/mount_fusefs.8 stable/12/sbin/mount_fusefs/mount_fusefs.c stable/12/share/man/man5/fusefs.5 stable/12/sys/fs/fuse/fuse.h stable/12/sys/fs/fuse/fuse_device.c stable/12/sys/fs/fuse/fuse_file.c stable/12/sys/fs/fuse/fuse_file.h stable/12/sys/fs/fuse/fuse_internal.c stable/12/sys/fs/fuse/fuse_internal.h stable/12/sys/fs/fuse/fuse_io.c stable/12/sys/fs/fuse/fuse_io.h stable/12/sys/fs/fuse/fuse_ipc.c stable/12/sys/fs/fuse/fuse_ipc.h stable/12/sys/fs/fuse/fuse_kernel.h stable/12/sys/fs/fuse/fuse_main.c stable/12/sys/fs/fuse/fuse_node.c stable/12/sys/fs/fuse/fuse_node.h stable/12/sys/fs/fuse/fuse_vfsops.c stable/12/sys/fs/fuse/fuse_vnops.c stable/12/sys/sys/param.h stable/12/tests/sys/fs/Makefile stable/12/tests/sys/fs/fusefs/access.cc stable/12/tests/sys/fs/fusefs/allow_other.cc stable/12/tests/sys/fs/fusefs/bmap.cc stable/12/tests/sys/fs/fusefs/create.cc stable/12/tests/sys/fs/fusefs/default_permissions.cc stable/12/tests/sys/fs/fusefs/default_permissions_privileged.cc stable/12/tests/sys/fs/fusefs/destroy.cc stable/12/tests/sys/fs/fusefs/dev_fuse_poll.cc stable/12/tests/sys/fs/fusefs/fifo.cc stable/12/tests/sys/fs/fusefs/flush.cc stable/12/tests/sys/fs/fusefs/forget.cc stable/12/tests/sys/fs/fusefs/fsync.cc stable/12/tests/sys/fs/fusefs/fsyncdir.cc stable/12/tests/sys/fs/fusefs/getattr.cc stable/12/tests/sys/fs/fusefs/interrupt.cc stable/12/tests/sys/fs/fusefs/io.cc stable/12/tests/sys/fs/fusefs/link.cc stable/12/tests/sys/fs/fusefs/locks.cc stable/12/tests/sys/fs/fusefs/lookup.cc stable/12/tests/sys/fs/fusefs/mkdir.cc stable/12/tests/sys/fs/fusefs/mknod.cc stable/12/tests/sys/fs/fusefs/mockfs.cc stable/12/tests/sys/fs/fusefs/mockfs.hh (contents, props changed) stable/12/tests/sys/fs/fusefs/mount.cc stable/12/tests/sys/fs/fusefs/nfs.cc stable/12/tests/sys/fs/fusefs/notify.cc stable/12/tests/sys/fs/fusefs/open.cc stable/12/tests/sys/fs/fusefs/opendir.cc stable/12/tests/sys/fs/fusefs/read.cc stable/12/tests/sys/fs/fusefs/readdir.cc stable/12/tests/sys/fs/fusefs/readlink.cc stable/12/tests/sys/fs/fusefs/release.cc stable/12/tests/sys/fs/fusefs/releasedir.cc stable/12/tests/sys/fs/fusefs/rename.cc stable/12/tests/sys/fs/fusefs/rmdir.cc stable/12/tests/sys/fs/fusefs/setattr.cc stable/12/tests/sys/fs/fusefs/statfs.cc stable/12/tests/sys/fs/fusefs/symlink.cc stable/12/tests/sys/fs/fusefs/unlink.cc stable/12/tests/sys/fs/fusefs/utils.cc stable/12/tests/sys/fs/fusefs/utils.hh (contents, props changed) stable/12/tests/sys/fs/fusefs/write.cc stable/12/tests/sys/fs/fusefs/xattr.cc Directory Properties: stable/12/ (props changed) Modified: stable/12/MAINTAINERS ============================================================================== --- stable/12/MAINTAINERS Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/MAINTAINERS Sun Sep 15 04:14:31 2019 (r352351) @@ -50,6 +50,7 @@ dev/usb/wlan adrian Pre-commit review requested, send etc/mail gshapiro Pre-commit review requested. Keep in sync with -STABLE. etc/sendmail gshapiro Pre-commit review requested. Keep in sync with -STABLE. fetch des Pre-commit review requested, email only. +fusefs(5) asomers Pre-commit review requested. geli pjd Pre-commit review requested (both sys/geom/eli/ and sbin/geom/class/eli/). isci(4) jimharris Pre-commit review requested. iwm(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org Modified: stable/12/UPDATING ============================================================================== --- stable/12/UPDATING Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/UPDATING Sun Sep 15 04:14:31 2019 (r352351) @@ -16,6 +16,18 @@ from older versions of FreeBSD, try WITHOUT_CLANG and the tip of head, and then rebuild without this option. The bootstrap process from older version of current across the gcc/clang cutover is a bit fragile. +20190914: + The vfs.fusefs.sync_unmount and vfs.fusefs.init_backgrounded sysctls + and the "-o sync_unmount" and "-o init_backgrounded" mount options have + been removed from mount_fusefs(8). You can safely remove them from + your scripts, because they had no effect. + + The vfs.fusefs.fix_broken_io, vfs.fusefs.sync_resize, + vfs.fusefs.refresh_size, vfs.fusefs.mmap_enable, + vfs.fusefs.reclaim_revoked, and vfs.fusefs.data_cache_invalidate + sysctls have been removed. If you felt the need to set any of them to + a non-default value, please tell asomers@FreeBSD.org why. + 20190906: The fuse(4) module has been renamed to fusefs(4) for consistency with other filesystems. You should update any kld_load="fuse" entries in Modified: stable/12/etc/mtree/BSD.tests.dist ============================================================================== --- stable/12/etc/mtree/BSD.tests.dist Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/etc/mtree/BSD.tests.dist Sun Sep 15 04:14:31 2019 (r352351) @@ -717,6 +717,8 @@ file .. fs + fusefs + .. tmpfs .. .. Modified: stable/12/sbin/mount_fusefs/mount_fusefs.8 ============================================================================== --- stable/12/sbin/mount_fusefs/mount_fusefs.8 Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/sbin/mount_fusefs/mount_fusefs.8 Sun Sep 15 04:14:31 2019 (r352351) @@ -3,6 +3,11 @@ .\" Copyright (c) 2005, 2006 Csaba Henk .\" All rights reserved. .\" +.\" Copyright (c) 2019 The FreeBSD Foundation +.\" +.\" Portions of this documentation were written by BFF Storage Systems under +.\" sponsorship from the FreeBSD Foundation. +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: @@ -29,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 17, 2018 +.Dd July 31, 2019 .Dt MOUNT_FUSEFS 8 .Os .Sh NAME @@ -108,27 +113,27 @@ Intended for use in scripts and the .Xr sudoers 5 file. .It Fl S , Ic --safe -Run in safe mode (i.e. reject invoking a filesystem daemon) +Run in safe mode (i.e., reject invoking a filesystem daemon). .It Fl v -Be verbose -.It Fl D, Ic --daemon Ar daemon +Be verbose. +.It Fl D , Ic --daemon Ar daemon Call the specified -.Ar daemon -.It Fl O, Ic --daemon_opts Ar opts +.Ar daemon . +.It Fl O , Ic --daemon_opts Ar opts Add .Ar opts -to the daemon's command line -.It Fl s, Ic --special Ar special +to the daemon's command line. +.It Fl s , Ic --special Ar special Use .Ar special -as special -.It Fl m, Ic --mountpath Ar node +as special. +.It Fl m , Ic --mountpath Ar node Mount on -.Ar node -.It Fl h, Ic --help -Show help -.It Fl V, Ic --version -Show version information +.Ar node . +.It Fl h , Ic --help +Show help. +.It Fl V , Ic --version +Show version information. .It Fl o Mount options are specified via .Fl o . @@ -136,23 +141,38 @@ The following options are available (and also their ne by prefixing them with .Dq no ) : .Bl -tag -width indent -.It Cm default_permissions -Enable traditional (file mode based) permission checking in kernel .It Cm allow_other Do not apply .Sx STRICT ACCESS POLICY . -Only root can use this option +Only root can use this option. +.It Cm async +I/O to the file system may be done asynchronously. +Writes may be delayed and/or reordered. +.It Cm default_permissions +Enable traditional (file mode based) permission checking in kernel. +.It Cm intr +Allow signals to interrupt operations that are blocked waiting for a reply from the server. +When this option is in use, system calls may fail with +.Er EINTR +whenever a signal is received. .It Cm max_read Ns = Ns Ar n Limit size of read requests to -.Ar n +.Ar n . +.It Cm neglect_shares +Do not refuse unmounting if there are secondary mounts. .It Cm private Refuse shared mounting of the daemon. This is the default behaviour, to allow sharing, expicitly use -.Fl o Cm noprivate -.It Cm neglect_shares -Do not refuse unmounting if there are secondary mounts +.Fl o Cm noprivate . .It Cm push_symlinks_in -Prefix absolute symlinks with the mountpoint +Prefix absolute symlinks with the mountpoint. +.It Cm subtype Ns = Ns Ar fsname +Suffix +.Ar fsname +to the file system name as reported by +.Xr statfs 2 . +This option can be used to identify the file system implemented by +.Ar fuse_daemon . .El .El .Pp @@ -167,11 +187,11 @@ However, there are some which do require in-kernel sup Currently the options supported by the kernel are: .Bl -tag -width indent .It Cm direct_io -Bypass the buffer cache system +Bypass the buffer cache system. .It Cm kernel_cache By default cached buffers of a given file are flushed at each .Xr open 2 . -This option disables this behaviour +This option disables this behaviour. .El .Sh DAEMON MOUNTS Usually users do not need to use @@ -194,7 +214,7 @@ only if the filesystem daemon has the same credentials real gid) as the user. .Pp This is applied for Fuse mounts by default and only root can mount without -the strict access policy (i.e. the +the strict access policy (i.e., the .Cm allow_other mount option). .Pp @@ -206,7 +226,7 @@ Users might opt to willingly relax strict access polic are concerned) by doing their own secondary mount (See .Sx SHARED MOUNTS ) . .Sh SHARED MOUNTS -A Fuse daemon can be shared (i.e. mounted multiple times). +A Fuse daemon can be shared (i.e., mounted multiple times). When doing the first (primary) mount, the spawner and the mounter of the daemon must have the same uid, or the mounter should be the superuser. .Pp @@ -225,7 +245,7 @@ is used or not. .Pp The device name of a secondary mount is the device name of the corresponding primary mount, followed by a '#' character and the index of the secondary -mount; e.g. +mount; e.g., .Pa /dev/fuse0#3 . .Sh SECURITY System administrators might want to use a custom mount policy (ie., one going @@ -239,7 +259,7 @@ However, given that is capable of invoking an arbitrary program, one must be careful when doing this. .Nm is designed in a way such that it makes that easy. -For this purpose, there are options which disable certain risky features (i.e. +For this purpose, there are options which disable certain risky features ( .Fl S and .Fl A ) , @@ -342,7 +362,7 @@ does not call any external utility and also provides a was written as the part of the .Fx implementation of the Fuse userspace filesystem framework (see -.Xr https://github.com/libfuse/libfuse ) +.Lk https://github.com/libfuse/libfuse ) and first appeared in the .Pa sysutils/fusefs-kmod port, supporting Modified: stable/12/sbin/mount_fusefs/mount_fusefs.c ============================================================================== --- stable/12/sbin/mount_fusefs/mount_fusefs.c Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/sbin/mount_fusefs/mount_fusefs.c Sun Sep 15 04:14:31 2019 (r352351) @@ -5,6 +5,11 @@ * Copyright (c) 2005 Csaba Henk * All rights reserved. * + * Copyright (c) 2019 The FreeBSD Foundation + * + * Portions of this software were developed by BFF Storage Systems under + * sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -60,7 +65,6 @@ void __usage_short(void); void usage(void); void helpmsg(void); void showversion(void); -int init_backgrounded(void); static struct mntopt mopts[] = { #define ALTF_PRIVATE 0x01 @@ -73,8 +77,6 @@ static struct mntopt mopts[] = { { "max_read=", 0, ALTF_MAXREAD, 1 }, #define ALTF_SUBTYPE 0x40 { "subtype=", 0, ALTF_SUBTYPE, 1 }, - #define ALTF_SYNC_UNMOUNT 0x80 - { "sync_unmount", 0, ALTF_SYNC_UNMOUNT, 1 }, /* * MOPT_AUTOMOUNTED, included by MOPT_STDOPTS, does not fit into * the 'flags' argument to nmount(2). We have to abuse altflags @@ -82,6 +84,8 @@ static struct mntopt mopts[] = { */ #define ALTF_AUTOMOUNTED 0x100 { "automounted", 0, ALTF_AUTOMOUNTED, 1 }, + #define ALTF_INTR 0x200 + { "intr", 0, ALTF_INTR, 1 }, /* Linux specific options, we silently ignore them */ { "fsname=", 0, 0x00, 1 }, { "fd=", 0, 0x00, 1 }, @@ -91,6 +95,8 @@ static struct mntopt mopts[] = { { "large_read", 0, 0x00, 1 }, /* "nonempty", just the first two chars are stripped off during parsing */ { "nempty", 0, 0x00, 1 }, + { "async", 0, MNT_ASYNC, 0}, + { "noasync", 1, MNT_ASYNC, 0}, MOPT_STDOPTS, MOPT_END }; @@ -107,7 +113,7 @@ static struct mntval mvals[] = { { 0, NULL, 0 } }; -#define DEFAULT_MOUNT_FLAGS ALTF_PRIVATE | ALTF_SYNC_UNMOUNT +#define DEFAULT_MOUNT_FLAGS ALTF_PRIVATE int main(int argc, char *argv[]) @@ -206,6 +212,8 @@ main(int argc, char *argv[]) q++; mv->mv_len = q - p + 1; mv->mv_value = malloc(mv->mv_len); + if (mv->mv_value == NULL) + err(1, "malloc"); memcpy(mv->mv_value, p, mv->mv_len - 1); ((char *)mv->mv_value)[mv->mv_len - 1] = '\0'; break; @@ -409,12 +417,6 @@ main(int argc, char *argv[]) } } - if (fd >= 0 && ! init_backgrounded() && close(fd) < 0) { - if (pid) - kill(pid, SIGKILL); - err(1, "failed to close fuse device"); - } - /* Prepare the options vector for nmount(). build_iovec() is declared * in mntopts.h. */ sprintf(fdstr, "%d", fd); @@ -471,6 +473,7 @@ helpmsg(void) " -o allow_other allow access to other users\n" /* " -o nonempty allow mounts over non-empty file/dir\n" */ " -o default_permissions enable permission checking by kernel\n" + " -o intr interruptible mount\n" /* " -o fsname=NAME set filesystem name\n" " -o large_read issue large read requests (2.4 only)\n" @@ -481,7 +484,6 @@ helpmsg(void) " -o neglect_shares don't report EBUSY when unmount attempted\n" " in presence of secondary mounts\n" " -o push_symlinks_in prefix absolute symlinks with mountpoint\n" - " -o sync_unmount do unmount synchronously\n" ); exit(EX_USAGE); } @@ -491,18 +493,4 @@ showversion(void) { puts("mount_fusefs [fuse4bsd] version: " FUSE4BSD_VERSION); exit(EX_USAGE); -} - -int -init_backgrounded(void) -{ - int ibg; - size_t len; - - len = sizeof(ibg); - - if (sysctlbyname("vfs.fusefs.init_backgrounded", &ibg, &len, NULL, 0)) - return (0); - - return (ibg); } Modified: stable/12/share/man/man5/fusefs.5 ============================================================================== --- stable/12/share/man/man5/fusefs.5 Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/share/man/man5/fusefs.5 Sun Sep 15 04:14:31 2019 (r352351) @@ -3,8 +3,8 @@ .\" .\" Copyright (c) 2019 The FreeBSD Foundation .\" -.\" This software was developed by BFF Storage Systems, LLC under sponsorship -.\" from the FreeBSD Foundation. +.\" This documentation was written by BFF Storage Systems, LLC under +.\" sponsorship from the FreeBSD Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -28,7 +28,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd April 13, 2019 +.Dd July 31, 2019 .Dt FUSEFS 5 .Os .Sh NAME @@ -60,11 +60,9 @@ Finally, the API is portable. Many daemons can run on multiple operating systems with minimal modifications. .Sh SYSCTL VARIABLES -The following variables are available as both +The following .Xr sysctl 8 -variables and -.Xr loader 8 -tunables: +variables are available: .Bl -tag -width indent .It Va vfs.fusefs.kernelabi_major Major version of the FUSE kernel ABI supported by this driver. @@ -73,7 +71,7 @@ Minor version of the FUSE kernel ABI supported by this .It Va vfs.fusefs.data_cache_mode Controls how .Nm -will cache file data. +will cache file data for pre-7.23 file systems. A value of 0 will disable caching entirely. Every data access will be forwarded to the daemon. A value of 1 will select write-through caching. @@ -84,33 +82,26 @@ Reads and writes will both be cached, and writes will to the daemon by the page daemon. Write-back caching is usually unsafe, especially for FUSE file systems that require network access. -.It Va vfs.fusefs.lookup_cache_enable -Controls whether -.Nm -will cache lookup responses from the file system. -FUSE file systems indicate whether lookup responses should be cacheable, but -it may be useful to globally disable caching them if a file system is -misbehaving. +.Pp +FUSE file systems using protocol 7.23 or later specify their cache behavior +on a per-mountpoint basis, ignoring this sysctl. +.It Va vfs.fusefs.stats.filehandle_count +Current number of open FUSE file handles. +.It Va vfs.fusefs.stats.lookup_cache_hits +Total number of lookup cache hits. +.It Va vfs.fusefs.stats.lookup_cache_misses +Total number of lookup cache misses. +.It Va vfs.fusefs.stats.node_count +Current number of allocated FUSE vnodes. +.It Va vfs.fusefs.stats.ticket_count +Current number of allocated FUSE tickets, which is roughly equal to the number +of FUSE operations currently being processed by daemons. .\" Undocumented sysctls .\" ==================== -.\" Counters: I intend to rename to vfs.fusefs.stats.* for clarity -.\" vfs.fusefs.lookup_cache_{hits, misses} -.\" vfs.fusefs.filehandle_count -.\" vfs.fusefs.ticker_count -.\" vfs.fusefs.node_count -.\" -.\" vfs.fusefs.version - useless since the driver moved in-tree -.\" vfs.fusefs.reclaim_revoked: I don't understand it well-enough -.\" vfs.fusefs.sync_unmount: dead code .\" vfs.fusefs.enforce_dev_perms: I don't understand it well enough. -.\" vfs.fusefs.init_backgrounded: dead code .\" vfs.fusefs.iov_credit: I don't understand it well enough .\" vfs.fusefs.iov_permanent_bufsize: I don't understand it well enough -.\" vfs.fusefs.fix_broken_io: I don't understand it well enough -.\" vfs.fusefs.sync_resize: useless and should be removed -.\" vfs.fusefs.refresh_size: probably useless? -.\" vfs.fusefs.mmap_enable: why is this optional? -.\" vfs.fusefs.data_cache_invalidate: what is this needed for? +.El .Sh SEE ALSO .Xr mount_fusefs 8 .Sh HISTORY @@ -119,7 +110,7 @@ The driver was written as the part of the .Fx implementation of the FUSE userspace file system framework (see -.Xr https://github.com/libfuse/libfuse ) +.Lk https://github.com/libfuse/libfuse ) and first appeared in the .Pa sysutils/fusefs-kmod port, supporting Modified: stable/12/sys/fs/fuse/fuse.h ============================================================================== --- stable/12/sys/fs/fuse/fuse.h Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/sys/fs/fuse/fuse.h Sun Sep 15 04:14:31 2019 (r352351) @@ -32,6 +32,11 @@ * * Copyright (C) 2005 Csaba Henk. * All rights reserved. + * + * Copyright (c) 2019 The FreeBSD Foundation + * + * Portions of this software were developed by BFF Storage Systems, LLC under + * sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -63,87 +68,10 @@ #define FUSE_MIN_DAEMON_TIMEOUT 0 /* s */ #define FUSE_MAX_DAEMON_TIMEOUT 600 /* s */ -#ifndef FUSE_FREEBSD_VERSION -#define FUSE_FREEBSD_VERSION "0.4.4" -#endif - -/* Mapping versions to features */ - -#define FUSE_KERNELABI_GEQ(maj, min) \ -(FUSE_KERNEL_VERSION > (maj) || (FUSE_KERNEL_VERSION == (maj) && FUSE_KERNEL_MINOR_VERSION >= (min))) - -/* - * Appearance of new FUSE operations is not always in par with version - * numbering... At least, 7.3 is a sufficient condition for having - * FUSE_{ACCESS,CREATE}. - */ -#if FUSE_KERNELABI_GEQ(7, 3) -#ifndef FUSE_HAS_ACCESS -#define FUSE_HAS_ACCESS 1 -#endif -#ifndef FUSE_HAS_CREATE -#define FUSE_HAS_CREATE 1 -#endif -#else /* FUSE_KERNELABI_GEQ(7, 3) */ -#ifndef FUSE_HAS_ACCESS -#define FUSE_HAS_ACCESS 0 -#endif -#ifndef FUSE_HAS_CREATE -#define FUSE_HAS_CREATE 0 -#endif -#endif - -#if FUSE_KERNELABI_GEQ(7, 7) -#ifndef FUSE_HAS_GETLK -#define FUSE_HAS_GETLK 1 -#endif -#ifndef FUSE_HAS_SETLK -#define FUSE_HAS_SETLK 1 -#endif -#ifndef FUSE_HAS_SETLKW -#define FUSE_HAS_SETLKW 1 -#endif -#ifndef FUSE_HAS_INTERRUPT -#define FUSE_HAS_INTERRUPT 1 -#endif -#else /* FUSE_KERNELABI_GEQ(7, 7) */ -#ifndef FUSE_HAS_GETLK -#define FUSE_HAS_GETLK 0 -#endif -#ifndef FUSE_HAS_SETLK -#define FUSE_HAS_SETLK 0 -#endif -#ifndef FUSE_HAS_SETLKW -#define FUSE_HAS_SETLKW 0 -#endif -#ifndef FUSE_HAS_INTERRUPT -#define FUSE_HAS_INTERRUPT 0 -#endif -#endif - -#if FUSE_KERNELABI_GEQ(7, 8) -#ifndef FUSE_HAS_FLUSH_RELEASE -#define FUSE_HAS_FLUSH_RELEASE 1 -/* - * "DESTROY" came in the middle of the 7.8 era, - * so this is not completely exact... - */ -#ifndef FUSE_HAS_DESTROY -#define FUSE_HAS_DESTROY 1 -#endif -#endif -#else /* FUSE_KERNELABI_GEQ(7, 8) */ -#ifndef FUSE_HAS_FLUSH_RELEASE -#define FUSE_HAS_FLUSH_RELEASE 0 -#ifndef FUSE_HAS_DESTROY -#define FUSE_HAS_DESTROY 0 -#endif -#endif -#endif - /* misc */ SYSCTL_DECL(_vfs_fusefs); +SYSCTL_DECL(_vfs_fusefs_stats); /* Fuse locking */ Modified: stable/12/sys/fs/fuse/fuse_device.c ============================================================================== --- stable/12/sys/fs/fuse/fuse_device.c Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/sys/fs/fuse/fuse_device.c Sun Sep 15 04:14:31 2019 (r352351) @@ -33,6 +33,11 @@ * Copyright (C) 2005 Csaba Henk. * All rights reserved. * + * Copyright (c) 2019 The FreeBSD Foundation + * + * Portions of this software were developed by BFF Storage Systems, LLC under + * sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -81,27 +86,28 @@ __FBSDID("$FreeBSD$"); #include #include "fuse.h" +#include "fuse_internal.h" #include "fuse_ipc.h" -SDT_PROVIDER_DECLARE(fuse); +SDT_PROVIDER_DECLARE(fusefs); /* * Fuse trace probe: * arg0: verbosity. Higher numbers give more verbose messages * arg1: Textual message */ -SDT_PROBE_DEFINE2(fuse, , device, trace, "int", "char*"); +SDT_PROBE_DEFINE2(fusefs, , device, trace, "int", "char*"); static struct cdev *fuse_dev; +static d_kqfilter_t fuse_device_filter; static d_open_t fuse_device_open; -static d_close_t fuse_device_close; static d_poll_t fuse_device_poll; static d_read_t fuse_device_read; static d_write_t fuse_device_write; static struct cdevsw fuse_device_cdevsw = { + .d_kqfilter = fuse_device_filter, .d_open = fuse_device_open, - .d_close = fuse_device_close, .d_name = "fuse", .d_poll = fuse_device_poll, .d_read = fuse_device_read, @@ -109,6 +115,15 @@ static struct cdevsw fuse_device_cdevsw = { .d_version = D_VERSION, }; +static int fuse_device_filt_read(struct knote *kn, long hint); +static void fuse_device_filt_detach(struct knote *kn); + +struct filterops fuse_device_rfiltops = { + .f_isfd = 1, + .f_detach = fuse_device_filt_detach, + .f_event = fuse_device_filt_read, +}; + /**************************** * * >>> Fuse device op defs @@ -119,11 +134,100 @@ static void fdata_dtor(void *arg) { struct fuse_data *fdata; + struct fuse_ticket *tick; fdata = arg; + if (fdata == NULL) + return; + + fdata_set_dead(fdata); + + FUSE_LOCK(); + fuse_lck_mtx_lock(fdata->aw_mtx); + /* wakup poll()ers */ + selwakeuppri(&fdata->ks_rsel, PZERO + 1); + /* Don't let syscall handlers wait in vain */ + while ((tick = fuse_aw_pop(fdata))) { + fuse_lck_mtx_lock(tick->tk_aw_mtx); + fticket_set_answered(tick); + tick->tk_aw_errno = ENOTCONN; + wakeup(tick); + fuse_lck_mtx_unlock(tick->tk_aw_mtx); + FUSE_ASSERT_AW_DONE(tick); + fuse_ticket_drop(tick); + } + fuse_lck_mtx_unlock(fdata->aw_mtx); + + /* Cleanup unsent operations */ + fuse_lck_mtx_lock(fdata->ms_mtx); + while ((tick = fuse_ms_pop(fdata))) { + fuse_ticket_drop(tick); + } + fuse_lck_mtx_unlock(fdata->ms_mtx); + FUSE_UNLOCK(); + fdata_trydestroy(fdata); } +static int +fuse_device_filter(struct cdev *dev, struct knote *kn) +{ + struct fuse_data *data; + int error; + + error = devfs_get_cdevpriv((void **)&data); + + /* EVFILT_WRITE is not supported; the device is always ready to write */ + if (error == 0 && kn->kn_filter == EVFILT_READ) { + kn->kn_fop = &fuse_device_rfiltops; + kn->kn_hook = data; + knlist_add(&data->ks_rsel.si_note, kn, 0); + error = 0; + } else if (error == 0) { + error = EINVAL; + kn->kn_data = error; + } + + return (error); +} + +static void +fuse_device_filt_detach(struct knote *kn) +{ + struct fuse_data *data; + + data = (struct fuse_data*)kn->kn_hook; + MPASS(data != NULL); + knlist_remove(&data->ks_rsel.si_note, kn, 0); + kn->kn_hook = NULL; +} + +static int +fuse_device_filt_read(struct knote *kn, long hint) +{ + struct fuse_data *data; + int ready; + + data = (struct fuse_data*)kn->kn_hook; + MPASS(data != NULL); + + mtx_assert(&data->ms_mtx, MA_OWNED); + if (fdata_get_dead(data)) { + kn->kn_flags |= EV_EOF; + kn->kn_fflags = ENODEV; + kn->kn_data = 1; + ready = 1; + } else if (STAILQ_FIRST(&data->ms_head)) { + MPASS(data->ms_count >= 1); + kn->kn_data = data->ms_count; + ready = 1; + } else { + ready = 0; + } + + return (ready); +} + /* * Resources are set up on a per-open basis */ @@ -133,52 +237,17 @@ fuse_device_open(struct cdev *dev, int oflags, int dev struct fuse_data *fdata; int error; - SDT_PROBE2(fuse, , device, trace, 1, "device open"); + SDT_PROBE2(fusefs, , device, trace, 1, "device open"); fdata = fdata_alloc(dev, td->td_ucred); error = devfs_set_cdevpriv(fdata, fdata_dtor); if (error != 0) fdata_trydestroy(fdata); else - SDT_PROBE2(fuse, , device, trace, 1, "device open success"); + SDT_PROBE2(fusefs, , device, trace, 1, "device open success"); return (error); } -static int -fuse_device_close(struct cdev *dev, int fflag, int devtype, struct thread *td) -{ - struct fuse_data *data; - struct fuse_ticket *tick; - int error; - - error = devfs_get_cdevpriv((void **)&data); - if (error != 0) - return (error); - if (!data) - panic("no fuse data upon fuse device close"); - fdata_set_dead(data); - - FUSE_LOCK(); - fuse_lck_mtx_lock(data->aw_mtx); - /* wakup poll()ers */ - selwakeuppri(&data->ks_rsel, PZERO + 1); - /* Don't let syscall handlers wait in vain */ - while ((tick = fuse_aw_pop(data))) { - fuse_lck_mtx_lock(tick->tk_aw_mtx); - fticket_set_answered(tick); - tick->tk_aw_errno = ENOTCONN; - wakeup(tick); - fuse_lck_mtx_unlock(tick->tk_aw_mtx); - FUSE_ASSERT_AW_DONE(tick); - fuse_ticket_drop(tick); - } - fuse_lck_mtx_unlock(data->aw_mtx); - FUSE_UNLOCK(); - - SDT_PROBE2(fuse, , device, trace, 1, "device close"); - return (0); -} - int fuse_device_poll(struct cdev *dev, int events, struct thread *td) { @@ -219,7 +288,7 @@ fuse_device_read(struct cdev *dev, struct uio *uio, in int buflen[3]; int i; - SDT_PROBE2(fuse, , device, trace, 1, "fuse device read"); + SDT_PROBE2(fusefs, , device, trace, 1, "fuse device read"); err = devfs_get_cdevpriv((void **)&data); if (err != 0) @@ -228,7 +297,7 @@ fuse_device_read(struct cdev *dev, struct uio *uio, in fuse_lck_mtx_lock(data->ms_mtx); again: if (fdata_get_dead(data)) { - SDT_PROBE2(fuse, , device, trace, 2, + SDT_PROBE2(fusefs, , device, trace, 2, "we know early on that reader should be kicked so we " "don't wait for news"); fuse_lck_mtx_unlock(data->ms_mtx); @@ -256,7 +325,7 @@ again: * -- and some other cases, too, tho not totally clear, when * (cv_signal/wakeup_one signals the whole process ?) */ - SDT_PROBE2(fuse, , device, trace, 1, "no message on thread"); + SDT_PROBE2(fusefs, , device, trace, 1, "no message on thread"); goto again; } fuse_lck_mtx_unlock(data->ms_mtx); @@ -266,9 +335,10 @@ again: * somebody somewhere -- eg., umount routine -- * wants this liaison finished off */ - SDT_PROBE2(fuse, , device, trace, 2, "reader is to be sacked"); + SDT_PROBE2(fusefs, , device, trace, 2, + "reader is to be sacked"); if (tick) { - SDT_PROBE2(fuse, , device, trace, 2, "weird -- " + SDT_PROBE2(fusefs, , device, trace, 2, "weird -- " "\"kick\" is set tho there is message"); FUSE_ASSERT_MS_DONE(tick); fuse_ticket_drop(tick); @@ -276,7 +346,7 @@ again: return (ENODEV); /* This should make the daemon get off * of us */ } - SDT_PROBE2(fuse, , device, trace, 1, + SDT_PROBE2(fusefs, , device, trace, 1, "fuse device read message successfully"); KASSERT(tick->tk_ms_bufdata || tick->tk_ms_bufsize == 0, @@ -311,7 +381,7 @@ again: */ if (uio->uio_resid < buflen[i]) { fdata_set_dead(data); - SDT_PROBE2(fuse, , device, trace, 2, + SDT_PROBE2(fusefs, , device, trace, 2, "daemon is stupid, kick it off..."); err = ENODEV; break; @@ -331,23 +401,26 @@ static inline int fuse_ohead_audit(struct fuse_out_header *ohead, struct uio *uio) { if (uio->uio_resid + sizeof(struct fuse_out_header) != ohead->len) { - SDT_PROBE2(fuse, , device, trace, 1, "Format error: body size " + SDT_PROBE2(fusefs, , device, trace, 1, + "Format error: body size " "differs from size claimed by header"); return (EINVAL); } - if (uio->uio_resid && ohead->error) { - SDT_PROBE2(fuse, , device, trace, 1, + if (uio->uio_resid && ohead->unique != 0 && ohead->error) { + SDT_PROBE2(fusefs, , device, trace, 1, "Format error: non zero error but message had a body"); return (EINVAL); } - /* Sanitize the linuxism of negative errnos */ - ohead->error = -(ohead->error); return (0); } -SDT_PROBE_DEFINE1(fuse, , device, fuse_device_write_bumped_into_callback, - "uint64_t"); +SDT_PROBE_DEFINE1(fusefs, , device, fuse_device_write_notify, + "struct fuse_out_header*"); +SDT_PROBE_DEFINE1(fusefs, , device, fuse_device_write_missing_ticket, + "uint64_t"); +SDT_PROBE_DEFINE1(fusefs, , device, fuse_device_write_found, + "struct fuse_ticket*"); /* * fuse_device_write first reads the header sent by the daemon. * If that's OK, looks up ticket/callback node by the unique id seen in header. @@ -360,15 +433,17 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i struct fuse_out_header ohead; int err = 0; struct fuse_data *data; - struct fuse_ticket *tick, *x_tick; + struct mount *mp; + struct fuse_ticket *tick, *itick, *x_tick; int found = 0; err = devfs_get_cdevpriv((void **)&data); if (err != 0) return (err); + mp = data->mp; if (uio->uio_resid < sizeof(struct fuse_out_header)) { - SDT_PROBE2(fuse, , device, trace, 1, + SDT_PROBE2(fusefs, , device, trace, 1, "fuse_device_write got less than a header!"); fdata_set_dead(data); return (EINVAL); @@ -393,15 +468,29 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i fuse_lck_mtx_lock(data->aw_mtx); TAILQ_FOREACH_SAFE(tick, &data->aw_head, tk_aw_link, x_tick) { - SDT_PROBE1(fuse, , device, - fuse_device_write_bumped_into_callback, - tick->tk_unique); if (tick->tk_unique == ohead.unique) { + SDT_PROBE1(fusefs, , device, fuse_device_write_found, + tick); found = 1; fuse_aw_remove(tick); break; } } + if (found && tick->irq_unique > 0) { + /* + * Discard the FUSE_INTERRUPT ticket that tried to interrupt + * this operation + */ + TAILQ_FOREACH_SAFE(itick, &data->aw_head, tk_aw_link, + x_tick) { + if (itick->tk_unique == tick->irq_unique) { + fuse_aw_remove(itick); + fuse_ticket_drop(itick); + break; + } + } + tick->irq_unique = 0; + } fuse_lck_mtx_unlock(data->aw_mtx); if (found) { @@ -414,13 +503,15 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i * via ticket_drop(), so no manual mucking * around...) */ - SDT_PROBE2(fuse, , device, trace, 1, + SDT_PROBE2(fusefs, , device, trace, 1, "pass ticket to a callback"); + /* Sanitize the linuxism of negative errnos */ + ohead.error *= -1; memcpy(&tick->tk_aw_ohead, &ohead, sizeof(ohead)); err = tick->tk_aw_handler(tick, uio); } else { /* pretender doesn't wanna do anything with answer */ - SDT_PROBE2(fuse, , device, trace, 1, + SDT_PROBE2(fusefs, , device, trace, 1, "stuff devalidated, so we drop it"); } @@ -430,11 +521,51 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i * because fuse_ticket_drop() will deal with refcount anyway. */ fuse_ticket_drop(tick); + } else if (ohead.unique == 0){ + /* unique == 0 means asynchronous notification */ + SDT_PROBE1(fusefs, , device, fuse_device_write_notify, &ohead); + switch (ohead.error) { + case FUSE_NOTIFY_INVAL_ENTRY: + err = fuse_internal_invalidate_entry(mp, uio); + break; + case FUSE_NOTIFY_INVAL_INODE: + err = fuse_internal_invalidate_inode(mp, uio); + break; + case FUSE_NOTIFY_RETRIEVE: + case FUSE_NOTIFY_STORE: + /* + * Unimplemented. I don't know of any file systems + * that use them, and the protocol isn't sound anyway, + * since the notification messages don't include the + * inode's generation number. Without that, it's + * possible to manipulate the cache of the wrong vnode. + * Finally, it's not defined what this message should + * do for a file with dirty cache. + */ + case FUSE_NOTIFY_POLL: + /* Unimplemented. See comments in fuse_vnops */ + default: + /* Not implemented */ + err = ENOSYS; + } } else { /* no callback at all! */ - SDT_PROBE2(fuse, , device, trace, 1, - "erhm, no handler for this response"); - err = EINVAL; + SDT_PROBE1(fusefs, , device, fuse_device_write_missing_ticket, + ohead.unique); + if (ohead.error == -EAGAIN) { + /* + * This was probably a response to a FUSE_INTERRUPT + * operation whose original operation is already + * complete. We can't store FUSE_INTERRUPT tickets + * indefinitely because their responses are optional. + * So we delete them when the original operation + * completes. And sadly the fuse_header_out doesn't + * identify the opcode, so we have to guess. + */ + err = 0; + } else { + err = EINVAL; + } } return (err); @@ -445,7 +576,7 @@ fuse_device_init(void) { fuse_dev = make_dev(&fuse_device_cdevsw, 0, UID_ROOT, GID_OPERATOR, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, "fuse"); + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, "fuse"); if (fuse_dev == NULL) return (ENOMEM); return (0); Modified: stable/12/sys/fs/fuse/fuse_file.c ============================================================================== --- stable/12/sys/fs/fuse/fuse_file.c Sun Sep 15 02:59:53 2019 (r352350) +++ stable/12/sys/fs/fuse/fuse_file.c Sun Sep 15 04:14:31 2019 (r352351) @@ -33,6 +33,11 @@ * Copyright (C) 2005 Csaba Henk. * All rights reserved. * + * Copyright (c) 2019 The FreeBSD Foundation + * + * Portions of this software were developed by BFF Storage Systems, LLC under + * sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -59,8 +64,9 @@ __FBSDID("$FreeBSD$"); #include -#include #include *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***