PERFORCE change 181372 for review

Ilya Putsikau ilya at FreeBSD.org
Fri Jul 23 15:26:41 UTC 2010


http://p4web.freebsd.org/@@181372?ac=10

Change 181372 by ilya at ilya_triton on 2010/07/23 15:25:49

	* Add regression tests
	* Fix vnode neg ref cnt in namei() panic
	* Use same struct field names as in Linux
	* Return as many events as possible in single read()
	* Return ENIVAL if buffer is too small for next event
	* Close fd before adding watch (if FN_CLOSEFD given)
	* Remove inactive events
	* Don't update node path during destroy events or if use count is zero

Affected files ...

.. //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vfs_notify.c#8 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vfs_subr.c#5 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vnode_if.src#3 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/sys/fsnotify.h#6 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/sys/vnode.h#4 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/tools/vnode_if.awk#3 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/Makefile#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/fsnotify-test.c#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.00.out#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.00.sh#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.01.out#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.01.sh#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.sh#1 add

Differences ...

==== //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vfs_notify.c#8 (text+ko) ====

@@ -50,6 +50,7 @@
 #include <sys/proc.h>
 #include <sys/queue.h>
 #include <sys/refcount.h>
+#include <sys/syscallsubr.h>
 #include <sys/systm.h>
 #include <sys/unistd.h>
 #include <sys/vnode.h>
@@ -147,10 +148,12 @@
 static fno_inactive_t hook_inactive;
 static fno_link_t hook_link;
 static fno_mkdir_t hook_mkdir;
+static fno_open_t hook_open;
 static fno_reclaim_t hook_reclaim;
 static fno_remove_t hook_remove;
 static fno_rename_t hook_rename;
 static fno_rmdir_t hook_rmdir;
+static fno_setattr_t hook_setattr;
 static fno_symlink_t hook_symlink;
 static fno_write_t hook_write;
 
@@ -160,10 +163,12 @@
 	.fno_inactive	= hook_inactive,
 	.fno_link	= hook_link,
 	.fno_mkdir	= hook_mkdir,
+	.fno_open	= hook_open,
 	.fno_reclaim	= hook_reclaim,
 	.fno_remove	= hook_remove,
 	.fno_rename	= hook_rename,
 	.fno_rmdir	= hook_rmdir,
+	.fno_setattr	= hook_setattr,
 	.fno_symlink	= hook_symlink,
 	.fno_write	= hook_write,
 };
@@ -183,8 +188,8 @@
 static void node_watchhold(struct fnnode *node);
 static void node_watchdrop(struct fnnode *node);
 
-static void event_copypath(struct fnevent *event, char *path, int *pathlen);
-static int event_pathlen(struct fnevent *event);
+static void event_copypath(struct fnevent *event, char *path);
+static int event_userpathlen(struct fnevent *event);
 static void event_enqueue(struct fnnode *node, struct componentname *cnp,
     int *cookiep, int mask);
 
@@ -395,50 +400,130 @@
 		return (error);
 	}
 
-	eh = TAILQ_FIRST(&ss->ss_queue);
-	event = eh->eh_event;
-	watch = eh->eh_watch;
 	fe = (struct fsnotify_event *) user_buf;
