PERFORCE change 182318 for review
Ilya Putsikau
ilya at FreeBSD.org
Thu Aug 12 13:34:23 UTC 2010
http://p4web.freebsd.org/@@182318?ac=10
Change 182318 by ilya at 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) ====
More information about the p4-projects
mailing list