Date: Tue, 27 Jul 2021 17:04:52 GMT From: Alan Somers <asomers@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 6b2266b050a6 - stable/12 - fusefs: support EVFILT_WRITE on /dev/fuse Message-ID: <202107271704.16RH4q6j097336@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=6b2266b050a6e06f20c065323379eefc3b6ec2f5 commit 6b2266b050a6e06f20c065323379eefc3b6ec2f5 Author: Alan Somers <asomers@FreeBSD.org> AuthorDate: 2021-06-15 23:17:28 +0000 Commit: Alan Somers <asomers@FreeBSD.org> 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202107271704.16RH4q6j097336>