summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-05-03 15:17:43 +0000
committerkib <kib@FreeBSD.org>2016-05-03 15:17:43 +0000
commit838f7d1304c723206899cd4965a1a8ba0761d68f (patch)
tree7218ce83f4cf8d64338a89b31295a32f6e5dc984
parentcacb7c41e21bf8ff9e1e931a5a98bef75389a4e3 (diff)
downloadFreeBSD-src-838f7d1304c723206899cd4965a1a8ba0761d68f.zip
FreeBSD-src-838f7d1304c723206899cd4965a1a8ba0761d68f.tar.gz
Add EVFILT_VNODE open, read and close notifications.
While there, order EVFILT_VNODE notes descriptions alphabetically. Based on submission, and tested by: Vladimir Kondratyev <wulf@cicgroup.ru> MFC after: 2 weeks
-rw-r--r--lib/libc/sys/kqueue.234
-rw-r--r--sys/kern/vfs_subr.c39
-rw-r--r--sys/kern/vnode_if.src4
-rw-r--r--sys/sys/event.h6
-rw-r--r--sys/sys/vnode.h4
5 files changed, 79 insertions, 8 deletions
diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index 221f451..548aeb8 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 2, 2016
+.Dd May 3, 2016
.Dt KQUEUE 2
.Os
.Sh NAME
@@ -367,14 +367,28 @@ Takes a file descriptor as the identifier and the events to watch for in
.Va fflags ,
and returns when one or more of the requested events occurs on the descriptor.
The events to monitor are:
-.Bl -tag -width "Dv NOTE_RENAME"
+.Bl -tag -width "Dv NOTE_CLOSE_WRITE"
+.It Dv NOTE_ATTRIB
+The file referenced by the descriptor had its attributes changed.
+.It Dv NOTE_CLOSE
+A file descriptor referencing the monitored file, was closed.
+The closed file descriptor did not possesed write access.
+.It Dv NOTE_CLOSE_WRITE
+A file descriptor referencing the monitored file, was closed.
+The closed file descriptor has write access.
+.Pp
+This note, as well as
+.Dv NOTE_CLOSE ,
+are not activated when files are closed forcibly by
+.Xr unmount 2 or
+.Xr revoke 2 .
+Instead,
+.Dv NOTE_REVOKE
+is sent for such events.
.It Dv NOTE_DELETE
The
.Fn unlink
-system call
-was called on the file referenced by the descriptor.
-.It Dv NOTE_WRITE
-A write occurred on the file referenced by the descriptor.
+system call was called on the file referenced by the descriptor.
.It Dv NOTE_EXTEND
For regular file, the file referenced by the descriptor was extended.
.Pp
@@ -383,20 +397,24 @@ as the result of rename operation.
The
.Dv NOTE_EXTEND
event is not reported when a name is changed inside the directory.
-.It Dv NOTE_ATTRIB
-The file referenced by the descriptor had its attributes changed.
.It Dv NOTE_LINK
The link count on the file changed.
In particular, the
.Dv NOTE_LINK
event is reported if a subdirectory was created or deleted inside
the directory referenced by the descriptor.
+.It Dv NOTE_OPEN
+The file referenced by the descriptor was opened.
+.It Dv NOTE_READ
+A read occurred on the file referenced by the descriptor.
.It Dv NOTE_RENAME
The file referenced by the descriptor was renamed.
.It Dv NOTE_REVOKE
Access to the file was revoked via
.Xr revoke 2
or the underlying file system was unmounted.
+.It Dv NOTE_WRITE
+A write occurred on the file referenced by the descriptor.
.El
.Pp
On return,
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 795eac5..97ab886 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -4722,6 +4722,45 @@ vop_symlink_post(void *ap, int rc)
VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE);
}
+void
+vop_open_post(void *ap, int rc)
+{
+ struct vop_open_args *a = ap;
+
+ if (!rc)
+ VFS_KNOTE_LOCKED(a->a_vp, NOTE_OPEN);
+}
+
+void
+vop_close_post(void *ap, int rc)
+{
+ struct vop_close_args *a = ap;
+
+ if (!rc && (a->a_cred != NOCRED || /* filter out revokes */
+ (a->a_vp->v_iflag & VI_DOOMED) == 0)) {
+ VFS_KNOTE_LOCKED(a->a_vp, (a->a_fflag & FWRITE) != 0 ?
+ NOTE_CLOSE_WRITE : NOTE_CLOSE);
+ }
+}
+
+void
+vop_read_post(void *ap, int rc)
+{
+ struct vop_read_args *a = ap;
+
+ if (!rc)
+ VFS_KNOTE_LOCKED(a->a_vp, NOTE_READ);
+}
+
+void
+vop_readdir_post(void *ap, int rc)
+{
+ struct vop_readdir_args *a = ap;
+
+ if (!rc)
+ VFS_KNOTE_LOCKED(a->a_vp, NOTE_READ);
+}
+
static struct knlist fs_knlist;
static void
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 1b07a36..0350e0e 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -121,6 +121,7 @@ vop_mknod {
%% open vp L L L
+%! open post vop_open_post
vop_open {
IN struct vnode *vp;
@@ -132,6 +133,7 @@ vop_open {
%% close vp L L L
+%! close post vop_close_post
vop_close {
IN struct vnode *vp;
@@ -186,6 +188,7 @@ vop_markatime {
};
%% read vp L L L
+%! read post vop_read_post
vop_read {
IN struct vnode *vp;
@@ -326,6 +329,7 @@ vop_symlink {
%% readdir vp L L L
+%! readdir post vop_readdir_post
vop_readdir {
IN struct vnode *vp;
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 7897c81..5b54150 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -121,6 +121,12 @@ struct kevent {
#define NOTE_LINK 0x0010 /* link count changed */
#define NOTE_RENAME 0x0020 /* vnode was renamed */
#define NOTE_REVOKE 0x0040 /* vnode access was revoked */
+#define NOTE_OPEN 0x0080 /* vnode was opened */
+#define NOTE_CLOSE 0x0100 /* file closed, fd did not
+ allowed write */
+#define NOTE_CLOSE_WRITE 0x0200 /* file closed, fd did allowed
+ write */
+#define NOTE_READ 0x0400 /* file was read */
/*
* data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index f3ae773..df43134 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -774,6 +774,7 @@ int dead_read(struct vop_read_args *ap);
int dead_write(struct vop_write_args *ap);
/* These are called from within the actual VOPS. */
+void vop_close_post(void *a, int rc);
void vop_create_post(void *a, int rc);
void vop_deleteextattr_post(void *a, int rc);
void vop_link_post(void *a, int rc);
@@ -783,6 +784,9 @@ void vop_lookup_post(void *a, int rc);
void vop_lookup_pre(void *a);
void vop_mkdir_post(void *a, int rc);
void vop_mknod_post(void *a, int rc);
+void vop_open_post(void *a, int rc);
+void vop_read_post(void *a, int rc);
+void vop_readdir_post(void *a, int rc);
void vop_reclaim_post(void *a, int rc);
void vop_remove_post(void *a, int rc);
void vop_rename_post(void *a, int rc);
OpenPOWER on IntegriCloud