I don't fully understand the dcache/dentry code yet, but it seems to me
that the dentry could be freed any time after i_count decreases to equal
the number of dentry counts. So if dentries reference the inode 4
times, when i_count drops to 4, it's time to think about freeing the
dentries (and thus eventually the inode.)
So maybe this would work: maintain a count of the number of dentry
references to the inode. In iput(), if i_count drops to this number,
walk the i_dentry chain and set a "may free" bit. (Has to be
non-blocking). In find_inode, walk the dentry chain and clear the bit.
Then your garbage collector can use any dentry with "may free" as a
candidate to be freed, along with LRU or other usage considerations.
BTW, for testing purposes a "random decimation" algorithm would be good
for freeing dentries -- just blow away 10% of the freeable entries at
each interval. By not following any sensible usage pattern this would
tend to reveal all the race conditions over time ...
Regards,
Bill Hawes