From owner-svn-src-projects@freebsd.org Fri May 10 15:02:31 2019 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C503715A4D9E for ; Fri, 10 May 2019 15:02:30 +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 64F3974569; Fri, 10 May 2019 15:02:30 +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 416D65F19; Fri, 10 May 2019 15:02:30 +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 x4AF2UIQ034090; Fri, 10 May 2019 15:02:30 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4AF2TuH034088; Fri, 10 May 2019 15:02:29 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905101502.x4AF2TuH034088@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Fri, 10 May 2019 15:02:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r347431 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs X-SVN-Commit-Revision: 347431 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 64F3974569 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.94 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.996,0]; NEURAL_HAM_SHORT(-0.94)[-0.943,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 May 2019 15:02:31 -0000 Author: asomers Date: Fri May 10 15:02:29 2019 New Revision: 347431 URL: https://svnweb.freebsd.org/changeset/base/347431 Log: fusefs: fix running multiple daemons concurrently When a FUSE daemon dies or closes /dev/fuse, all of that daemon's pending requests must be terminated. Previously that was done in /dev/fuse's .d_close method. However, d_close only gets called on the *last* close of the device. That means that if multiple daemons were running concurrently, all but the last daemon to close would leave their I/O hanging around. The problem was easily visible just by running "kyua -v parallelism=2 test" in fusefs's test directory. Fix this bug by terminating a daemon's pending I/O during /dev/fuse's cdvpriv dtor method instead. That method runs on every close of a file. Also, fix some potential races in the tests: * Clear SA_RESTART when registering the daemon's signal handler so read(2) will return EINTR. * Wait for the daemon to die before unmounting the mountpoint, so we won't see an unwanted FUSE_DESTROY operation in the mock file system. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_device.c projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Modified: projects/fuse2/sys/fs/fuse/fuse_device.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_device.c Fri May 10 13:41:19 2019 (r347430) +++ projects/fuse2/sys/fs/fuse/fuse_device.c Fri May 10 15:02:29 2019 (r347431) @@ -94,14 +94,12 @@ SDT_PROBE_DEFINE2(fusefs, , device, trace, "int", "cha static struct cdev *fuse_dev; 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_open = fuse_device_open, - .d_close = fuse_device_close, .d_name = "fuse", .d_poll = fuse_device_poll, .d_read = fuse_device_read, @@ -119,8 +117,31 @@ 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); + FUSE_UNLOCK(); + fdata_trydestroy(fdata); } @@ -142,41 +163,6 @@ fuse_device_open(struct cdev *dev, int oflags, int dev else 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(fusefs, , device, trace, 1, "device close"); - return (0); } int Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Fri May 10 13:41:19 2019 (r347430) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Fri May 10 15:02:29 2019 (r347431) @@ -147,7 +147,7 @@ ReturnImmediate(std::function &out) { + if (verbosity > 1) + printf("%-11s REJECTED (wrong pid %d)\n", + opcode2opname(in->header.opcode), in->header.pid); auto out0 = new mockfs_buf_out; out0->header.unique = in->header.unique; out0->header.error = -EOPNOTSUPP;