diff options
-rw-r--r-- | fs/nfsd/export.c | 25 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 23 | ||||
-rw-r--r-- | include/linux/nfsd/export.h | 3 |
3 files changed, 23 insertions, 28 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 84f5e5cb0863..8b1f8efb4690 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1299,24 +1299,19 @@ gss: | |||
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | struct svc_export * | 1301 | struct svc_export * |
1302 | rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, | 1302 | rqst_exp_parent(struct svc_rqst *rqstp, struct path *path) |
1303 | struct dentry *dentry) | ||
1304 | { | 1303 | { |
1305 | struct svc_export *exp; | 1304 | struct dentry *saved = dget(path->dentry); |
1306 | struct path path = {.mnt = mnt, .dentry = dentry}; | 1305 | struct svc_export *exp = rqst_exp_get_by_name(rqstp, path); |
1307 | |||
1308 | dget(dentry); | ||
1309 | exp = rqst_exp_get_by_name(rqstp, &path); | ||
1310 | |||
1311 | while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { | ||
1312 | struct dentry *parent; | ||
1313 | 1306 | ||
1314 | parent = dget_parent(dentry); | 1307 | while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { |
1315 | dput(dentry); | 1308 | struct dentry *parent = dget_parent(path->dentry); |
1316 | dentry = parent; | 1309 | dput(path->dentry); |
1317 | exp = rqst_exp_get_by_name(rqstp, &path); | 1310 | path->dentry = parent; |
1311 | exp = rqst_exp_get_by_name(rqstp, path); | ||
1318 | } | 1312 | } |
1319 | dput(dentry); | 1313 | dput(path->dentry); |
1314 | path->dentry = saved; | ||
1320 | return exp; | 1315 | return exp; |
1321 | } | 1316 | } |
1322 | 1317 | ||
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d84c4eaa526b..9f1ea3127f5d 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -169,28 +169,29 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
169 | /* checking mountpoint crossing is very different when stepping up */ | 169 | /* checking mountpoint crossing is very different when stepping up */ |
170 | struct svc_export *exp2 = NULL; | 170 | struct svc_export *exp2 = NULL; |
171 | struct dentry *dp; | 171 | struct dentry *dp; |
172 | struct vfsmount *mnt = mntget(exp->ex_path.mnt); | 172 | struct path path = {.mnt = mntget(exp->ex_path.mnt), |
173 | dentry = dget(dparent); | 173 | .dentry = dget(dparent)}; |
174 | while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) | 174 | |
175 | while (path.dentry == path.mnt->mnt_root && | ||
176 | follow_up(&path.mnt, &path.dentry)) | ||
175 | ; | 177 | ; |
176 | dp = dget_parent(dentry); | 178 | dp = dget_parent(path.dentry); |
177 | dput(dentry); | 179 | dput(path.dentry); |
178 | dentry = dp; | 180 | path.dentry = dp; |
179 | 181 | ||
180 | exp2 = rqst_exp_parent(rqstp, mnt, dentry); | 182 | exp2 = rqst_exp_parent(rqstp, &path); |
181 | if (PTR_ERR(exp2) == -ENOENT) { | 183 | if (PTR_ERR(exp2) == -ENOENT) { |
182 | dput(dentry); | ||
183 | dentry = dget(dparent); | 184 | dentry = dget(dparent); |
184 | } else if (IS_ERR(exp2)) { | 185 | } else if (IS_ERR(exp2)) { |
185 | host_err = PTR_ERR(exp2); | 186 | host_err = PTR_ERR(exp2); |
186 | dput(dentry); | 187 | path_put(&path); |
187 | mntput(mnt); | ||
188 | goto out_nfserr; | 188 | goto out_nfserr; |
189 | } else { | 189 | } else { |
190 | dentry = dget(path.dentry); | ||
190 | exp_put(exp); | 191 | exp_put(exp); |
191 | exp = exp2; | 192 | exp = exp2; |
192 | } | 193 | } |
193 | mntput(mnt); | 194 | path_put(&path); |
194 | } | 195 | } |
195 | } else { | 196 | } else { |
196 | fh_lock(fhp); | 197 | fh_lock(fhp); |
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index 98f6fd584d53..a6d9ef2bb34a 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h | |||
@@ -127,8 +127,7 @@ void exp_readunlock(void); | |||
127 | struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, | 127 | struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, |
128 | struct path *); | 128 | struct path *); |
129 | struct svc_export * rqst_exp_parent(struct svc_rqst *, | 129 | struct svc_export * rqst_exp_parent(struct svc_rqst *, |
130 | struct vfsmount *mnt, | 130 | struct path *); |
131 | struct dentry *dentry); | ||
132 | int exp_rootfh(struct auth_domain *, | 131 | int exp_rootfh(struct auth_domain *, |
133 | char *path, struct knfsd_fh *, int maxsize); | 132 | char *path, struct knfsd_fh *, int maxsize); |
134 | __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); | 133 | __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); |