summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2003-03-26 18:57:29 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-03-26 18:57:29 -0800
commitc2dfcb95e30c9c9f3f4681ade0239cd6c3197736 (patch)
treee203e9ff910ab8725f38ea346b077fadb579e520
parent3172a066f8609eea6ea36193967949da07ffa173 (diff)
[PATCH] kNFSd: Be more careful with readlock in exp_parent
We currently hold a read_lock of dparent_lock while calling exp_get_by_name on several ancestors of a given dentry. However exp_get_by_name can malloc(GFP_KERNEL), so that isn't a good idea. Now we only claim the lock while actually stepping up the parent chain. This addresses bug 29 @ bugme.osdl.org
-rw-r--r--fs/nfsd/export.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 4ea38a35403e..835d996497cb 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -496,13 +496,19 @@ exp_parent(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
{
svc_export *exp;
- read_lock(&dparent_lock);
+ dget(dentry);
exp = exp_get_by_name(clp, mnt, dentry, reqp);
+
while (exp == NULL && dentry != dentry->d_parent) {
- dentry = dentry->d_parent;
+ struct dentry *parent;
+ read_lock(&dparent_lock);
+ parent = dget(dentry->d_parent);
+ dput(dentry);
+ dentry = parent;
+ read_unlock(&dparent_lock);
exp = exp_get_by_name(clp, mnt, dentry, reqp);
}
- read_unlock(&dparent_lock);
+ dput(dentry);
return exp;
}