diff options
-rw-r--r-- | sys/kern/vfs_export.c | 5 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 5 | ||||
-rw-r--r-- | sys/sys/event.h | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 13 |
4 files changed, 24 insertions, 0 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 3c99779..f10edb2 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -53,6 +53,7 @@ #include <sys/dirent.h> #include <sys/domain.h> #include <sys/eventhandler.h> +#include <sys/event.h> #include <sys/fcntl.h> #include <sys/kernel.h> #include <sys/kthread.h> @@ -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 3c99779..f10edb2 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -53,6 +53,7 @@ #include <sys/dirent.h> #include <sys/domain.h> #include <sys/eventhandler.h> +#include <sys/event.h> #include <sys/fcntl.h> #include <sys/kernel.h> #include <sys/kthread.h> @@ -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 9f21678..3c22678 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 29efbcc..870d6dd 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); } |