From 5e25370d706d35424cf5eb1d61f2614cbb29b9cd Mon Sep 17 00:00:00 2001 From: Tomohiro Kusumi Date: Fri, 29 Apr 2016 10:08:11 +0900 Subject: [PATCH] sys/kern: Add kqueue EVFILT_FS 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 | 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 2d47047ae8..cf9f759295 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]; @@ -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. * diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 387920b228..1ef23e5c21 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 9a463a3c82..331a8b5975 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 4d1ae3d69d..5fec43610d 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -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 -- 2.41.0