A few filesystems modify dentry.d_flags under non-obvious locking.  To
consolidate that field wth d_vfs_flags they need to take ->d_lock



---

 /dev/null                   |    0 
 25-akpm/fs/afs/dir.c        |    2 ++
 25-akpm/fs/autofs4/root.c   |   13 ++++++++++++-
 25-akpm/fs/exportfs/expfs.c |    4 ++++
 25-akpm/fs/nfs/unlink.c     |    4 ++++
 5 files changed, 22 insertions(+), 1 deletion(-)

diff -puN fs/nfs/unlink.c~d_flags-locking-fix fs/nfs/unlink.c
--- 25/fs/nfs/unlink.c~d_flags-locking-fix	Mon May 10 15:42:22 2004
+++ 25-akpm/fs/nfs/unlink.c	Mon May 10 15:42:22 2004
@@ -180,7 +180,9 @@ nfs_async_unlink(struct dentry *dentry)
 	task->tk_action = nfs_async_unlink_init;
 	task->tk_release = nfs_async_unlink_release;
 
+	spin_lock(&dentry->d_lock);
 	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
+	spin_unlock(&dentry->d_lock);
 	data->cred = rpcauth_lookupcred(clnt->cl_auth, 0);
 
 	rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL);
@@ -210,7 +212,9 @@ nfs_complete_unlink(struct dentry *dentr
 		return;
 	data->count++;
 	nfs_copy_dname(dentry, data);
+	spin_lock(&dentry->d_lock);
 	dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
+	spin_unlock(&dentry->d_lock);
 	if (data->task.tk_rpcwait == &nfs_delete_queue)
 		rpc_wake_up_task(&data->task);
 	nfs_put_unlinkdata(data);
diff -puN fs/afs/dir.c~d_flags-locking-fix fs/afs/dir.c
--- 25/fs/afs/dir.c~d_flags-locking-fix	Mon May 10 15:42:22 2004
+++ 25-akpm/fs/afs/dir.c	Mon May 10 15:42:22 2004
@@ -615,7 +615,9 @@ static int afs_d_revalidate(struct dentr
 
 	/* the dirent, if it exists, now points to a different vnode */
  not_found:
+	spin_lock(&dentry->d_lock);
 	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
+	spin_unlock(&dentry->d_lock);
 
  out_bad:
 	if (inode) {
diff -puN fs/autofs4/root.c~d_flags-locking-fix fs/autofs4/root.c
--- 25/fs/autofs4/root.c~d_flags-locking-fix	Mon May 10 15:42:22 2004
+++ 25-akpm/fs/autofs4/root.c	Mon May 10 15:42:22 2004
@@ -326,7 +326,9 @@ static int try_to_fill_dentry(struct den
 		/* Turn this into a real negative dentry? */
 		if (status == -ENOENT) {
 			dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
+			spin_lock(&dentry->d_lock);
 			dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+			spin_unlock(&dentry->d_lock);
 			return 1;
 		} else if (status) {
 			/* Return a negative dentry, but leave it "pending" */
@@ -338,13 +340,17 @@ static int try_to_fill_dentry(struct den
 		DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s\n",
 			dentry->d_name.len, dentry->d_name.name));
 
+		spin_lock(&dentry->d_lock);
 		dentry->d_flags |= DCACHE_AUTOFS_PENDING;
+		spin_unlock(&dentry->d_lock);
 		status = autofs4_wait(sbi, dentry, NFY_MOUNT);
 
 		DPRINTK(("try_to_fill_entry: mount done status=%d\n", status));
 
 		if (status) {
+			spin_lock(&dentry->d_lock);
 			dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+			spin_unlock(&dentry->d_lock);
 			return 0;
 		}
 	}
@@ -354,7 +360,9 @@ static int try_to_fill_dentry(struct den
 	if (!autofs4_oz_mode(sbi))
 		autofs4_update_usage(dentry);
 
+	spin_lock(&dentry->d_lock);
 	dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+	spin_unlock(&dentry->d_lock);
 	return 1;
 }
 
@@ -478,8 +486,11 @@ static struct dentry *autofs4_root_looku
 	 */
 	dentry->d_op = &autofs4_root_dentry_operations;
 
-	if (!oz_mode)
+	if (!oz_mode) {
+		spin_lock(&dentry->d_lock);
 		dentry->d_flags |= DCACHE_AUTOFS_PENDING;
+		spin_unlock(&dentry->d_lock);
+	}
 	dentry->d_fsdata = NULL;
 	d_add(dentry, NULL);
 
diff -L fs/intermezzo/dir.c -puN /dev/null /dev/null
diff -puN fs/exportfs/expfs.c~d_flags-locking-fix fs/exportfs/expfs.c
--- 25/fs/exportfs/expfs.c~d_flags-locking-fix	Mon May 10 15:42:22 2004
+++ 25-akpm/fs/exportfs/expfs.c	Mon May 10 15:42:23 2004
@@ -155,11 +155,15 @@ find_exported_dentry(struct super_block 
 
 		if (!IS_ROOT(pd)) {
 			/* must have found a connected parent - great */
+			spin_lock(&pd->d_lock);
 			pd->d_flags &= ~DCACHE_DISCONNECTED;
+			spin_unlock(&pd->d_lock);
 			noprogress = 0;
 		} else if (pd == sb->s_root) {
 			printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
+			spin_lock(&pd->d_lock);
 			pd->d_flags &= ~DCACHE_DISCONNECTED;
+			spin_unlock(&pd->d_lock);
 			noprogress = 0;
 		} else {
 			/* we have hit the top of a disconnected path.  Try

_