-	fe->fe_wd = watch->wt_wd;
-	fe->fe_mask = watch->wt_mask & event->ev_mask;
-	fe->fe_fileno = event->ev_node->nd_ino;
-	fe->fe_cookie = event->ev_cookie;
-	event_copypath(event, fe->fe_name, &fe->fe_namelen);
-	len = fe->fe_namelen + sizeof(struct fsnotify_event);
-	destroy = event->ev_mask & FE_DESTROY;
+	while (1) {
+		eh = TAILQ_FIRST(&ss->ss_queue);
+		if (eh == NULL) {
+			SESSION_UNLOCK(ss);
+			break;
+		}
+		event = eh->eh_event;
+		watch = eh->eh_watch;
+		fe->len = event_userpathlen(event);
+		len = fe->len + sizeof(struct fsnotify_event);
+		if (len > uio->uio_resid) {
+			SESSION_UNLOCK(ss);
+			break;
+		}
+		fe->wd = watch->wt_wd;
+		fe->mask = watch->wt_mask & event->ev_mask;
+		fe->fileno = event->ev_node->nd_ino;
+		fe->cookie = event->ev_cookie;
+		event_copypath(event, fe->name);
 
-	SESSION_UNLOCK(ss);
-
-	error = uiomove(user_buf, MIN(len, uio->uio_resid), uio);
-	printf("fsnotify_read: uiomove: error %d, offset %jd, len %d\n", error,
-	    uio->uio_offset, len);
-	if (error == 0 && uio->uio_offset >= len) {
-		uio->uio_offset = 0;
-		SESSION_LOCK(ss);
+		destroy = event->ev_mask & FN_DESTROY;
 		session_drophandle(ss, eh);
 		if (destroy != 0)
 			watch_free(watch);
+
 		SESSION_UNLOCK(ss);
+
+		MPASS(len <= uio->uio_resid);
+		error = uiomove(user_buf, len, uio);
+		if (error != 0 ||
+		    uio->uio_resid < sizeof(struct fsnotify_event))
+			break;
+
+		SESSION_LOCK(ss);
 	}
 
+	if (error == 0 && uio->uio_offset == 0)
+		error = EINVAL;		/* Buffer is too small */
+	uio->uio_offset = 0;
+
 	return (error);
 }
 
 static int
