From d535f532db35a7e39dac0cb7aca0e9e8b65cb82b Mon Sep 17 00:00:00 2001
From:
Date: Fri, 29 Apr 2016 10:08:11 +0900
Subject: [PATCH] sys/kern: Add EVFILT_FS

---
 sys/kern/kern_event.c   | 33 +++++++++++++++++++++++++++++++++
 sys/kern/vfs_syscalls.c |  2 ++
 sys/sys/event.h         |  5 ++++-
 sys/sys/mount.h         | 19 +++++++++++++++++++
 4 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 34a24a3..ecaaa79 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -123,6 +123,9 @@ static void	filt_userdetach(struct knote *kn);
 static int	filt_user(struct knote *kn, long hint);
 static void	filt_usertouch(struct knote *kn, struct kevent *kev,
 				u_long type);
+static int	filt_fsattach(struct knote *kn);
+static void	filt_fsdetach(struct knote *kn);
+static int	filt_fs(struct knote *kn, long hint);
 
 static struct filterops file_filtops =
 	{ FILTEROP_ISFD | FILTEROP_MPSAFE, filt_fileattach, NULL, NULL };
@@ -134,6 +137,8 @@ static struct filterops timer_filtops =
 	{ FILTEROP_MPSAFE, filt_timerattach, filt_timerdetach, filt_timer };
 static struct filterops user_filtops =
 	{ FILTEROP_MPSAFE, filt_userattach, filt_userdetach, filt_user };
+static struct filterops fs_filtops =
+	{ FILTEROP_MPSAFE, filt_fsattach, filt_fsdetach, filt_fs };
 
 static int 		kq_ncallouts = 0;
 static int 		kq_calloutmax = (4 * 1024);
@@ -168,6 +173,7 @@ static struct filterops *sysfilt_ops[] = {
 	&timer_filtops,			/* EVFILT_TIMER */
 	&file_filtops,			/* EVFILT_EXCEPT */
 	&user_filtops,			/* EVFILT_USER */
+	&fs_filtops,			/* EVFILT_FS */
 };
 
 static struct knote_cache_list	knote_cache_lists[MAXCPU];
@@ -587,6 +593,33 @@ filt_usertouch(struct knote *kn, struct kevent *kev, u_long type)
 }
 
 /*
+ * EVFILT_FS
+ */
+struct klist fs_klist = SLIST_HEAD_INITIALIZER(&fs_klist);
+
+static int
+filt_fsattach(struct knote *kn)
+{
+	kn->kn_flags |= EV_CLEAR;
+	knote_insert(&fs_klist, kn);
+
+	return (0);
+}
+
+static void
+filt_fsdetach(struct knote *kn)
+{
+	knote_remove(&fs_klist, kn);
+}
+
+static int
+filt_fs(struct knote *kn, long hint)
+{
+	kn->kn_fflags |= hint;
+	return (kn->kn_fflags != 0);
+}
+
+/*
  * Initialize a kqueue.
  *
  * NOTE: The lwp/proc code initializes a kqueue for select/poll ops.
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 387920b..1ef23e5 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -415,6 +415,7 @@ update:
 		vfs_unbusy(mp);
 		error = VFS_START(mp, 0);
 		vrele(vp);
+		KNOTE(&fs_klist, VQ_MOUNT);
 	} else {
 		vn_syncer_thr_stop(mp);
 		vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_coherency_ops);
@@ -862,6 +863,7 @@ dounmount(struct mount *mp, int flags)
 		mp = NULL;
 	}
 	error = 0;
+	KNOTE(&fs_klist, VQ_UNMOUNT);
 out:
 	if (mp)
 		lwkt_reltoken(&mp->mnt_token);
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 9a463a3..331a8b5 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -46,10 +46,11 @@
 #define EVFILT_TIMER		(-7)	/* timers */
 #define EVFILT_EXCEPT		(-8)	/* exceptional conditions */
 #define EVFILT_USER		(-9)	/* user events */
+#define EVFILT_FS		(-10)	/* filesystem events */
 
 #define EVFILT_MARKER		0xF	/* placemarker for tailq */
 
-#define EVFILT_SYSCOUNT		9
+#define EVFILT_SYSCOUNT		10
 
 #define EV_SET(kevp_, a, b, c, d, e, f) do {	\
 	struct kevent *kevp = (kevp_);		\
@@ -252,6 +253,8 @@ extern void	kqueue_init(struct kqueue *kq, struct filedesc *fdp);
 extern void	kqueue_terminate(struct kqueue *kq);
 extern int 	kqueue_register(struct kqueue *kq, struct kevent *kev);
 
+extern struct klist fs_klist;	/* EVFILT_FS */
+
 #endif 	/* _KERNEL */
 
 #if !defined(_KERNEL) || defined(_KERNEL_VIRTUAL)
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 4be002c..7d81f65 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -488,6 +488,25 @@ struct ovfsconf {
 #define	VFCF_LOOPBACK	0x00100000	/* aliases some other mounted FS */
 #define	VFCF_UNICODE	0x00200000	/* stores file names as Unicode*/
 
+/* vfsquery flags */
+#define VQ_NOTRESP	0x0001	/* server down */
+#define VQ_NEEDAUTH	0x0002	/* server bad auth */
+#define VQ_LOWDISK	0x0004	/* we're low on space */
+#define VQ_MOUNT	0x0008	/* new filesystem arrived */
+#define VQ_UNMOUNT	0x0010	/* filesystem has left */
+#define VQ_DEAD		0x0020	/* filesystem is dead, needs force unmount */
+#define VQ_ASSIST	0x0040	/* filesystem needs assistance from external
+				   program */
+#define VQ_NOTRESPLOCK	0x0080	/* server lockd down */
+#define VQ_FLAG0100	0x0100	/* placeholder */
+#define VQ_FLAG0200	0x0200	/* placeholder */
+#define VQ_FLAG0400	0x0400	/* placeholder */
+#define VQ_FLAG0800	0x0800	/* placeholder */
+#define VQ_FLAG1000	0x1000	/* placeholder */
+#define VQ_FLAG2000	0x2000	/* placeholder */
+#define VQ_FLAG4000	0x4000	/* placeholder */
+#define VQ_FLAG8000	0x8000	/* placeholder */
+
 #ifdef _KERNEL
 
 #ifdef MALLOC_DECLARE
-- 
2.7.4

