On Mon, 18 Jul 2011, Linus Torvalds wrote:
On Mon, Jul 18, 2011 at 12:47 PM, Al Viro [off-list ref] wrote:
quoted
Huh? We do __d_drop() in there, and do that before we start messing
with ->d_inode.
Hmm. Yes, looking at it, the ordering all seems correct. But then what
did Hugh see at all?
The inode thing he got from d_inode is re-verified by
__d_lookup_rcu(). So if inode is NULL, that means that the other CPU
has done dentry_iput(), which means that __d_drop has already
happened, which means that the dentry has been removed from the hash
list *and* the count has been incremented.
__d_lookup_rcu() is being careful about *inode, yes.
But I'd forgotten it was even setting it: doesn't that setting get
overridden later by the more careless *inode = path->d_entry->d_inode
at the head of __follow_mount_rcu()'s loop?
Perhaps that line just needs to be moved to the tail of the loop?
Hugh