-fsnotify_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags,
+fsnotify_nread(struct fnsession *ss, int *nread)
+{
+	struct fneventhandle *eh;
+
+	*nread = 0;
+	SESSION_LOCK(ss);
+	TAILQ_FOREACH(eh, &ss->ss_queue, eh_queueentry) {
+		*nread += sizeof(struct fsnotify_event) +
+		    event_userpathlen(eh->eh_event);
+	}
+	SESSION_UNLOCK(ss);
+
+	return (0);
+}
+
+static int
+fsnotify_addwatch(struct fnsession *ss, struct fsnotify_addwatch_args *ap,
     struct thread *td)
 {
-	struct fnsession *ss;
 	struct fnnode *node;
-	struct fnevent *event;
 	struct fnwatch *watch;
-	struct fsnotify_addwatch_args *add_args;
 	struct file *fp;
 	struct filedesc *fdp;
 	struct vnode *vp;
+	char *path, *pathfree;
 	ino_t ino;
-	char *path, *pathfree;
-	int vfslocked;
+	int error = 0, vfslocked;
+
+	fdp = td->td_proc->p_fd;
+	vp = NULL;
+	FILEDESC_SLOCK(fdp);
+	fp = fget_locked(fdp, ap->fd);
+	if (fp != NULL && fp->f_type == DTYPE_VNODE) {
+		vp = fp->f_vnode;
+	}
+	FILEDESC_SUNLOCK(fdp);
+	if (vp == NULL)
+		return (EBADF);
+	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+	ino = 0;
+	node = node_lookupex(vp, &ino, LOOKUP_IGNINVAL);
+	if (node != NULL) {
+		node_watchhold(node);
+		NODE_UNLOCK(node);
+		VFS_UNLOCK_GIANT(vfslocked);
+	} else {
+		error = vn_fullpath_global(td, vp, &path, &pathfree);
+		VFS_UNLOCK_GIANT(vfslocked);
+		if (error == 0) {
+			node = node_alloc(vp, ino);
+			node->nd_path = path;
+			node->nd_pathlen = strlen(path);
+			node->nd_pathfree = pathfree;
+			node_watchhold(node);
+			NODE_UNLOCK(node);
+		}
+	}
+
+	if ((ap->mask & FN_CLOSEFD) != 0) {
+		kern_close(td, ap->fd);
+		ap->fd = -1;
+	}
+
+	if (error != 0)
+		return (error);
+
+	error = session_addwatch(ss, node, ap->mask, &watch);
+	node_drop(node);
+	if (error == 0)
+		ap->wd = watch->wt_wd;
+
+	return (error);
+}
+
+static int
+fsnotify_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags,
+    struct thread *td)
+{
+	struct fnsession *ss;
 	int error;
 
 	error = devfs_get_cdevpriv((void **)&ss);
@@ -447,54 +532,14 @@
 
 	switch (cmd) {
 	case FSNOTIFY_ADDWATCH:
-		add_args = (struct fsnotify_addwatch_args *)data;
-		fdp = td->td_proc->p_fd;
-		vp = NULL;
-		FILEDESC_SLOCK(fdp);
-		fp = fget_locked(fdp, add_args->fa_fd);
-		if (fp != NULL && fp->f_type == DTYPE_VNODE) {
-			vp = fp->f_vnode;
-		}
-		FILEDESC_SUNLOCK(fdp);
-		if (vp == NULL)
-			return (EBADF);
-		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
-		ino = 0;
-		node = node_lookupex(vp, &ino, LOOKUP_IGNINVAL);
-		if (node != NULL) {
-			node_watchhold(node);
-			NODE_UNLOCK(node);
-			VFS_UNLOCK_GIANT(vfslocked);
-		} else {
-			error = vn_fullpath_global(td, vp, &path, &pathfree);
-			VFS_UNLOCK_GIANT(vfslocked);
-			if (error != 0)
-				return (error);
-			node = node_alloc(vp, ino);
-			node->nd_path = path;
-			node->nd_pathlen = strlen(path);
-			node->nd_pathfree = pathfree;
-			node_watchhold(node);
-			NODE_UNLOCK(node);
-		}
-		error = session_addwatch(ss, node, add_args->fa_mask, &watch);
-		node_drop(node);
-		if (error == 0)
-			add_args->fa_wd = watch->wt_wd;
-		/* If error != 0 node will be removed by hook_reclaim */
+		error = fsnotify_addwatch(ss,
+		    (struct fsnotify_addwatch_args *)data, td);
 		break;
 	case FSNOTIFY_RMWATCH:
 		error = session_rmwatch(ss, *(int *)data);
 		break;
 	case FIONREAD:
-		SESSION_LOCK(ss);
-		if (!TAILQ_EMPTY(&ss->ss_queue)) {
-			event = TAILQ_FIRST(&ss->ss_queue)->eh_event;
-			*(int *)data = sizeof(struct fsnotify_event) +
-			    event_pathlen(event) + 1;
-		} else
-			*(int *)data = 0;
-		SESSION_UNLOCK(ss);
+		error = fsnotify_nread(ss, (int *)data);
 		break;
 	default:
 		error = ENOENT;
@@ -553,7 +598,7 @@
 }
 
 static void
-hook_close(struct vop_close_args *ap)
+hook_open(struct vop_open_args *ap)
 {
 	struct fnnode *node;
 	int cookie = 0;
@@ -561,14 +606,14 @@
 	node = node_lookup(ap->a_vp);
 	if (node != NULL) {
 		if ((node->nd_flags & NODE_ISDIR) == 0)
-			event_enqueue(node, NULL, &cookie, FE_CLOSE);
+			event_enqueue(node, NULL, &cookie, FN_OPEN);
 		else
 			NODE_UNLOCK(node);
 	}
 }
 
 static void
-hook_inactive(struct vop_inactive_args *ap)
+hook_close(struct vop_close_args *ap)
 {
 	struct fnnode *node;
 	int cookie = 0, mask;
@@ -577,15 +622,30 @@
 	if (node != NULL) {
 		if ((node->nd_flags & NODE_ISDIR) == 0) {
 			mask = (node->nd_flags & NODE_CHANGED) != 0 ?
-			    FE_INACTIVE_CHANGED : FE_INACTIVE;
+			    FN_CLOSE_RW : FN_CLOSE_RO;
 			event_enqueue(node, NULL, &cookie, mask);
-			node->nd_flags &= ~NODE_CHANGED;
 		} else
 			NODE_UNLOCK(node);
 	}
 }
 
 static void
+hook_inactive(struct vop_inactive_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct fnnode *node;
+
+	VI_LOCK(vp);
+	node = vp->v_fnnode;
+	if (NODE_ISVALID(node)) {
+		NODE_LOCK(node);
+		node->nd_flags &= ~NODE_CHANGED;
+		NODE_UNLOCK(node);
+	}
+	VI_UNLOCK(vp);
+}
+
+static void
 hook_write(struct vop_write_args *ap)
 {
 	struct fnnode *node;
@@ -598,6 +658,18 @@
 	}
 }
 
