mechanism for busy inodes in NFS

Bill Hawes (whawes@star.net)
Thu, 04 Dec 1997 10:55:18 -0500


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.

The operations for task 1 are protected from file lookup and creations
in that directory, but this doesn't prevent file creation in other
directories from proceeding, and the new file may very well reuse the
just-released inode. (This depends only on the underlying filesystem's
policy on inode reuse.)

The net result is that the NFS filehandle of the inode isn't updated
locally because the inode already exists. Since the NFS server may have
specified a different filehandle, there's a potential stale filehandle
or file corruption problem.

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. So the sequence would be something like
verify d_count == 1
unhash dentry
iput inode (dentry negative, unhashed)
nfs unlink
success: rehash negative dentry
failure: do nothing

Does this seem like a reasonable resolution?

Regards,
Bill