diff -ru clean/linux-2.6.6/fs/attr.c linux-2.6.6/fs/attr.c --- clean/linux-2.6.6/fs/attr.c 2004-05-09 22:32:01.000000000 -0400 +++ linux-2.6.6/fs/attr.c 2004-05-11 18:38:22.000000000 -0400 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -184,8 +185,10 @@ } if (!error) { unsigned long dn_mask = setattr_mask(ia_valid); - if (dn_mask) + if (dn_mask) { dnotify_parent(dentry, dn_mask); + inotify_dentry_queue_event (dentry, dn_mask); + } } return error; } diff -ru clean/linux-2.6.6/fs/inode.c linux-2.6.6/fs/inode.c --- clean/linux-2.6.6/fs/inode.c 2004-05-09 22:33:21.000000000 -0400 +++ linux-2.6.6/fs/inode.c 2004-05-11 19:09:47.000000000 -0400 @@ -402,6 +402,8 @@ * * If the inode has metadata buffers attached to mapping->private_list then * try to remove them. + * + * If the inode has watchers we can not free it. */ static void prune_icache(int nr_to_scan) { @@ -420,7 +422,7 @@ inode = list_entry(inode_unused.prev, struct inode, i_list); - if (inode->i_state || atomic_read(&inode->i_count)) { + if (inode->i_state || atomic_read(&inode->i_count) || atomic_read(&inode->watcher_count)) { list_move(&inode->i_list, &inode_unused); continue; } diff -ru clean/linux-2.6.6/fs/Makefile linux-2.6.6/fs/Makefile --- clean/linux-2.6.6/fs/Makefile 2004-05-09 22:32:38.000000000 -0400 +++ linux-2.6.6/fs/Makefile 2004-05-11 18:39:44.000000000 -0400 @@ -10,7 +10,7 @@ namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \ dcache.o inode.o attr.o bad_inode.o file.o dnotify.o \ filesystems.o namespace.o seq_file.o xattr.o libfs.o \ - fs-writeback.o mpage.o direct-io.o aio.o + fs-writeback.o mpage.o direct-io.o aio.o inotify.o obj-$(CONFIG_EPOLL) += eventpoll.o obj-$(CONFIG_COMPAT) += compat.o diff -ru clean/linux-2.6.6/fs/read_write.c linux-2.6.6/fs/read_write.c --- clean/linux-2.6.6/fs/read_write.c 2004-05-09 22:32:52.000000000 -0400 +++ linux-2.6.6/fs/read_write.c 2004-05-11 18:41:29.000000000 -0400 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -214,8 +215,10 @@ ret = file->f_op->read(file, buf, count, pos); else ret = do_sync_read(file, buf, count, pos); - if (ret > 0) + if (ret > 0) { dnotify_parent(file->f_dentry, DN_ACCESS); + inotify_dentry_queue_event(file->f_dentry, IN_ACCESS); + } } } @@ -258,8 +261,10 @@ ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); - if (ret > 0) + if (ret > 0) { dnotify_parent(file->f_dentry, DN_MODIFY); + inotify_dentry_queue_event(file->f_dentry, IN_MODIFY); + } } } @@ -473,9 +478,12 @@ out: if (iov != iovstack) kfree(iov); - if ((ret + (type == READ)) > 0) + if ((ret + (type == READ)) > 0) { dnotify_parent(file->f_dentry, (type == READ) ? DN_ACCESS : DN_MODIFY); + inotify_dentry_queue_event(file->f_dentry, + (type == READ) ? IN_ACCESS : IN_MODIFY); + } return ret; } diff -ru clean/linux-2.6.6/include/linux/fs.h linux-2.6.6/include/linux/fs.h --- clean/linux-2.6.6/include/linux/fs.h 2004-05-09 22:32:26.000000000 -0400 +++ linux-2.6.6/include/linux/fs.h 2004-05-11 18:42:25.000000000 -0400 @@ -447,6 +447,10 @@ unsigned long i_dnotify_mask; /* Directory notify events */ struct dnotify_struct *i_dnotify; /* for directory notifications */ + struct list_head watchers; + unsigned long watchers_mask; + atomic_t watcher_count; + unsigned long i_state; unsigned long dirtied_when; /* jiffies of first dirtying */