Commit 322eddbd authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] PATCH 5/16: NFSD: BKL removal: add BKL where needed in filehandle lookup

Protect dentry attachement from BKL

The process of attaching a dentry into the dcache
still needs the BKL I think.
When all the other BKL changes in the VFS settle down, I
will revisit this.  But as it is not a very frequent
operation, the BKL wont hurt.

Also add a down/up of i_sem when doing a lookup(".."),
as it is down for all other lookups.
parent 734f5929
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -273,7 +274,9 @@ struct dentry *nfsd_findparent(struct dentry *child) ...@@ -273,7 +274,9 @@ struct dentry *nfsd_findparent(struct dentry *child)
/* I'm going to assume that if the returned dentry is different, then /* I'm going to assume that if the returned dentry is different, then
* it is well connected. But nobody returns different dentrys do they? * it is well connected. But nobody returns different dentrys do they?
*/ */
down(&child->d_inode->i_sem);
pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
up(&child->d_inode->i_sem);
d_drop(tdentry); /* we never want ".." hashed */ d_drop(tdentry); /* we never want ".." hashed */
if (!pdentry && tdentry->d_inode == NULL) { if (!pdentry && tdentry->d_inode == NULL) {
/* File system cannot find ".." ... sad but possible */ /* File system cannot find ".." ... sad but possible */
...@@ -426,6 +429,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne ...@@ -426,6 +429,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne
*/ */
dprintk("nfs_fh: need to look harder for %s/%d\n", sb->s_id, datap[0]); dprintk("nfs_fh: need to look harder for %s/%d\n", sb->s_id, datap[0]);
lock_kernel();
if (!S_ISDIR(result->d_inode->i_mode)) { if (!S_ISDIR(result->d_inode->i_mode)) {
nfsdstats.fh_nocache_nondir++; nfsdstats.fh_nocache_nondir++;
/* need to iget dirino and make sure this inode is in that directory */ /* need to iget dirino and make sure this inode is in that directory */
...@@ -499,6 +503,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne ...@@ -499,6 +503,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne
dput(dentry); dput(dentry);
dput(result); /* this will discard the whole free path, so we can up the semaphore */ dput(result); /* this will discard the whole free path, so we can up the semaphore */
up(&sb->s_nfsd_free_path_sem); up(&sb->s_nfsd_free_path_sem);
unlock_kernel();
goto retry; goto retry;
} }
dput(dentry); dput(dentry);
...@@ -506,6 +511,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne ...@@ -506,6 +511,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne
} }
dput(dentry); dput(dentry);
up(&sb->s_nfsd_free_path_sem); up(&sb->s_nfsd_free_path_sem);
unlock_kernel();
return result; return result;
err_dentry: err_dentry:
...@@ -513,6 +519,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne ...@@ -513,6 +519,7 @@ find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int ne
err_result: err_result:
dput(result); dput(result);
up(&sb->s_nfsd_free_path_sem); up(&sb->s_nfsd_free_path_sem);
unlock_kernel();
err_out: err_out:
if (err == -ESTALE) if (err == -ESTALE)
nfsdstats.fh_stale++; nfsdstats.fh_stale++;
......
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