Messages in this thread | | | From | Nikita Danilov <> | Date | Fri, 23 Apr 2004 17:02:40 +0400 | Subject | d_splice_alias() problem. |
| |
Hello,
for some time I am observing that during stress tests over NFS
shrink_slab->...->prune_dcache()->prune_one_dentry()->...->iput()
is called on inode with ->i_nlink == 0 which results in truncate and file deletion. This is wrong in general (file system is re-entered), and deadlock prone on some file systems.
After some debugging, I tracked problem down the to d_splice_alias() failing to identify dentries when necessary.
Suppose we have an inode with ->i_nlink == 1. It's accessed over NFS and DCACHE_DISCONNECTED dentry D1 is created for it. Then, unlink request comes for this file. nfsd looks name up in the parent directory (nfsd_unlink()->lookup_one_len()). File system back-end uses d_splice_alias(), but it only works for directories and we end up with second (this time connected) dentry D2.
D2 is successfully unlinked, file has ->i_nlink == 0, and ->i_count == 1 from D1, and when prune_dcache() hits D1 bad things happen.
It's hard to imagine how new name can be identified with one among multiple anonymous dentries, which is necessary for NFSEXP_NOSUBTREECHECK export to work reliably.
One possible work-around is to forcibly destroy all remaining DCACHE_DISCONNECTED dentries when ->i_nlink drops to zero, but I am not sure that this is possible and solves all problems of having more dentries than there are nlinks.
Nikita. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |