Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Aug 2010 13:34:22 GMT
From:      Ilya Putsikau <ilya@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 182318 for review
Message-ID:  <201008121334.o7CDYMkr032568@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@182318?ac=10

Change 182318 by ilya@ilya_triton on 2010/08/12 13:33:41

	Update node name in vop_rename hook. Use node name if no name event available.
	Use path argument as inotify does, not file descriptor, to add watch.
	Make event struct the same as linux' inotify_event. Remove inode number.
	Add tests I've forgotten to commit last time.

Affected files ...

.. //depot/projects/soc2010/ilya_fsnotify/src/sys/kern/vfs_notify.c#11 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/sys/fsnotify.h#8 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/sys/sys/inotify.h#2 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.02.out#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.03.out#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/fsnotify/regress.04.out#1 add
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/inotify/regress.01.out#2 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/inotify/regress.01.out-linux#2 edit
.. //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/inotify/regress.sh#2 edit

Differences ...

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

@@ -76,7 +76,7 @@
 	struct mtx		nd_mtx;
 	struct vnode		*nd_vnode;
 	struct mount		*nd_mount;
-	char			*nd_name;
+	char			nd_name[NAME_MAX + 1];
 	ino_t			nd_ino;
 	volatile u_int		nd_refcnt;
 	int			nd_namelen;
@@ -181,8 +181,8 @@
     int mask, struct fnwatch **watchpp);
 static int session_rmwatch(struct fnsession *ss, int wd);
 
-static struct fnnode* node_alloc(struct vnode *vp, ino_t ino, char *name,
-    int namelen);
+static struct fnnode* node_alloc(struct vnode *vp, ino_t ino);
+static void node_setname(struct fnnode *node, struct componentname *cnp);
 static struct fnnode* node_lookup(struct vnode *vp);
 static struct fnnode* node_lookupex(struct vnode *vp, ino_t *inop, int flags);
 static void node_hold(struct fnnode *node);
@@ -379,7 +379,7 @@
 	char user_buf[sizeof(struct fsnotify_event) + NAME_MAX + 1];
 
 	printf("fsnotify_read: offset %jd\n", uio->uio_offset);
-	
+
 	if (uio->uio_resid == 0)
 		return (0);
 
@@ -419,7 +419,6 @@
 		}
 		fe->wd = watch->wt_wd;
 		fe->mask = (FN_FLAGS | watch->wt_mask) & event->ev_mask;
-		fe->fileno = event->ev_node->nd_ino;
 		fe->cookie = event->ev_cookie;
 		memcpy(fe->name, event->ev_name, event->ev_namelen + 1);
 
@@ -468,56 +467,33 @@
 {
 	struct fnnode *node;
 	struct fnwatch *watch;
-	struct file *fp;
-	struct filedesc *fdp;
-	struct vnode *vp, *xvp;
-	char *name;
+	struct nameidata nd;
 	ino_t ino;
 	int error = 0, vfslocked;
-	u_int namelen;
+
+	NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | SAVENAME, UIO_USERSPACE,
+	    ap->path, td);
+	error = namei(&nd);
+	vfslocked = NDHASGIANT(&nd);
+	if (error != 0)
+		return (error);
 
-	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);
-	/* FIXME FIXME */
-	if (vp->v_type != VDIR)
-		return (EINVAL);
-	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+	MPASS((nd.ni_cnd.cn_flags & HASBUF) != 0);
+	printf("FOUND NAME: %.*s\n", (int)nd.ni_cnd.cn_namelen, nd.ni_cnd.cn_nameptr);
 	ino = 0;
