From nobody Tue Oct 12 07:44:25 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id BA1D3180E897; Tue, 12 Oct 2021 07:44:26 +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 4HT73G0p0Hz54yL; Tue, 12 Oct 2021 07:44:25 +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 B8EB010E80; Tue, 12 Oct 2021 07:44:25 +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 19C7iPB9009455; Tue, 12 Oct 2021 07:44:25 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 19C7iPe1009454; Tue, 12 Oct 2021 07:44:25 GMT (envelope-from git) Date: Tue, 12 Oct 2021 07:44:25 GMT Message-Id: <202110120744.19C7iPe1009454@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: 7259ca31048e - main - fifos: delegate unhandled kqueue filters to underlying filesystem List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7259ca31048e5ced8e7f90657a3d7084aeafdf51 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=7259ca31048e5ced8e7f90657a3d7084aeafdf51 commit 7259ca31048e5ced8e7f90657a3d7084aeafdf51 Author: Kyle Evans AuthorDate: 2021-10-02 05:23:03 +0000 Commit: Kyle Evans CommitDate: 2021-10-12 07:43:07 +0000 fifos: delegate unhandled kqueue filters to underlying filesystem This gives the vfs layer a chance to provide handling for EVFILT_VNODE, for instance. Change pipe_specops to use the default vop_kqfilter to accommodate fifoops that don't specify the method (i.e. all in-tree). Based on a patch by Jan Kokemüller. PR: 225934 Reviewed by: kib, markj (both pre-KASSERT) Differential Revision: https://reviews.freebsd.org/D32271 --- sys/fs/fifofs/fifo_vnops.c | 1 - sys/kern/sys_pipe.c | 4 +++ sys/kern/vfs_subr.c | 3 ++ tests/sys/kqueue/libkqueue/common.h | 2 ++ tests/sys/kqueue/libkqueue/vnode.c | 59 +++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index 1b941620b080..d9dc8eee8e60 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -83,7 +83,6 @@ struct vop_vector fifo_specops = { .vop_create = VOP_PANIC, .vop_getattr = VOP_EBADF, .vop_ioctl = VOP_PANIC, - .vop_kqfilter = VOP_PANIC, .vop_link = VOP_PANIC, .vop_mkdir = VOP_PANIC, .vop_mknod = VOP_PANIC, diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 7bd7fea28e76..1d5d7329692e 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1751,6 +1751,10 @@ pipe_kqfilter(struct file *fp, struct knote *kn) cpipe = PIPE_PEER(cpipe); break; default: + if ((cpipe->pipe_type & PIPE_TYPE_NAMED) != 0) { + PIPE_UNLOCK(cpipe); + return (vnops.fo_kqfilter(fp, kn)); + } PIPE_UNLOCK(cpipe); return (EINVAL); } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 69ac73bd3954..d4b7ac71eb97 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -6172,6 +6172,9 @@ vfs_kqfilter(struct vop_kqfilter_args *ap) struct knote *kn = ap->a_kn; struct knlist *knl; + KASSERT(vp->v_type != VFIFO || (kn->kn_filter != EVFILT_READ && + kn->kn_filter != EVFILT_WRITE), + ("READ/WRITE filter on a FIFO leaked through")); switch (kn->kn_filter) { case EVFILT_READ: kn->kn_fop = &vfsread_filtops; diff --git a/tests/sys/kqueue/libkqueue/common.h b/tests/sys/kqueue/libkqueue/common.h index d621a8bf1e00..a92e544910ba 100644 --- a/tests/sys/kqueue/libkqueue/common.h +++ b/tests/sys/kqueue/libkqueue/common.h @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include diff --git a/tests/sys/kqueue/libkqueue/vnode.c b/tests/sys/kqueue/libkqueue/vnode.c index 8f4311e90745..b6c0915b2654 100644 --- a/tests/sys/kqueue/libkqueue/vnode.c +++ b/tests/sys/kqueue/libkqueue/vnode.c @@ -64,6 +64,64 @@ test_kevent_vnode_note_delete(void) success(); } +static void +test_kevent_vnode_note_delete_fifo(void) +{ + const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE, FIFO)"; + const char *fifo_path = "./kqueue-fifo.tmp"; + struct kevent kev; + int fd; + pid_t pid; + + test_begin(test_id); + + if (mkfifo(fifo_path, 0600) != 0) + err(1, "mkfifo"); + + pid = fork(); + if (pid == -1) + err(1, "fork"); + + if (pid == 0) { + char buf[4]; + + fd = open(fifo_path, O_RDONLY); + if (fd == -1) + _exit(1); + + while (read(fd, buf, sizeof(buf)) != 0) { + } + + _exit(0); + } + + sleep(1); + if (waitpid(pid, NULL, WNOHANG) == pid) { + unlink(fifo_path); + err(1, "open"); + } + + fd = open(fifo_path, O_WRONLY); + if (fd < 0) { + unlink(fifo_path); + err(1, "open"); + } + + EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL); + if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) { + unlink(fifo_path); + err(1, "%s", test_id); + } + + if (unlink(fifo_path) < 0) + err(1, "unlink"); + + kevent_cmp(&kev, kevent_get(kqfd)); + close(fd); + + success(); +} + static void test_kevent_vnode_note_write(void) { @@ -261,5 +319,6 @@ test_evfilt_vnode(void) test_kevent_vnode_note_attrib(); test_kevent_vnode_note_rename(); test_kevent_vnode_note_delete(); + test_kevent_vnode_note_delete_fifo(); close(kqfd); }