|
@@ -169,28 +169,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|
/* checking mountpoint crossing is very different when stepping up */
|
|
/* checking mountpoint crossing is very different when stepping up */
|
|
struct svc_export *exp2 = NULL;
|
|
struct svc_export *exp2 = NULL;
|
|
struct dentry *dp;
|
|
struct dentry *dp;
|
|
- struct vfsmount *mnt = mntget(exp->ex_path.mnt);
|
|
|
|
- dentry = dget(dparent);
|
|
|
|
- while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry))
|
|
|
|
|
|
+ struct path path = {.mnt = mntget(exp->ex_path.mnt),
|
|
|
|
+ .dentry = dget(dparent)};
|
|
|
|
+
|
|
|
|
+ while (path.dentry == path.mnt->mnt_root &&
|
|
|
|
+ follow_up(&path.mnt, &path.dentry))
|
|
;
|
|
;
|
|
- dp = dget_parent(dentry);
|
|
|
|
- dput(dentry);
|
|
|
|
- dentry = dp;
|
|
|
|
|
|
+ dp = dget_parent(path.dentry);
|
|
|
|
+ dput(path.dentry);
|
|
|
|
+ path.dentry = dp;
|
|
|
|
|
|
- exp2 = rqst_exp_parent(rqstp, mnt, dentry);
|
|
|
|
|
|
+ exp2 = rqst_exp_parent(rqstp, &path);
|
|
if (PTR_ERR(exp2) == -ENOENT) {
|
|
if (PTR_ERR(exp2) == -ENOENT) {
|
|
- dput(dentry);
|
|
|
|
dentry = dget(dparent);
|
|
dentry = dget(dparent);
|
|
} else if (IS_ERR(exp2)) {
|
|
} else if (IS_ERR(exp2)) {
|
|
host_err = PTR_ERR(exp2);
|
|
host_err = PTR_ERR(exp2);
|
|
- dput(dentry);
|
|
|
|
- mntput(mnt);
|
|
|
|
|
|
+ path_put(&path);
|
|
goto out_nfserr;
|
|
goto out_nfserr;
|
|
} else {
|
|
} else {
|
|
|
|
+ dentry = dget(path.dentry);
|
|
exp_put(exp);
|
|
exp_put(exp);
|
|
exp = exp2;
|
|
exp = exp2;
|
|
}
|
|
}
|
|
- mntput(mnt);
|
|
|
|
|
|
+ path_put(&path);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
fh_lock(fhp);
|
|
fh_lock(fhp);
|