diff options
| -rw-r--r-- | fs/nfsd/export.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 6453669dcef7..688264b55a3a 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
| @@ -785,8 +785,8 @@ exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type, | |||
| 785 | } | 785 | } |
| 786 | 786 | ||
| 787 | 787 | ||
| 788 | static svc_export *exp_get_by_name(svc_client *clp, const struct path *path, | 788 | static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp, |
| 789 | struct cache_req *reqp) | 789 | const struct path *path, struct cache_req *reqp) |
| 790 | { | 790 | { |
| 791 | struct svc_export *exp, key; | 791 | struct svc_export *exp, key; |
| 792 | int err; | 792 | int err; |
| @@ -796,12 +796,12 @@ static svc_export *exp_get_by_name(svc_client *clp, const struct path *path, | |||
| 796 | 796 | ||
| 797 | key.ex_client = clp; | 797 | key.ex_client = clp; |
| 798 | key.ex_path = *path; | 798 | key.ex_path = *path; |
| 799 | key.cd = &svc_export_cache; | 799 | key.cd = cd; |
| 800 | 800 | ||
| 801 | exp = svc_export_lookup(&key); | 801 | exp = svc_export_lookup(&key); |
| 802 | if (exp == NULL) | 802 | if (exp == NULL) |
| 803 | return ERR_PTR(-ENOMEM); | 803 | return ERR_PTR(-ENOMEM); |
| 804 | err = cache_check(&svc_export_cache, &exp->h, reqp); | 804 | err = cache_check(cd, &exp->h, reqp); |
| 805 | if (err) | 805 | if (err) |
| 806 | return ERR_PTR(err); | 806 | return ERR_PTR(err); |
| 807 | return exp; | 807 | return exp; |
| @@ -810,16 +810,17 @@ static svc_export *exp_get_by_name(svc_client *clp, const struct path *path, | |||
| 810 | /* | 810 | /* |
| 811 | * Find the export entry for a given dentry. | 811 | * Find the export entry for a given dentry. |
| 812 | */ | 812 | */ |
| 813 | static struct svc_export *exp_parent(svc_client *clp, struct path *path) | 813 | static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp, |
| 814 | struct path *path) | ||
| 814 | { | 815 | { |
| 815 | struct dentry *saved = dget(path->dentry); | 816 | struct dentry *saved = dget(path->dentry); |
| 816 | svc_export *exp = exp_get_by_name(clp, path, NULL); | 817 | svc_export *exp = exp_get_by_name(cd, clp, path, NULL); |
| 817 | 818 | ||
| 818 | while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { | 819 | while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { |
| 819 | struct dentry *parent = dget_parent(path->dentry); | 820 | struct dentry *parent = dget_parent(path->dentry); |
| 820 | dput(path->dentry); | 821 | dput(path->dentry); |
| 821 | path->dentry = parent; | 822 | path->dentry = parent; |
| 822 | exp = exp_get_by_name(clp, path, NULL); | 823 | exp = exp_get_by_name(cd, clp, path, NULL); |
| 823 | } | 824 | } |
| 824 | dput(path->dentry); | 825 | dput(path->dentry); |
| 825 | path->dentry = saved; | 826 | path->dentry = saved; |
| @@ -834,13 +835,15 @@ static struct svc_export *exp_parent(svc_client *clp, struct path *path) | |||
| 834 | * since its harder to fool a kernel module than a user space program. | 835 | * since its harder to fool a kernel module than a user space program. |
| 835 | */ | 836 | */ |
| 836 | int | 837 | int |
| 837 | exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize) | 838 | exp_rootfh(svc_client *clp, char *name, |
| 839 | struct knfsd_fh *f, int maxsize) | ||
| 838 | { | 840 | { |
| 839 | struct svc_export *exp; | 841 | struct svc_export *exp; |
| 840 | struct path path; | 842 | struct path path; |
| 841 | struct inode *inode; | 843 | struct inode *inode; |
| 842 | struct svc_fh fh; | 844 | struct svc_fh fh; |
| 843 | int err; | 845 | int err; |
| 846 | struct cache_detail *cd = &svc_export_cache; | ||
| 844 | 847 | ||
| 845 | err = -EPERM; | 848 | err = -EPERM; |
| 846 | /* NB: we probably ought to check that it's NUL-terminated */ | 849 | /* NB: we probably ought to check that it's NUL-terminated */ |
| @@ -853,7 +856,7 @@ exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize) | |||
| 853 | dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", | 856 | dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", |
| 854 | name, path.dentry, clp->name, | 857 | name, path.dentry, clp->name, |
| 855 | inode->i_sb->s_id, inode->i_ino); | 858 | inode->i_sb->s_id, inode->i_ino); |
| 856 | exp = exp_parent(clp, &path); | 859 | exp = exp_parent(cd, clp, &path); |
| 857 | if (IS_ERR(exp)) { | 860 | if (IS_ERR(exp)) { |
| 858 | err = PTR_ERR(exp); | 861 | err = PTR_ERR(exp); |
| 859 | goto out; | 862 | goto out; |
| @@ -875,7 +878,8 @@ out: | |||
| 875 | return err; | 878 | return err; |
| 876 | } | 879 | } |
| 877 | 880 | ||
| 878 | static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type, | 881 | static struct svc_export *exp_find(struct cache_detail *cd, |
| 882 | struct auth_domain *clp, int fsid_type, | ||
| 879 | u32 *fsidv, struct cache_req *reqp) | 883 | u32 *fsidv, struct cache_req *reqp) |
| 880 | { | 884 | { |
| 881 | struct svc_export *exp; | 885 | struct svc_export *exp; |
| @@ -883,7 +887,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type, | |||
| 883 | if (IS_ERR(ek)) | 887 | if (IS_ERR(ek)) |
| 884 | return ERR_CAST(ek); | 888 | return ERR_CAST(ek); |
| 885 | 889 | ||
| 886 | exp = exp_get_by_name(clp, &ek->ek_path, reqp); | 890 | exp = exp_get_by_name(cd, clp, &ek->ek_path, reqp); |
| 887 | cache_put(&ek->h, &svc_expkey_cache); | 891 | cache_put(&ek->h, &svc_expkey_cache); |
| 888 | 892 | ||
| 889 | if (IS_ERR(exp)) | 893 | if (IS_ERR(exp)) |
| @@ -926,12 +930,13 @@ struct svc_export * | |||
| 926 | rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) | 930 | rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) |
| 927 | { | 931 | { |
| 928 | struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); | 932 | struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); |
| 933 | struct cache_detail *cd = &svc_export_cache; | ||
| 929 | 934 | ||
| 930 | if (rqstp->rq_client == NULL) | 935 | if (rqstp->rq_client == NULL) |
| 931 | goto gss; | 936 | goto gss; |
| 932 | 937 | ||
| 933 | /* First try the auth_unix client: */ | 938 | /* First try the auth_unix client: */ |
| 934 | exp = exp_get_by_name(rqstp->rq_client, path, &rqstp->rq_chandle); | 939 | exp = exp_get_by_name(cd, rqstp->rq_client, path, &rqstp->rq_chandle); |
| 935 | if (PTR_ERR(exp) == -ENOENT) | 940 | if (PTR_ERR(exp) == -ENOENT) |
| 936 | goto gss; | 941 | goto gss; |
| 937 | if (IS_ERR(exp)) | 942 | if (IS_ERR(exp)) |
| @@ -943,7 +948,7 @@ gss: | |||
| 943 | /* Otherwise, try falling back on gss client */ | 948 | /* Otherwise, try falling back on gss client */ |
| 944 | if (rqstp->rq_gssclient == NULL) | 949 | if (rqstp->rq_gssclient == NULL) |
| 945 | return exp; | 950 | return exp; |
| 946 | gssexp = exp_get_by_name(rqstp->rq_gssclient, path, &rqstp->rq_chandle); | 951 | gssexp = exp_get_by_name(cd, rqstp->rq_gssclient, path, &rqstp->rq_chandle); |
| 947 | if (PTR_ERR(gssexp) == -ENOENT) | 952 | if (PTR_ERR(gssexp) == -ENOENT) |
| 948 | return exp; | 953 | return exp; |
| 949 | if (!IS_ERR(exp)) | 954 | if (!IS_ERR(exp)) |
| @@ -955,12 +960,14 @@ struct svc_export * | |||
| 955 | rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) | 960 | rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) |
| 956 | { | 961 | { |
| 957 | struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); | 962 | struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); |
| 963 | struct cache_detail *cd = &svc_export_cache; | ||
| 958 | 964 | ||
| 959 | if (rqstp->rq_client == NULL) | 965 | if (rqstp->rq_client == NULL) |
| 960 | goto gss; | 966 | goto gss; |
| 961 | 967 | ||
| 962 | /* First try the auth_unix client: */ | 968 | /* First try the auth_unix client: */ |
| 963 | exp = exp_find(rqstp->rq_client, fsid_type, fsidv, &rqstp->rq_chandle); | 969 | exp = exp_find(cd, rqstp->rq_client, fsid_type, |
| 970 | fsidv, &rqstp->rq_chandle); | ||
| 964 | if (PTR_ERR(exp) == -ENOENT) | 971 | if (PTR_ERR(exp) == -ENOENT) |
| 965 | goto gss; | 972 | goto gss; |
| 966 | if (IS_ERR(exp)) | 973 | if (IS_ERR(exp)) |
| @@ -972,7 +979,7 @@ gss: | |||
| 972 | /* Otherwise, try falling back on gss client */ | 979 | /* Otherwise, try falling back on gss client */ |
| 973 | if (rqstp->rq_gssclient == NULL) | 980 | if (rqstp->rq_gssclient == NULL) |
| 974 | return exp; | 981 | return exp; |
| 975 | gssexp = exp_find(rqstp->rq_gssclient, fsid_type, fsidv, | 982 | gssexp = exp_find(cd, rqstp->rq_gssclient, fsid_type, fsidv, |
| 976 | &rqstp->rq_chandle); | 983 | &rqstp->rq_chandle); |
| 977 | if (PTR_ERR(gssexp) == -ENOENT) | 984 | if (PTR_ERR(gssexp) == -ENOENT) |
| 978 | return exp; | 985 | return exp; |