+static void
+hook_setattr(struct vop_setattr_args *ap)
+{
+	struct fnnode *node;
+	int cookie = 0;
+
+	node = node_lookup(ap->a_vp);
+	if (node != NULL) {
+		event_enqueue(node, NULL, &cookie, FN_SETATTR);
+	}
+}
+
 static __inline int
 hook_generic_create(struct vnode *dvp, struct vnode *vp,
     struct componentname *cnp)
@@ -607,7 +679,7 @@
 
 	dirnode = node_lookup(dvp);
 	if (dirnode != NULL)
-		event_enqueue(dirnode, cnp, &cookie, FE_CREATE);
+		event_enqueue(dirnode, cnp, &cookie, FN_CREATE);
 	return (0);
 }
 
@@ -622,11 +694,11 @@
 
 	node = node_lookup(vp);
 	if (node != NULL)
-		event_enqueue(node, NULL, &cookie, FE_DESTROY | FE_REMOVE);
+		event_enqueue(node, NULL, &cookie, FN_DESTROY | FN_REMOVE);
 
 	dirnode = node_lookup(dvp);
 	if (dirnode != NULL)
-		event_enqueue(dirnode, cnp, &cookie, FE_REMOVE);
+		event_enqueue(dirnode, cnp, &cookie, FN_REMOVE);
 }
 
 static void
@@ -679,7 +751,7 @@
 		tnode = node_lookupex(ap->a_tvp, NULL, 0);
 		if (tnode != NULL) {
 			event_enqueue(tnode, NULL, &cookie,
-			    FE_DESTROY | FE_REMOVE);
+			    FN_DESTROY | FN_REMOVE);
 		}
 	}
 	fnode = node_lookupex(ap->a_fvp, NULL, 0);
@@ -691,10 +763,10 @@
 
 	fdirnode = node_lookupex(ap->a_fdvp, NULL, 0);
 	if (fdirnode != NULL)
-		event_enqueue(fdirnode, ap->a_fcnp, &cookie, FE_RENAME_FROM);
+		event_enqueue(fdirnode, ap->a_fcnp, &cookie, FN_RENAME_FROM);
 	tdirnode = node_lookupex(ap->a_tdvp, NULL, 0);
 	if (tdirnode != NULL)
-		event_enqueue(tdirnode, ap->a_tcnp, &cookie, FE_RENAME_TO);
+		event_enqueue(tdirnode, ap->a_tcnp, &cookie, FN_RENAME_TO);
 }
 
 static int
@@ -989,21 +1061,23 @@
 
 	/* Should be executed in *single* fsnotify_daemon thread */
 	vp = node->nd_vnode;
+	if ((vp->v_iflag & VI_DOOMED) != 0 || vp->v_usecount == 0) {
+		printf("skip node path update: %p\n", vp);
+		return (ENOENT);
+	}
+
 	printf("node_updatepath: node %p  vp %p  %s\n",
 	    node, vp, node->nd_path);
-	if ((vp->v_iflag & VI_DOOMED) != 0)
-		return (ENOENT);
-
 	path = node->nd_path;
 	pathfree = node->nd_pathfree;
 	npath = npathfree = NULL;
 	vhold(vp);
 	NODE_UNLOCK(node);
 
+	vref(rootvnode);
 	NDINIT_ATVP(&ni, LOOKUP, MPSAFE | FOLLOW, UIO_SYSSPACE, path, rootvnode,
 	    curthread);
 	error = namei(&ni);
