Commit 87ada13e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] d_flags locking fixes

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
parent 12102e4e
...@@ -615,7 +615,9 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -615,7 +615,9 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
/* the dirent, if it exists, now points to a different vnode */ /* the dirent, if it exists, now points to a different vnode */
not_found: not_found:
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_NFSFS_RENAMED; dentry->d_flags |= DCACHE_NFSFS_RENAMED;
spin_unlock(&dentry->d_lock);
out_bad: out_bad:
if (inode) { if (inode) {
......
...@@ -107,7 +107,9 @@ static int try_to_fill_dentry(struct dentry *dentry, ...@@ -107,7 +107,9 @@ static int try_to_fill_dentry(struct dentry *dentry,
/* Turn this into a real negative dentry? */ /* Turn this into a real negative dentry? */
if (status == -ENOENT) { if (status == -ENOENT) {
dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT; dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
spin_lock(&dentry->d_lock);
dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
spin_unlock(&dentry->d_lock);
return 1; return 1;
} else if (status) { } else if (status) {
/* Return a negative dentry, but leave it "pending" */ /* Return a negative dentry, but leave it "pending" */
...@@ -132,7 +134,9 @@ static int try_to_fill_dentry(struct dentry *dentry, ...@@ -132,7 +134,9 @@ static int try_to_fill_dentry(struct dentry *dentry,
if (!autofs4_oz_mode(sbi)) if (!autofs4_oz_mode(sbi))
autofs4_update_usage(dentry); autofs4_update_usage(dentry);
spin_lock(&dentry->d_lock);
dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
spin_unlock(&dentry->d_lock);
return 1; return 1;
} }
...@@ -269,8 +273,11 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent ...@@ -269,8 +273,11 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent
*/ */
dentry->d_op = &autofs4_root_dentry_operations; dentry->d_op = &autofs4_root_dentry_operations;
if (!oz_mode) if (!oz_mode) {
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_AUTOFS_PENDING; dentry->d_flags |= DCACHE_AUTOFS_PENDING;
spin_unlock(&dentry->d_lock);
}
dentry->d_fsdata = NULL; dentry->d_fsdata = NULL;
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -155,11 +155,15 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, ...@@ -155,11 +155,15 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent,
if (!IS_ROOT(pd)) { if (!IS_ROOT(pd)) {
/* must have found a connected parent - great */ /* must have found a connected parent - great */
spin_lock(&pd->d_lock);
pd->d_flags &= ~DCACHE_DISCONNECTED; pd->d_flags &= ~DCACHE_DISCONNECTED;
spin_unlock(&pd->d_lock);
noprogress = 0; noprogress = 0;
} else if (pd == sb->s_root) { } else if (pd == sb->s_root) {
printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n"); printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
spin_lock(&pd->d_lock);
pd->d_flags &= ~DCACHE_DISCONNECTED; pd->d_flags &= ~DCACHE_DISCONNECTED;
spin_unlock(&pd->d_lock);
noprogress = 0; noprogress = 0;
} else { } else {
/* we have hit the top of a disconnected path. Try /* we have hit the top of a disconnected path. Try
......
...@@ -180,7 +180,9 @@ nfs_async_unlink(struct dentry *dentry) ...@@ -180,7 +180,9 @@ nfs_async_unlink(struct dentry *dentry)
task->tk_action = nfs_async_unlink_init; task->tk_action = nfs_async_unlink_init;
task->tk_release = nfs_async_unlink_release; task->tk_release = nfs_async_unlink_release;
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_NFSFS_RENAMED; dentry->d_flags |= DCACHE_NFSFS_RENAMED;
spin_unlock(&dentry->d_lock);
data->cred = rpcauth_lookupcred(clnt->cl_auth, 0); data->cred = rpcauth_lookupcred(clnt->cl_auth, 0);
rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL); rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL);
...@@ -210,7 +212,9 @@ nfs_complete_unlink(struct dentry *dentry) ...@@ -210,7 +212,9 @@ nfs_complete_unlink(struct dentry *dentry)
return; return;
data->count++; data->count++;
nfs_copy_dname(dentry, data); nfs_copy_dname(dentry, data);
spin_lock(&dentry->d_lock);
dentry->d_flags &= ~DCACHE_NFSFS_RENAMED; dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
spin_unlock(&dentry->d_lock);
if (data->task.tk_rpcwait == &nfs_delete_queue) if (data->task.tk_rpcwait == &nfs_delete_queue)
rpc_wake_up_task(&data->task); rpc_wake_up_task(&data->task);
nfs_put_unlinkdata(data); nfs_put_unlinkdata(data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment