From owner-p4-projects@FreeBSD.ORG Thu Aug 12 13:34:23 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0442210656A6; Thu, 12 Aug 2010 13:34:22 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6E09710656A4 for ; Thu, 12 Aug 2010 13:34:22 +0000 (UTC) (envelope-from ilya@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 5A6088FC18 for ; Thu, 12 Aug 2010 13:34:22 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o7CDYMSS032571 for ; Thu, 12 Aug 2010 13:34:22 GMT (envelope-from ilya@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o7CDYMkr032568 for perforce@freebsd.org; Thu, 12 Aug 2010 13:34:22 GMT (envelope-from ilya@FreeBSD.org) Date: Thu, 12 Aug 2010 13:34:22 GMT Message-Id: <201008121334.o7CDYMkr032568@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to ilya@FreeBSD.org using -f From: Ilya Putsikau To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182318 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2010 13:34:23 -0000 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 #include #include -#include #include #include /* 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) ====