diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-03 01:28:05 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-03 20:41:15 -0400 |
commit | a1bcecd29cdf1670df6908a620add4211c0abb7a (patch) | |
tree | a4323b21675db5a47a45f5d292fef468b9786007 /fs | |
parent | 0733d21338747483985a5964e852af160d88e429 (diff) |
nfsd41: match clientid establishment method
We need to distinguish between client names provided by NFSv4.0 clients
SETCLIENTID and those provided by NFSv4.1 via EXCHANGE_ID when looking
up the clientid by string.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Andy Adamson <andros@netapp.com>
[nfsd41: use boolean values for use_exchange_id argument]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfsd41: simplify match_clientid_establishment logic]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4recover.c | 3 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 42 |
2 files changed, 33 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b11cf8d34280..3444c0052a87 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -344,7 +344,8 @@ purge_old(struct dentry *parent, struct dentry *child) | |||
344 | { | 344 | { |
345 | int status; | 345 | int status; |
346 | 346 | ||
347 | if (nfs4_has_reclaimed_state(child->d_name.name)) | 347 | /* note: we currently use this path only for minorversion 0 */ |
348 | if (nfs4_has_reclaimed_state(child->d_name.name, false)) | ||
348 | return 0; | 349 | return 0; |
349 | 350 | ||
350 | status = nfsd4_clear_clid_dir(parent, child); | 351 | status = nfsd4_clear_clid_dir(parent, child); |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4f963e902972..dfc6d946cdfe 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -715,25 +715,45 @@ find_unconfirmed_client(clientid_t *clid) | |||
715 | return NULL; | 715 | return NULL; |
716 | } | 716 | } |
717 | 717 | ||
718 | /* | ||
719 | * Return 1 iff clp's clientid establishment method matches the use_exchange_id | ||
720 | * parameter. Matching is based on the fact the at least one of the | ||
721 | * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1 | ||
722 | * | ||
723 | * FIXME: we need to unify the clientid namespaces for nfsv4.x | ||
724 | * and correctly deal with client upgrade/downgrade in EXCHANGE_ID | ||
725 | * and SET_CLIENTID{,_CONFIRM} | ||
726 | */ | ||
727 | static inline int | ||
728 | match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id) | ||
729 | { | ||
730 | bool has_exchange_flags = (clp->cl_exchange_flags != 0); | ||
731 | return use_exchange_id == has_exchange_flags; | ||
732 | } | ||
733 | |||
718 | static struct nfs4_client * | 734 | static struct nfs4_client * |
719 | find_confirmed_client_by_str(const char *dname, unsigned int hashval) | 735 | find_confirmed_client_by_str(const char *dname, unsigned int hashval, |
736 | bool use_exchange_id) | ||
720 | { | 737 | { |
721 | struct nfs4_client *clp; | 738 | struct nfs4_client *clp; |
722 | 739 | ||
723 | list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { | 740 | list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { |
724 | if (same_name(clp->cl_recdir, dname)) | 741 | if (same_name(clp->cl_recdir, dname) && |
742 | match_clientid_establishment(clp, use_exchange_id)) | ||
725 | return clp; | 743 | return clp; |
726 | } | 744 | } |
727 | return NULL; | 745 | return NULL; |
728 | } | 746 | } |
729 | 747 | ||
730 | static struct nfs4_client * | 748 | static struct nfs4_client * |
731 | find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) | 749 | find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, |
750 | bool use_exchange_id) | ||
732 | { | 751 | { |
733 | struct nfs4_client *clp; | 752 | struct nfs4_client *clp; |
734 | 753 | ||
735 | list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { | 754 | list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { |
736 | if (same_name(clp->cl_recdir, dname)) | 755 | if (same_name(clp->cl_recdir, dname) && |
756 | match_clientid_establishment(clp, use_exchange_id)) | ||
737 | return clp; | 757 | return clp; |
738 | } | 758 | } |
739 | return NULL; | 759 | return NULL; |
@@ -890,7 +910,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
890 | nfs4_lock_state(); | 910 | nfs4_lock_state(); |
891 | status = nfs_ok; | 911 | status = nfs_ok; |
892 | 912 | ||
893 | conf = find_confirmed_client_by_str(dname, strhashval); | 913 | conf = find_confirmed_client_by_str(dname, strhashval, true); |
894 | if (conf) { | 914 | if (conf) { |
895 | if (!same_verf(&verf, &conf->cl_verifier)) { | 915 | if (!same_verf(&verf, &conf->cl_verifier)) { |
896 | /* 18.35.4 case 8 */ | 916 | /* 18.35.4 case 8 */ |
@@ -938,7 +958,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
938 | } | 958 | } |
939 | } | 959 | } |
940 | 960 | ||
941 | unconf = find_unconfirmed_client_by_str(dname, strhashval); | 961 | unconf = find_unconfirmed_client_by_str(dname, strhashval, true); |
942 | if (unconf) { | 962 | if (unconf) { |
943 | /* | 963 | /* |
944 | * Possible retry or client restart. Per 18.35.4 case 4, | 964 | * Possible retry or client restart. Per 18.35.4 case 4, |
@@ -1035,7 +1055,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
1035 | strhashval = clientstr_hashval(dname); | 1055 | strhashval = clientstr_hashval(dname); |
1036 | 1056 | ||
1037 | nfs4_lock_state(); | 1057 | nfs4_lock_state(); |
1038 | conf = find_confirmed_client_by_str(dname, strhashval); | 1058 | conf = find_confirmed_client_by_str(dname, strhashval, false); |
1039 | if (conf) { | 1059 | if (conf) { |
1040 | /* RFC 3530 14.2.33 CASE 0: */ | 1060 | /* RFC 3530 14.2.33 CASE 0: */ |
1041 | status = nfserr_clid_inuse; | 1061 | status = nfserr_clid_inuse; |
@@ -1050,7 +1070,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
1050 | * has a description of SETCLIENTID request processing consisting | 1070 | * has a description of SETCLIENTID request processing consisting |
1051 | * of 5 bullet points, labeled as CASE0 - CASE4 below. | 1071 | * of 5 bullet points, labeled as CASE0 - CASE4 below. |
1052 | */ | 1072 | */ |
1053 | unconf = find_unconfirmed_client_by_str(dname, strhashval); | 1073 | unconf = find_unconfirmed_client_by_str(dname, strhashval, false); |
1054 | status = nfserr_resource; | 1074 | status = nfserr_resource; |
1055 | if (!conf) { | 1075 | if (!conf) { |
1056 | /* | 1076 | /* |
@@ -1205,7 +1225,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
1205 | unsigned int hash = | 1225 | unsigned int hash = |
1206 | clientstr_hashval(unconf->cl_recdir); | 1226 | clientstr_hashval(unconf->cl_recdir); |
1207 | conf = find_confirmed_client_by_str(unconf->cl_recdir, | 1227 | conf = find_confirmed_client_by_str(unconf->cl_recdir, |
1208 | hash); | 1228 | hash, false); |
1209 | if (conf) { | 1229 | if (conf) { |
1210 | nfsd4_remove_clid_dir(conf); | 1230 | nfsd4_remove_clid_dir(conf); |
1211 | expire_client(conf); | 1231 | expire_client(conf); |
@@ -3326,12 +3346,12 @@ alloc_reclaim(void) | |||
3326 | } | 3346 | } |
3327 | 3347 | ||
3328 | int | 3348 | int |
3329 | nfs4_has_reclaimed_state(const char *name) | 3349 | nfs4_has_reclaimed_state(const char *name, bool use_exchange_id) |
3330 | { | 3350 | { |
3331 | unsigned int strhashval = clientstr_hashval(name); | 3351 | unsigned int strhashval = clientstr_hashval(name); |
3332 | struct nfs4_client *clp; | 3352 | struct nfs4_client *clp; |
3333 | 3353 | ||
3334 | clp = find_confirmed_client_by_str(name, strhashval); | 3354 | clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id); |
3335 | return clp ? 1 : 0; | 3355 | return clp ? 1 : 0; |
3336 | } | 3356 | } |
3337 | 3357 | ||