To: Matt C Cc: Trond Myklebust , Olaf Hering , "H. Peter Anvin" , Arun Sharma , , , Ian Kent Subject: Re: [NFS] Re: [autofs] VFS: Busy inodes after unmount on 2 way SMP Reply-To: trond.myklebust@fys.uio.no From: Trond Myklebust Sender: nfs-admin@lists.sourceforge.net Date: Thu, 25 Sep 2003 17:24:49 -0700 >>>>> " " == Matt C writes: > Hi All- We've been having the 'VFS: Busy inodes after unmount' > problems like crazy on our desktop and server linux boxes > running autofs under 2.4.21 (vanilla). We're using the > autofs-3.1.7 userspace tools, but with the autofs4 kernel > module. > I applied the patch that was attached earlier in this thread to > our kernel and have been running it for the past few days on my > desktop. These errors have completely disappeared, and autofs > is behaving as expected so far. > So, while it might be the wrong thing to do, it does fix our > problems. That changes nothing. It is still not a "fix" that I want to see go into the main kernel. The problem here is that sillyrename needs to hold onto the parent directory's inode until it is done, and yet it cannot know which vfsmount struct to hold onto because that information is not passed down by the VFS. I would rather then have something like the appended patch go in to which force the last process to close the file to actually wait on completion (unless someone signals it with a 'kill -9' - in which case they are knowingly breaking things). Cheers, Trond diff -u --recursive --new-file linux-2.4.22-03-soft2/fs/nfs/dir.c linux-2.4.22-04-fix_unlink/fs/nfs/dir.c --- linux-2.4.22-03-soft2/fs/nfs/dir.c 2002-10-15 06:59:27.000000000 +0200 +++ linux-2.4.22-04-fix_unlink/fs/nfs/dir.c 2003-07-03 12:29:28.000000000 +0200 @@ -994,7 +994,7 @@ struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct dentry *dentry = NULL, *rehash = NULL; - int error = -EBUSY; + int error; /* * To prevent any new references to the target during the rename, @@ -1020,6 +1020,12 @@ */ if (!new_inode) goto go_ahead; + /* If target is a hard link to the source, then noop */ + error = 0; + if (NFS_FILEID(new_inode) == NFS_FILEID(old_inode)) + goto out; + + error = -EBUSY; if (S_ISDIR(new_inode->i_mode)) goto out; else if (atomic_read(&new_dentry->d_count) > 1) { diff -u --recursive --new-file linux-2.4.22-03-soft2/fs/nfs/unlink.c linux-2.4.22-04-fix_unlink/fs/nfs/unlink.c --- linux-2.4.22-03-soft2/fs/nfs/unlink.c 2002-08-11 13:34:02.000000000 +0200 +++ linux-2.4.22-04-fix_unlink/fs/nfs/unlink.c 2003-07-03 12:29:28.000000000 +0200 @@ -12,6 +12,7 @@ #include #include #include +#include struct nfs_unlinkdata { @@ -21,6 +22,9 @@ struct rpc_task task; struct rpc_cred *cred; unsigned int count; + + wait_queue_head_t waitq; + int completed; }; static struct nfs_unlinkdata *nfs_deletes; @@ -133,6 +137,8 @@ put_rpccred(data->cred); data->cred = NULL; dput(dir); + data->completed = 1; + wake_up(&data->waitq); } /** @@ -175,6 +181,8 @@ nfs_deletes = data; data->count = 1; + init_waitqueue_head(&data->waitq); + task = &data->task; rpc_init_task(task, clnt, nfs_async_unlink_done , RPC_TASK_ASYNC); task->tk_calldata = data; @@ -212,7 +220,10 @@ data->count++; nfs_copy_dname(dentry, data); dentry->d_flags &= ~DCACHE_NFSFS_RENAMED; - if (data->task.tk_rpcwait == &nfs_delete_queue) + if (data->task.tk_rpcwait == &nfs_delete_queue) { + struct rpc_clnt *clnt = data->task.tk_client; rpc_wake_up_task(&data->task); + nfs_wait_event(clnt, data->waitq, data->completed == 1); + } nfs_put_unlinkdata(data); } ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs