Re: [patch] stop inotify from sending random DELETE_SELF event under load

Linus Torvalds
2005-09-20T02:20:31Z

On Mon, 19 Sep 2005, John McCutchan wrote:
>
> To quote you:

Yeah, sometimes I'm more right than other times. That wasn't one of them.

It's actually _almost_ right. The problem being that dentry_iput() is
called for non-delete events too.

However, your patch is _worse_. Your patch will cause it not to report the
delete at all, because what will happen is that if the delete() is done
while somebody else has a pointer to the dentry, then we won't call
"dentry_iput()" with a "delete" AT ALL. We will only call it later when
the _other_ person (who didn't do a delete) releases the dentry.

See? It's very very wrong to send a flag that depends on the call-chain,
because the call-chain is _not_ what determines whether the inode gets
deleted or not.

The only way to know whether it gets deleted or not is whan the actual
i_nlink goes down to 0, and the inode gets deleted. Ie exactly the
generic_delete_inode() case.

But if you keep a reference to the inode, that will never actually happen.
Hmm.

Who wants that inode delete event anyway? It's fundamentally harder than
removing a name, partly because of the delayed delete, partly because an
inode may be reachable multiple ways.

Maybe this patch instead? It's not going to be reliable on networked
filesystems, though. Nothing is.

Linus

---
diff --git a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -102,7 +102,8 @@ static inline void dentry_iput(struct de
list_del_init(&dentry->d_alias);
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
- fsnotify_inoderemove(inode);
+ if (!inode->i_nlink)
+ fsnotify_inoderemove(inode);
if (dentry->d_op && dentry->d_op->d_iput)
dentry->d_op->d_iput(dentry, inode);
else