> I think I've found the path by which busy inodes are occurring with NFS
> operations. It's basically a race between the inode being freed on the
> server and a being reused in a new directory. For example,
>
> Task 1 deletes foo: Task 2 creates file home/bar:
>
> File foo has inode #123
> (1) verify d_count == 1
> (2) drop dentry
> (3) nfs_proc_unlink
> inode #123 now free
> . nfs_create succeeds, returns
> . inode #123
> . dentry home/bar d_count ==1,
> . inode i_count == 2.
> (4) successful unlink, rehash foo
> (5) d_delete calls iput, but
> inode is already in use again.
> I think the best way to handle this is to iput the inode _before_ doing
> the unlink operation, then if the unlink succeeds rehash the negative
> dentry. [...]
wouldnt it be better to first look up newly created inodes, and wait for
still pending operations if still present? [new inodes wont be present
locally 99% of the cases]. We should not assume anything about the order
RPC requests get scheduled by the server, me thinks.
Your suggestion i think works identically well, but it rather relies on
the local directory being locked than on (more fundamental) RPC scheduling
properties. So if one time we want to parallelize NFS operations more
aggressively (eg. unlock the parent directory _before_ getting back a
reply from the server?), we might be bitten by the 'early iput()' trick?
Plus, a 'filehandle number uniqueness check' might catch a few bugs as
well.
-- mingo