Re: 2.6.16-rc5-mm1

Nick Piggin
2006-03-02T04:52:23Z

[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]

Andrew Morton wrote:

> Maybe you're not running applications which install inotify watches. This
> is apparently triggerable by doing `touch foo;rm foo;touch foo' in a watched
> directory.
>
> Nick, isn't it simply a matter of..
>

Sorry, I forgot about that. With that patch, d_instantiate can still get some
warnings. The following one should fix that and also makes the watch creation
deletion loop-over-all-dentrys ignore negative dentrys too.

I'm not sure what the cleanest way to do this is. I'm fairly sure the vfs
guys do not want a DENTRY_INOTIFY_ flag in fs/dcache.c, so I've added a
comment there.

I also don't know whether or not the inotify guys want parent events on
negative entries. They don't appear to now, so I'll take that as a no.

After the DENTRY_INOTIFY_PARENT_WATCHED debugging stuff is taken out, that
flag will basically be undefined for negative dentrys rather than always
clear (after this patch). I'm not sure whether the vfs people consider that
to be unclean.

--
SUSE Labs, Novell Inc.

[-- Attachment #2: inotify-dentry-flag-fix.patch --]
[-- Type: text/plain, Size: 1314 bytes --]

Index: linux-2.6/fs/dcache.c
===================================================================
--- linux-2.6.orig/fs/dcache.c
+++ linux-2.6/fs/dcache.c
@@ -1177,6 +1177,9 @@ void d_delete(struct dentry * dentry)
spin_lock(&dentry->d_lock);
isdir = S_ISDIR(dentry->d_inode->i_mode);
if (atomic_read(&dentry->d_count) == 1) {
+ /* remove this and other inotify debug checks after 2.6.18 */
+ dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
+
dentry_iput(dentry);
fsnotify_nameremove(dentry, isdir);
return;
Index: linux-2.6/fs/inotify.c
===================================================================
--- linux-2.6.orig/fs/inotify.c
+++ linux-2.6/fs/inotify.c
@@ -390,6 +390,7 @@ static inline int inotify_inode_watched(

/*
* Get child dentry flag into synch with parent inode.
+ * Flag should always be clear for negative dentrys.
*/
static void set_dentry_child_flags(struct inode *inode, int watched)
{
@@ -400,6 +401,10 @@ static void set_dentry_child_flags(struc
struct dentry *child;

list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
+ if (!child->d_inode) {
+ WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
+ continue;
+ }
spin_lock(&child->d_lock);
if (watched) {
WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);