sys/kern: Add kqueue EVFILT_FS
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Fri, 29 Apr 2016 01:08:11 +0000 (10:08 +0900)
committerTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Thu, 2 Jun 2016 22:42:53 +0000 (07:42 +0900)
Brought in from FreeBSD@GitHub bbaa6c3ec045b7de225f726d3c9367510b287184.
Needed by autofs.

Triggers an event on mount(2) and unmount(2).

Also see https://bugs.dragonflybsd.org/issues/2905.
Reviewed-by: sephe
sys/kern/kern_event.c
sys/kern/vfs_syscalls.c
sys/sys/event.h
sys/sys/mount.h

index 2d47047..cf9f759 100644 (file)
@@ -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];
@@ -593,6 +599,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.
  *
index 387920b..1ef23e5 100644 (file)
@@ -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);
index 9a463a3..331a8b5 100644 (file)
 #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)
index 4d1ae3d..5fec436 100644 (file)
@@ -482,6 +482,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