diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2003-03-26 18:57:29 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-26 18:57:29 -0800 |
| commit | c2dfcb95e30c9c9f3f4681ade0239cd6c3197736 (patch) | |
| tree | e203e9ff910ab8725f38ea346b077fadb579e520 | |
| parent | 3172a066f8609eea6ea36193967949da07ffa173 (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.c | 12 |
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; } |
