aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/export.c')
-rw-r--r--fs/nfsd/export.c78
1 files changed, 32 insertions, 46 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 5839b229cd0e..8b1f8efb4690 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -847,9 +847,8 @@ exp_get_fsid_key(svc_client *clp, int fsid)
847 return exp_find_key(clp, FSID_NUM, fsidv, NULL); 847 return exp_find_key(clp, FSID_NUM, fsidv, NULL);
848} 848}
849 849
850static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt, 850static svc_export *exp_get_by_name(svc_client *clp, const struct path *path,
851 struct dentry *dentry, 851 struct cache_req *reqp)
852 struct cache_req *reqp)
853{ 852{
854 struct svc_export *exp, key; 853 struct svc_export *exp, key;
855 int err; 854 int err;
@@ -858,8 +857,7 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
858 return ERR_PTR(-ENOENT); 857 return ERR_PTR(-ENOENT);
859 858
860 key.ex_client = clp; 859 key.ex_client = clp;
861 key.ex_path.mnt = mnt; 860 key.ex_path = *path;
862 key.ex_path.dentry = dentry;
863 861
864 exp = svc_export_lookup(&key); 862 exp = svc_export_lookup(&key);
865 if (exp == NULL) 863 if (exp == NULL)
@@ -873,24 +871,19 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
873/* 871/*
874 * Find the export entry for a given dentry. 872 * Find the export entry for a given dentry.
875 */ 873 */
876static struct svc_export *exp_parent(svc_client *clp, struct vfsmount *mnt, 874static struct svc_export *exp_parent(svc_client *clp, struct path *path)
877 struct dentry *dentry,
878 struct cache_req *reqp)
879{ 875{
880 svc_export *exp; 876 struct dentry *saved = dget(path->dentry);
881 877 svc_export *exp = exp_get_by_name(clp, path, NULL);
882 dget(dentry); 878
883 exp = exp_get_by_name(clp, mnt, dentry, reqp); 879 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
884 880 struct dentry *parent = dget_parent(path->dentry);
885 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { 881 dput(path->dentry);
886 struct dentry *parent; 882 path->dentry = parent;
887 883 exp = exp_get_by_name(clp, path, NULL);
888 parent = dget_parent(dentry);
889 dput(dentry);
890 dentry = parent;
891 exp = exp_get_by_name(clp, mnt, dentry, reqp);
892 } 884 }
893 dput(dentry); 885 dput(path->dentry);
886 path->dentry = saved;
894 return exp; 887 return exp;
895} 888}
896 889
@@ -1018,7 +1011,7 @@ exp_export(struct nfsctl_export *nxp)
1018 goto out_put_clp; 1011 goto out_put_clp;
1019 err = -EINVAL; 1012 err = -EINVAL;
1020 1013
1021 exp = exp_get_by_name(clp, path.mnt, path.dentry, NULL); 1014 exp = exp_get_by_name(clp, &path, NULL);
1022 1015
1023 memset(&new, 0, sizeof(new)); 1016 memset(&new, 0, sizeof(new));
1024 1017
@@ -1135,7 +1128,7 @@ exp_unexport(struct nfsctl_export *nxp)
1135 goto out_domain; 1128 goto out_domain;
1136 1129
1137 err = -EINVAL; 1130 err = -EINVAL;
1138 exp = exp_get_by_name(dom, path.mnt, path.dentry, NULL); 1131 exp = exp_get_by_name(dom, &path, NULL);
1139 path_put(&path); 1132 path_put(&path);
1140 if (IS_ERR(exp)) 1133 if (IS_ERR(exp))
1141 goto out_domain; 1134 goto out_domain;
@@ -1177,7 +1170,7 @@ exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize)
1177 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", 1170 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
1178 name, path.dentry, clp->name, 1171 name, path.dentry, clp->name,
1179 inode->i_sb->s_id, inode->i_ino); 1172 inode->i_sb->s_id, inode->i_ino);
1180 exp = exp_parent(clp, path.mnt, path.dentry, NULL); 1173 exp = exp_parent(clp, &path);
1181 if (IS_ERR(exp)) { 1174 if (IS_ERR(exp)) {
1182 err = PTR_ERR(exp); 1175 err = PTR_ERR(exp);
1183 goto out; 1176 goto out;
@@ -1207,7 +1200,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
1207 if (IS_ERR(ek)) 1200 if (IS_ERR(ek))
1208 return ERR_CAST(ek); 1201 return ERR_CAST(ek);
1209 1202
1210 exp = exp_get_by_name(clp, ek->ek_path.mnt, ek->ek_path.dentry, reqp); 1203 exp = exp_get_by_name(clp, &ek->ek_path, reqp);
1211 cache_put(&ek->h, &svc_expkey_cache); 1204 cache_put(&ek->h, &svc_expkey_cache);
1212 1205
1213 if (IS_ERR(exp)) 1206 if (IS_ERR(exp))
@@ -1247,8 +1240,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
1247 * use exp_get_by_name() or exp_find(). 1240 * use exp_get_by_name() or exp_find().
1248 */ 1241 */
1249struct svc_export * 1242struct svc_export *
1250rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt, 1243rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
1251 struct dentry *dentry)
1252{ 1244{
1253 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 1245 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
1254 1246
@@ -1256,8 +1248,7 @@ rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt,
1256 goto gss; 1248 goto gss;
1257 1249
1258 /* First try the auth_unix client: */ 1250 /* First try the auth_unix client: */
1259 exp = exp_get_by_name(rqstp->rq_client, mnt, dentry, 1251 exp = exp_get_by_name(rqstp->rq_client, path, &rqstp->rq_chandle);
1260 &rqstp->rq_chandle);
1261 if (PTR_ERR(exp) == -ENOENT) 1252 if (PTR_ERR(exp) == -ENOENT)
1262 goto gss; 1253 goto gss;
1263 if (IS_ERR(exp)) 1254 if (IS_ERR(exp))
@@ -1269,8 +1260,7 @@ gss:
1269 /* Otherwise, try falling back on gss client */ 1260 /* Otherwise, try falling back on gss client */
1270 if (rqstp->rq_gssclient == NULL) 1261 if (rqstp->rq_gssclient == NULL)
1271 return exp; 1262 return exp;
1272 gssexp = exp_get_by_name(rqstp->rq_gssclient, mnt, dentry, 1263 gssexp = exp_get_by_name(rqstp->rq_gssclient, path, &rqstp->rq_chandle);
1273 &rqstp->rq_chandle);
1274 if (PTR_ERR(gssexp) == -ENOENT) 1264 if (PTR_ERR(gssexp) == -ENOENT)
1275 return exp; 1265 return exp;
1276 if (!IS_ERR(exp)) 1266 if (!IS_ERR(exp))
@@ -1309,23 +1299,19 @@ gss:
1309} 1299}
1310 1300
1311struct svc_export * 1301struct svc_export *
1312rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, 1302rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
1313 struct dentry *dentry)
1314{ 1303{
1315 struct svc_export *exp; 1304 struct dentry *saved = dget(path->dentry);
1316 1305 struct svc_export *exp = rqst_exp_get_by_name(rqstp, path);
1317 dget(dentry); 1306
1318 exp = rqst_exp_get_by_name(rqstp, mnt, dentry); 1307 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
1319 1308 struct dentry *parent = dget_parent(path->dentry);
1320 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(dentry)) { 1309 dput(path->dentry);
1321 struct dentry *parent; 1310 path->dentry = parent;
1322 1311 exp = rqst_exp_get_by_name(rqstp, path);
1323 parent = dget_parent(dentry);
1324 dput(dentry);
1325 dentry = parent;
1326 exp = rqst_exp_get_by_name(rqstp, mnt, dentry);
1327 } 1312 }
1328 dput(dentry); 1313 dput(path->dentry);
1314 path->dentry = saved;
1329 return exp; 1315 return exp;
1330} 1316}
1331 1317