Subject: Re: [NFS] Re: [autofs] VFS: Busy inodes after unmount on 2 way SMP
From: Trond Myklebust <[email-masked]>
To: Matt C <[email-masked]>
Cc: Trond Myklebust <[email-masked]>, Olaf Hering <[email-masked]>, "H. Peter Anvin" <[email-masked]>, Arun Sharma <[email-masked]>, <[email-masked]>, <[email-masked]>, Ian Kent <[email-masked]>
Date: Thu, 25 Sep 2003 17:24:49 -0700

>>>>> " " == Matt C <Matt> 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 <linux/sunrpc/sched.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
+#include <linux/wait.h>

 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  -  [email-masked]
https://lists.sourceforge.net/lists/listinfo/nfs