From owner-dev-commits-src-branches@freebsd.org Tue Jul 27 17:04:53 2021 Return-Path: Delivered-To: dev-commits-src-branches@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 4BB256646E7; Tue, 27 Jul 2021 17:04:53 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GZ37T1gl5z4nmJ; Tue, 27 Jul 2021 17:04:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 171C766B9; Tue, 27 Jul 2021 17:04:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 16RH4qHh097337; Tue, 27 Jul 2021 17:04:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16RH4q6j097336; Tue, 27 Jul 2021 17:04:52 GMT (envelope-from git) Date: Tue, 27 Jul 2021 17:04:52 GMT Message-Id: <202107271704.16RH4q6j097336@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Alan Somers Subject: git: 6b2266b050a6 - stable/12 - fusefs: support EVFILT_WRITE on /dev/fuse MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: asomers X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 6b2266b050a6e06f20c065323379eefc3b6ec2f5 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jul 2021 17:04:53 -0000 The branch stable/12 has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=6b2266b050a6e06f20c065323379eefc3b6ec2f5 commit 6b2266b050a6e06f20c065323379eefc3b6ec2f5 Author: Alan Somers AuthorDate: 2021-06-15 23:17:28 +0000 Commit: Alan Somers CommitDate: 2021-07-27 17:03:38 +0000 fusefs: support EVFILT_WRITE on /dev/fuse /dev/fuse is always ready for writing, so it's kind of dumb to poll it. But some applications do it anyway. Better to return ready than EINVAL. Reviewed by: emaste, pfg Differential Revision: https://reviews.freebsd.org/D30784 (cherry picked from commit 7b8622fa220b9c08041102f638f848c48e022644) --- sys/fs/fuse/fuse_device.c | 22 +++++++++++++++++++++- tests/sys/fs/fusefs/mockfs.cc | 20 +++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c index 203da2c6f7ba..c918d593f1a4 100644 --- a/sys/fs/fuse/fuse_device.c +++ b/sys/fs/fuse/fuse_device.c @@ -116,6 +116,7 @@ static struct cdevsw fuse_device_cdevsw = { }; static int fuse_device_filt_read(struct knote *kn, long hint); +static int fuse_device_filt_write(struct knote *kn, long hint); static void fuse_device_filt_detach(struct knote *kn); struct filterops fuse_device_rfiltops = { @@ -124,6 +125,11 @@ struct filterops fuse_device_rfiltops = { .f_event = fuse_device_filt_read, }; +struct filterops fuse_device_wfiltops = { + .f_isfd = 1, + .f_event = fuse_device_filt_write, +}; + /**************************** * * >>> Fuse device op defs @@ -177,12 +183,14 @@ fuse_device_filter(struct cdev *dev, struct knote *kn) 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 && kn->kn_filter == EVFILT_WRITE) { + kn->kn_fop = &fuse_device_wfiltops; + error = 0; } else if (error == 0) { error = EINVAL; kn->kn_data = error; @@ -228,6 +236,18 @@ fuse_device_filt_read(struct knote *kn, long hint) return (ready); } +static int +fuse_device_filt_write(struct knote *kn, long hint) +{ + int ready; + + /* The device is always ready to write */ + kn->kn_data = 0; + ready = 1; + + return (ready); +} + /* * Resources are set up on a per-open basis */ diff --git a/tests/sys/fs/fusefs/mockfs.cc b/tests/sys/fs/fusefs/mockfs.cc index f43afd247502..bbdd515f027d 100644 --- a/tests/sys/fs/fusefs/mockfs.cc +++ b/tests/sys/fs/fusefs/mockfs.cc @@ -820,8 +820,8 @@ void MockFS::read_request(mockfs_buf_in &in, ssize_t &res) { timeout_ts.tv_sec = 0; timeout_ts.tv_nsec = timeout_ms * 1'000'000; while (nready == 0) { - EV_SET(&changes[0], m_fuse_fd, EVFILT_READ, EV_ADD, 0, - 0, 0); + EV_SET(&changes[0], m_fuse_fd, EVFILT_READ, + EV_ADD | EV_ONESHOT, 0, 0, 0); nready = kevent(m_kq, &changes[0], 1, &events[0], 1, &timeout_ts); if (m_quit) @@ -883,12 +883,26 @@ void MockFS::read_request(mockfs_buf_in &in, ssize_t &res) { void MockFS::write_response(const mockfs_buf_out &out) { fd_set writefds; pollfd fds[1]; + struct kevent changes[1]; + struct kevent events[1]; int nready, nfds; ssize_t r; switch (m_pm) { case BLOCKING: - case KQ: /* EVFILT_WRITE is not supported */ + break; + case KQ: + EV_SET(&changes[0], m_fuse_fd, EVFILT_WRITE, + EV_ADD | EV_ONESHOT, 0, 0, 0); + nready = kevent(m_kq, &changes[0], 1, &events[0], 1, + NULL); + ASSERT_LE(0, nready) << strerror(errno); + ASSERT_EQ(events[0].ident, (uintptr_t)m_fuse_fd); + if (events[0].flags & EV_ERROR) + FAIL() << strerror(events[0].data); + else if (events[0].flags & EV_EOF) + FAIL() << strerror(events[0].fflags); + m_nready = events[0].data; break; case POLL: fds[0].fd = m_fuse_fd;