-	node = node_lookupex(vp, &ino, LOOKUP_IGNINVAL);
+	node = node_lookupex(nd.ni_vp, &ino, LOOKUP_IGNINVAL);
 	if (node != NULL) {
 		node_watchhold(node);
 		NODE_UNLOCK(node);
-		VFS_UNLOCK_GIANT(vfslocked);
 	} else {
-		namelen = NAME_MAX;
-		name = malloc(namelen + 1, M_FSNOTIFY, M_WAITOK);
-		xvp = vp;
-		error = vn_vptocnp(&xvp, td->td_ucred, name, &namelen);
-		if (error == 0) {
-			memcpy(name, name + namelen, NAME_MAX - namelen);
-			namelen = NAME_MAX - namelen;
-			name[namelen] = '\0';
-			node = node_alloc(vp, ino, name, namelen);
-			node_watchhold(node);
-			vdrop(xvp);
-			NODE_UNLOCK(node);
-		} else
-			free(name, M_FSNOTIFY);
-		VFS_UNLOCK_GIANT(vfslocked);
+		node = node_alloc(nd.ni_vp, ino);
+		node_setname(node, &nd.ni_cnd);
+		node_watchhold(node);
+		NODE_UNLOCK(node);
 	}
+	NDFREE(&nd, 0);
+	VFS_UNLOCK_GIANT(vfslocked);
 
-	if ((ap->mask & FN_CLOSEFD) != 0) {
-		kern_close(td, ap->fd);
-		ap->fd = -1;
-	}
-
 	if (error != 0)
 		return (error);
 
@@ -784,9 +760,8 @@
 	}
 	fnode = node_lookupex(ap->a_fvp, NULL, 0);
 	if (fnode != NULL) {
+		node_setname(fnode, ap->a_tcnp);
 		NODE_UNLOCK(fnode);
-		/* TODO */
-		/* mark path stale */
 	}
 
 	fdirnode = node_lookupex(ap->a_fdvp, NULL, 0);
@@ -883,7 +858,7 @@
 	if (refcount_release(&node->nd_refcnt) != 0) {
 		printf("node_drop: free node %p\n", node);
 		MPASS(node->nd_vnode == NULL);
-		KASSERT(node->nd_watchcount == 0 && 
+		KASSERT(node->nd_watchcount == 0 &&
 		    TAILQ_EMPTY(&node->nd_watchlist),
 		    ("Invalid watch count: %d", node->nd_watchcount));
 		if (node->nd_ino != 0) {
@@ -892,7 +867,6 @@
 			INOHASH_UNLOCK();
 		}
 		mtx_destroy(&node->nd_mtx);
-		free(node->nd_name, M_FSNOTIFY);
 		free(node, M_FSNOTIFY);
 	}
 }
@@ -907,7 +881,7 @@
 }
 
 static struct fnnode *
-node_alloc(struct vnode *vp, ino_t ino, char *path, int namelen)
+node_alloc(struct vnode *vp, ino_t ino)
 {
 	struct fnnode *node;
 
@@ -922,8 +896,6 @@
 	TAILQ_INIT(&node->nd_watchlist);
 
 	node->nd_ino = ino;
-	node->nd_name = path;
-	node->nd_namelen = namelen;
 
 	NODE_LOCK(node);
 
@@ -942,6 +914,15 @@
 }
 
 static void