-	vfslocked = NDHASGIANT(&ni);
 	if (error == 0) {
 		if (vp != ni.ni_vp) {
 			printf("fsnotify: vnode was replaced between lookups: %s\n",
@@ -1012,10 +1086,12 @@
 		}
 		NDFREE(&ni, 0);
 	}
-	if (error != 0)
+	if (error != 0) {
+		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 		error = vn_fullpath_global(curthread, vp, &npath, &npathfree);
+		VFS_UNLOCK_GIANT(vfslocked);
+	}
 
-	VFS_UNLOCK_GIANT(vfslocked);
 	if ((vp->v_iflag & VI_DOOMED) != 0) {
 		printf("fsnotify: vnode is doomed: %s\n", path);
 		error = ENOENT;
@@ -1083,12 +1159,18 @@
 	return (MAXPATHLEN - 1 - event->ev_pathpos);
 }
 
+static __inline int
+event_userpathlen(struct fnevent *event)
+{
+	/* Count last zero byte */
+	return event_pathlen(event) + 1;
+}
+
 static __inline void
-event_copypath(struct fnevent *event, char *path, int *pathlen)
+event_copypath(struct fnevent *event, char *path)
 {
-	/* Count last zero byte */
-	*pathlen = event_pathlen(event) + 1;
-	memcpy(path, event->ev_pathfree + event->ev_pathpos, *pathlen);
+	memcpy(path, event->ev_pathfree + event->ev_pathpos,
+	    event_userpathlen(event));
 }
 
 static void
@@ -1186,6 +1268,13 @@
     struct fnwatch **watchpp)
 {
 	struct fnwatch *watch;
+	struct fnwatch *w;
+
+	mask &= ~FN_FLAGS_INTERNAL;
+	if ((mask & FN_FLAGS) != 0) {
+		printf("fsnotify: invalid watch mask: %08x\n", mask);
+		mask &= ~FN_FLAGS;
+	}
 
 	printf("session_addwatch: %s: node %p  session %p\n",
 	    node->nd_path, node, ss);
@@ -1199,6 +1288,16 @@
 	watch->wt_node = node;
 
 	SESSION_LOCK(ss);
+	TAILQ_FOREACH(w, &ss->ss_watchlist, wt_sessionentry) {
+		if (w->wt_node != node)
+			continue;
+		if ((w->wt_mask & mask) == mask) {
+			SESSION_UNLOCK(ss);
+			watch_free(watch);
+			return (EEXIST);
+		}
+		break;
+	}
 	TAILQ_INSERT_TAIL(&ss->ss_watchlist, watch, wt_sessionentry);
 	SESSION_UNLOCK(ss);
 
@@ -1279,24 +1378,23 @@
 	MPASS(fsnotify_proc != NULL && fsnotify_proc == curthread->td_proc);
 
 	FILEDESC_XLOCK(fsnotify_proc->p_fd);
-	if (fsnotify_proc->p_fd->fd_cdir == NULL) {
-		fsnotify_proc->p_fd->fd_cdir = rootvnode;
-		vref(rootvnode);
-	}
-	if (fsnotify_proc->p_fd->fd_rdir == NULL) {
-		fsnotify_proc->p_fd->fd_rdir = rootvnode;
-		vref(rootvnode);
-	}
+	MPASS(fsnotify_proc->p_fd->fd_cdir == NULL);
+	fsnotify_proc->p_fd->fd_cdir = rootvnode;
+	vref(rootvnode);
+	MPASS(fsnotify_proc->p_fd->fd_rdir == NULL);
+	fsnotify_proc->p_fd->fd_rdir = rootvnode;
+	vref(rootvnode);
 	FILEDESC_XUNLOCK(fsnotify_proc->p_fd);
 
-	QUEUE_LOCK();
 	while (1) {
+		QUEUE_LOCK();
+again:
 		if (fsnotify_proc == NULL)
 			break;
 		if (TAILQ_EMPTY(&fsnotify_queue)) {
 			msleep(&fsnotify_queue, &fsnotify_queue_mtx, PWAIT,
 			    "wait", 0);
-			continue;
+			goto again;
 		}
 		event = TAILQ_FIRST(&fsnotify_queue);
 		TAILQ_REMOVE(&fsnotify_queue, event, ev_queueentry);
@@ -1326,22 +1424,21 @@
 			event_free(event);
 			continue;
 		}
-		if (node->nd_vnode != NULL)
+		if (node->nd_vnode != NULL &&
+		    (event->ev_mask & FN_DESTROY) == 0)
 			node_updatepath(node);
 		else
 			printf("fsnotify: vnode not found, reusing cached path: %s\n",
 			    node->nd_path);
 		event_prependpath(event, node);
 
-		if (event->ev_mask & FE_DESTROY)
+		if (event->ev_mask & FN_DESTROY)
 			node_detachallwatches(node);
 		else
 			NODE_UNLOCK(node);
 
 		for (i = 0; i < handle_count; i++)
 			session_enqueue(&event->ev_handlebuf[i]);
-
-		QUEUE_LOCK();
 	}
 
 	wakeup_one(&fsnotify_queue);

