Commit ef2dc37c authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] (3/4) BKL removal from d_move()

	nfsd_acceptable() calls permission() on a a dentry that is
not guaranteed to stay around (its child is pinned down, but there
is no promises that child won't move and nothing pins dentry itself).
Fixed, cleaned up.
parent d7a2e19f
...@@ -45,27 +45,26 @@ int nfsd_acceptable(void *expv, struct dentry *dentry) ...@@ -45,27 +45,26 @@ int nfsd_acceptable(void *expv, struct dentry *dentry)
struct svc_export *exp = expv; struct svc_export *exp = expv;
int rv; int rv;
struct dentry *tdentry; struct dentry *tdentry;
struct dentry *parent;
if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
return 1; return 1;
dget(dentry); tdentry = dget(dentry);
read_lock(&dparent_lock); while (tdentry != exp->ex_dentry && ! IS_ROOT(tdentry)) {
for (tdentry = dentry;
tdentry != exp->ex_dentry && ! IS_ROOT(tdentry);
(dget(tdentry->d_parent),
dput(tdentry),
tdentry = tdentry->d_parent)
) {
/* make sure parents give x permission to user */ /* make sure parents give x permission to user */
int err; int err;
read_unlock(&dparent_lock);
err = permission(tdentry->d_parent->d_inode, S_IXOTH);
read_lock(&dparent_lock); read_lock(&dparent_lock);
if (err < 0) parent = dget(tdentry->d_parent);
read_unlock(&dparent_lock);
err = permission(parent->d_inode, S_IXOTH);
if (err < 0) {
dput(parent);
break; break;
} }
read_unlock(&dparent_lock); dput(tdentry);
tdentry = parent;
}
if (tdentry != exp->ex_dentry) if (tdentry != exp->ex_dentry)
dprintk("nfsd_acceptable failed at %p %s\n", tdentry, tdentry->d_name.name); dprintk("nfsd_acceptable failed at %p %s\n", tdentry, tdentry->d_name.name);
rv = (tdentry == exp->ex_dentry); rv = (tdentry == exp->ex_dentry);
......
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