git: 7b096a997fad - stable/13 - fusefs: support EVFILT_WRITE on /dev/fuse
Alan Somers
asomers at FreeBSD.org
Sat Jul 3 23:59:10 UTC 2021
The branch stable/13 has been updated by asomers:
URL: https://cgit.FreeBSD.org/src/commit/?id=7b096a997fad199eddccfb6784e4b85184d9af17
commit 7b096a997fad199eddccfb6784e4b85184d9af17
Author: Alan Somers <asomers at FreeBSD.org>
AuthorDate: 2021-06-15 23:17:28 +0000
Commit: Alan Somers <asomers at FreeBSD.org>
CommitDate: 2021-07-03 23:57:51 +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)
Simplify fuse_device_filt_write
It always returns 1, so why bother having a variable.
Pull Request: https://github.com/freebsd/freebsd-src/pull/478
(cherry picked from commit 9b876fbd504e5c718d8d0275b32d806ab14558c8)
---
sys/fs/fuse/fuse_device.c | 20 +++++++++++++++++++-
tests/sys/fs/fusefs/mockfs.cc | 20 +++++++++++++++++---
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c
index cab5925c91de..f8807d6d1c26 100644
--- a/sys/fs/fuse/fuse_device.c
+++ b/sys/fs/fuse/fuse_device.c
@@ -119,6 +119,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 = {
@@ -127,6 +128,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
@@ -180,12 +186,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;
@@ -231,6 +239,16 @@ fuse_device_filt_read(struct knote *kn, long hint)
return (ready);
}
+static int
+fuse_device_filt_write(struct knote *kn, long hint)
+{
+
+ kn->kn_data = 0;
+
+ /* The device is always ready to write, so we return 1*/
+ return (1);
+}
+
/*
* 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 7e4991fb7bb9..7003472ca52b 100644
--- a/tests/sys/fs/fusefs/mockfs.cc
+++ b/tests/sys/fs/fusefs/mockfs.cc
@@ -867,8 +867,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)
@@ -930,12 +930,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;
More information about the dev-commits-src-all
mailing list