if (isdotent(name, len)) {
if (len==1)
dentry = dget(dparent);
- else { /* must be ".." */
+ else if (dparent != exp->ex_dentry)
+ dentry = dget(dparent->d_parent);
+ else if (!EX_CROSSMNT(exp))
+ dentry = dget(dparent); /* .. == . just like at / */
+ else {
/* checking mountpoint crossing is very different when stepping up */
- if (dparent == exp->ex_dentry) {
- if (!EX_CROSSMNT(exp))
- dentry = dget(dparent); /* .. == . just like at / */
- else
- {
- struct svc_export *exp2 = NULL;
- struct dentry *dp;
- struct vfsmount *mnt = mntget(exp->ex_mnt);
- dentry = dget(dparent);
- while(follow_up(&mnt, &dentry))
- ;
- dp = dget(dentry->d_parent);
- dput(dentry);
- dentry = dp;
- for ( ; exp2 == NULL && dp->d_parent != dp;
- dp=dp->d_parent)
- exp2 = exp_get_by_name(exp->ex_client, mnt, dp);
- if (exp2==NULL) {
- dput(dentry);
- dentry = dget(dparent);
- } else {
- exp = exp2;
- }
- mntput(mnt);
- }
- } else
- dentry = dget(dparent->d_parent);
+ struct svc_export *exp2 = NULL;
+ struct dentry *dp;
+ struct vfsmount *mnt = mntget(exp->ex_mnt);
+ dentry = dget(dparent);
+ while(follow_up(&mnt, &dentry))
+ ;
+ dp = dget(dentry->d_parent);
+ dput(dentry);
+ dentry = dp;
+ for ( ; !exp2 && dp->d_parent != dp; dp=dp->d_parent)
+ exp2 = exp_get_by_name(exp->ex_client, mnt, dp);
+ if (!exp2) {
+ dput(dentry);
+ dentry = dget(dparent);
+ } else {
+ exp = exp2;
+ }
+ mntput(mnt);
}
} else {
fh_lock(fhp);