==== //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vfs_subr.c#5 (text+ko) ====

@@ -284,10 +284,12 @@
 	.fno_inactive	= (fno_inactive_t *) fsnotify_nullop,
 	.fno_link	= (fno_link_t *) fsnotify_nullop,
 	.fno_mkdir	= (fno_mkdir_t *) fsnotify_nullop,
+	.fno_open	= (fno_open_t *) fsnotify_nullop,
 	.fno_reclaim	= (fno_reclaim_t *) fsnotify_nullop,
 	.fno_remove	= (fno_remove_t *) fsnotify_nullop,
 	.fno_rename	= (fno_rename_t *) fsnotify_nullop,
 	.fno_rmdir	= (fno_rmdir_t *) fsnotify_nullop,
+	.fno_setattr	= (fno_setattr_t *) fsnotify_nullop,
 	.fno_symlink	= (fno_symlink_t *) fsnotify_nullop,
 	.fno_write	= (fno_write_t *) fsnotify_nullop,
 };
@@ -3938,6 +3940,15 @@
 }
 
 void
+vop_open_post(void *ap, int rc)
+{
+	struct vop_open_args *a = ap;
+
+	if (!rc)
+		fsnotify_curops->fno_open(a);
+}
+
+void
 vop_close_post(void *ap, int rc)
 {
 	struct vop_close_args *a = ap;
@@ -4049,8 +4060,10 @@
 {
 	struct vop_setattr_args *a = ap;
 
-	if (!rc)
+	if (!rc) {
 		VFS_KNOTE_LOCKED(a->a_vp, NOTE_ATTRIB);
+		fsnotify_curops->fno_setattr(ap);
+	}
 
 }
 

==== //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vnode_if.src#3 (text+ko) ====

@@ -123,6 +123,7 @@
 
 
 %% open		vp	L L L
+%! open		post	vop_open_post
 
 vop_open {
 	IN struct vnode *vp;

==== //depot/projects/soc2010/ilya_fsnotify/src/sys/sys/fsnotify.h#6 (text+ko) ====

@@ -30,33 +30,53 @@
 #ifndef	_SYS_FSNOTIFY_H_
 #define	_SYS_FSNOTIFY_H_
 
-#define	FE_CREATE		0x0001
-#define	FE_REMOVE		0x0002
-#define	FE_RENAME_FROM		0x0004
-#define	FE_RENAME_TO		0x0008
+/* Events */
+#define	FN_CREATE		0x00000001
+#define FN_OPEN			0x00000002
+#define FN_SETATTR		0x00000004
+#define	FN_REMOVE		0x00000008
+#define	FN_RENAME_FROM		0x00000010
+#define	FN_RENAME_TO		0x00000020
+#define	FN_CLOSE_RO		0x00000040
+#define	FN_CLOSE_RW		0x00000080
+
+#define	FN_CLOSE		(FN_CLOSE_RO | FN_CLOSE_RW)
+#define	FN_RENAME		(FN_RENAME_FROM | FN_RENAME_TO)
+
+#define FN_ALL			(FN_OPEN | FN_CLOSE | FN_CREATE | \
+				FN_REMOVE | FN_RENAME | FN_SETATTR)
+
+/* Event flags */
+#define	FN_ISDIR		0x00010000
+#define	FN_DESTROY		0x00020000
+#define	FN_UNMOUNT		0x00040000
+#define	FN_OVERFLOW		0x00080000
+
+#define FN_FLAGS		(FN_ISDIR | FN_DESTROY | FN_UNMOUNT | \
+				FN_OVERFLOW)
 