+node_setname(struct fnnode *node, struct componentname *cnp)
+{
+	MPASS(cnp->cn_namelen <= NAME_MAX);
+	node->nd_namelen = cnp->cn_namelen;
+	memcpy(node->nd_name, cnp->cn_nameptr, node->nd_namelen);
+	node->nd_name[node->nd_namelen] = '\0';
+}
+
+static void
 node_detachallwatches(struct fnnode *node)
 {
 	struct fnwatch *watch = NULL;
@@ -1134,12 +1115,20 @@
 	char *nameptr;
 	int namelen, supermask, watchcount;
 
+again:
 	printf("event_enqueue: %s %x\n",
 	    cnp != NULL ? cnp->cn_nameptr : NULL, mask);
 
 	mtx_assert(&node->nd_mtx, MA_OWNED);
 	watchcount = node->nd_watchcount;
 	supermask = node->nd_supermask & mask;
+	if (cnp != NULL) {
+		nameptr = cnp->cn_nameptr;
+		namelen = cnp->cn_namelen;
+	} else {
+		nameptr = node->nd_name;
+		namelen = node->nd_namelen;
+	}
 	node_hold(node);
 	NODE_UNLOCK(node);
 
@@ -1150,20 +1139,18 @@
 
 	KASSERT(watchcount > 0, ("No watches found"));
 
-	if (cnp != NULL) {
-		nameptr = cnp->cn_nameptr;
-		namelen = cnp->cn_namelen;
-	} else {
-		nameptr = NULL;
-		namelen = 0;
-	}
-
 	if (*cookiep == 0)
 		*cookiep = event_nextcookie();
 
 	event = event_alloc(node, nameptr, namelen, watchcount + 1, mask,
 	    *cookiep);
 
+	if (cnp == NULL && namelen != node->nd_namelen) {
+		event_free(event);
+		NODE_LOCK(node);
+		goto again;
+	}
+
 	QUEUE_LOCK();
 	TAILQ_INSERT_TAIL(&fsnotify_queue, event, ev_queueentry);
 	QUEUE_UNLOCK();

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

@@ -55,28 +55,24 @@
 #define FN_FLAGS		(FN_ISDIR | FN_DESTROY | FN_UNMOUNT | \
 				FN_OVERFLOW)
 
-/* Extra flags */
-#define FN_CLOSEFD		0x01000000
-
 #define FN_INVALID		0x80000000
 
-#define FN_FLAGS_INTERNAL	FN_CLOSEFD
+#define FN_FLAGS_INTERNAL	0
 
 /* Ioctls */
 #define	FSNOTIFY_ADDWATCH	_IOWR('F', 1, struct fsnotify_addwatch_args)
 #define	FSNOTIFY_RMWATCH	_IOW('F', 2, int)
 
 struct fsnotify_event {
-	int32_t		wd;
+	int		wd;
 	uint32_t	mask;
 	uint32_t	cookie;
 	uint32_t	len;
-	ino_t		fileno;
 	char		name[0];
 };
 
 struct fsnotify_addwatch_args {
-	int		fd;
+	char		*path;
 	uint32_t	mask;
 	int32_t		wd;
 };

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

@@ -10,17 +10,15 @@
 #include <sys/types.h>
 #include <sys/fsnotify.h>
 #include <sys/ioctl.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
 /* Keep the same as struct fsnotify_event */
 struct inotify_event {
-	int32_t		wd;
+	int		wd;
 	uint32_t	mask;
 	uint32_t	cookie;
 	uint32_t	len;
-	ino_t		fileno;
 	char		name[0];
 };
 
@@ -76,22 +74,12 @@
 inotify_add_watch(int fd, const char *name, uint32_t mask)
 {
 	struct fsnotify_addwatch_args addwatch;
-	int wfd;
+	int error;
 
-	wfd = open(name, O_RDONLY);
-	if (wfd == -1)
-		return (-1);
-	addwatch.fd = wfd;
-	addwatch.mask = mask | FN_CLOSEFD;
-	if (ioctl(fd, FSNOTIFY_ADDWATCH, &addwatch) != 0) {
-		if (addwatch.fd != -1) {
-			fd = errno;
-			close(wfd);
-			errno = fd;
-		}
-		return (-1);
-	}
-	return (0);
+	addwatch.path = name;
+	addwatch.mask = mask;
+	error = ioctl(fd, FSNOTIFY_ADDWATCH, &addwatch);
+	return (error);
 }
 
 static __inline int

==== //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/inotify/regress.01.out#2 (text+ko) ====


==== //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/inotify/regress.01.out-linux#2 (text+ko) ====


==== //depot/projects/soc2010/ilya_fsnotify/src/tools/regression/inotify/regress.sh#2 (text+ko) ====




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008121334.o7CDYMkr032568>