diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 3c99779ca7b..f10edb221f4 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -2745,6 +2746,9 @@ vn_pollevent(vp, events) mtx_unlock(&vp->v_pollinfo.vpi_lock); } +#define VN_KNOTE(vp, b) \ + KNOTE((struct klist *)&vp->v_pollinfo.vpi_selinfo.si_note, (b)) + /* * Wake up anyone polling on vp because it is being revoked. * This depends on dead_poll() returning POLLHUP for correct @@ -2755,6 +2759,7 @@ vn_pollgone(vp) struct vnode *vp; { mtx_lock(&vp->v_pollinfo.vpi_lock); + VN_KNOTE(vp, NOTE_REVOKE); if (vp->v_pollinfo.vpi_events) { vp->v_pollinfo.vpi_events = 0; selwakeup(&vp->v_pollinfo.vpi_selinfo); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 3c99779ca7b..f10edb221f4 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -2745,6 +2746,9 @@ vn_pollevent(vp, events) mtx_unlock(&vp->v_pollinfo.vpi_lock); } +#define VN_KNOTE(vp, b) \ + KNOTE((struct klist *)&vp->v_pollinfo.vpi_selinfo.si_note, (b)) + /* * Wake up anyone polling on vp because it is being revoked. * This depends on dead_poll() returning POLLHUP for correct @@ -2755,6 +2759,7 @@ vn_pollgone(vp) struct vnode *vp; { mtx_lock(&vp->v_pollinfo.vpi_lock); + VN_KNOTE(vp, NOTE_REVOKE); if (vp->v_pollinfo.vpi_events) { vp->v_pollinfo.vpi_events = 0; selwakeup(&vp->v_pollinfo.vpi_selinfo); diff --git a/sys/sys/event.h b/sys/sys/event.h index 9f216786386..3c22678c019 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -73,6 +73,7 @@ struct kevent { #define NOTE_ATTRIB 0x0008 /* attributes changed */ #define NOTE_LINK 0x0010 /* link count changed */ #define NOTE_RENAME 0x0020 /* vnode was renamed */ +#define NOTE_REVOKE 0x0040 /* vnode access was revoked */ /* * data/hint flags for EVFILT_PROC, shared with userspace diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 29efbcc221a..870d6dd7417 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -2235,6 +2235,15 @@ filt_ufsread(struct knote *kn, long hint) struct vnode *vp = (struct vnode *)kn->kn_hook; struct inode *ip = VTOI(vp); + /* + * filesystem is gone, so set the EOF flag and schedule + * the knote for deletion. + */ + if (hint == NOTE_REVOKE) { + kn->kn_flags |= (EV_EOF | EV_ONESHOT); + return (1); + } + kn->kn_data = ip->i_size - kn->kn_fp->f_offset; return (kn->kn_data != 0); } @@ -2245,6 +2254,10 @@ filt_ufsvnode(struct knote *kn, long hint) if (kn->kn_sfflags & hint) kn->kn_fflags |= hint; + if (hint == NOTE_REVOKE) { + kn->kn_flags |= EV_EOF; + return (1); + } return (kn->kn_fflags != 0); }