-#define	FE_CLOSE		0x0010
-#define	FE_INACTIVE		0x0020
-#define	FE_INACTIVE_CHANGED	0x0040
+/* Extra flags */
+#define FN_CLOSEFD		0x01000000
 
-#define	FE_DESTROY		0x0080
+#define FN_FLAGS_INTERNAL	FN_CLOSEFD
 
+/* Ioctls */
 #define	FSNOTIFY_ADDWATCH	_IOWR('F', 1, struct fsnotify_addwatch_args)
 #define	FSNOTIFY_RMWATCH	_IOW('F', 2, int)
 
 struct fsnotify_event {
-	int32_t		fe_wd;
-	uint32_t	fe_mask;
-	uint32_t	fe_cookie;
-	uint32_t	fe_namelen;
-	ino_t		fe_fileno;
-	char		fe_name[0];
+	int32_t		wd;
+	uint32_t	mask;
+	uint32_t	cookie;
+	uint32_t	len;
+	ino_t		fileno;
+	char		name[0];
 };
 
 struct fsnotify_addwatch_args {
-	int		fa_fd;
-	uint32_t	fa_mask;
-	int32_t		fa_wd;
+	int		fd;
+	uint32_t	mask;
+	int32_t		wd;
 };
 
 #ifdef _KERNEL
@@ -69,9 +89,11 @@
 struct vop_inactive_args;
 struct vop_link_args;
 struct vop_mkdir_args;
+struct vop_open_args;
 struct vop_remove_args;
 struct vop_rename_args;
 struct vop_rmdir_args;
+struct vop_setattr_args;
 struct vop_symlink_args;
 struct vop_write_args;
 
@@ -80,10 +102,12 @@
 typedef void fno_inactive_t(struct vop_inactive_args *);
 typedef void fno_link_t(struct vop_link_args *);
 typedef void fno_mkdir_t(struct vop_mkdir_args *);
+typedef void fno_open_t(struct vop_open_args *);
 typedef void fno_reclaim_t(struct vnode *);
 typedef void fno_remove_t(struct vop_remove_args *);
 typedef void fno_rename_t(struct vop_rename_args *);
 typedef void fno_rmdir_t(struct vop_rmdir_args *);
+typedef void fno_setattr_t(struct vop_setattr_args *);
 typedef void fno_symlink_t(struct vop_symlink_args *);
 typedef void fno_write_t(struct vop_write_args *);
 
@@ -93,10 +117,12 @@
 	fno_inactive_t	*fno_inactive;
 	fno_link_t	*fno_link;
 	fno_mkdir_t	*fno_mkdir;
+	fno_open_t	*fno_open;
 	fno_reclaim_t	*fno_reclaim;
 	fno_remove_t	*fno_remove;
 	fno_rename_t	*fno_rename;
 	fno_rmdir_t	*fno_rmdir;
+	fno_setattr_t	*fno_setattr;
 	fno_symlink_t	*fno_symlink;
 	fno_write_t	*fno_write;
 };

==== //depot/projects/soc2010/ilya_fsnotify/src/sys/sys/vnode.h#4 (text+ko) ====

@@ -714,6 +714,7 @@
 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_remove_post(void *a, int rc);
 void	vop_rename_post(void *a, int rc);
 void	vop_rename_pre(void *a);

==== //depot/projects/soc2010/ilya_fsnotify/src/sys/tools/vnode_if.awk#3 (text+ko) ====



More information about the p4-projects mailing list