diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-03 01:28:28 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-03 20:41:18 -0400 |
commit | ec6b5d7b5064fde27aee798b81107ea3a830de85 (patch) | |
tree | de1571b6773201268796fe5bf3db9bb0f8d23812 /fs/nfsd/nfs4xdr.c | |
parent | 14778a133e3be332be77d981552a79260a61ee17 (diff) |
nfsd41: create_session operation
Implement the create_session operation confoming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26
Look up the client id (generated by the server on exchange_id,
given by the client on create_session).
If neither a confirmed or unconfirmed client is found
then the client id is stale
If a confirmed cilent is found (i.e. we already received
create_session for it) then compare the sequence id
to determine if it's a replay or possibly a mis-ordered rpc.
If the seqid is in order, update the confirmed client seqid
and procedd with updating the session parameters.
If an unconfirmed client_id is found then verify the creds
and seqid. If both match move the client id to confirmed state
and proceed with processing the create_session.
Currently, we do not support persistent sessions, and RDMA.
alloc_init_session generates a new sessionid and creates
a session structure.
NFSD_PAGES_PER_SLOT is used for the max response cached calculation, and for
the counting of DRC pages using the hard limits set in struct srv_serv.
A note on NFSD_PAGES_PER_SLOT:
Other patches in this series allow for NFSD_PAGES_PER_SLOT + 1 pages to be
cached in a DRC slot when the response size is less than NFSD_PAGES_PER_SLOT *
PAGE_SIZE but xdr_buf pages are used. e.g. a READDIR operation will encode a
small amount of data in the xdr_buf head, and then the READDIR in the xdr_buf
pages. So, the hard limit calculation use of pages by a session is
underestimated by the number of cached operations using the xdr_buf pages.
Yet another patch caches no pages for the solo sequence operation, or any
compound where cache_this is False. So the hard limit calculation use of
pages by a session is overestimated by the number of these operations in the
cache.
TODO: improve resource pre-allocation and negotiate session
parameters accordingly. Respect and possibly adjust
backchannel attributes.
Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
[nfsd41: remove headerpadsz from channel attributes]
Our client and server only support a headerpadsz of 0.
[nfsd41: use DRC limits in fore channel init]
[nfsd41: do not change CREATE_SESSION back channel attrs]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[use sessionid_lock spin lock]
[nfsd41: use bool inuse for slot state]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfsd41 remove sl_session from alloc_init_session]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[simplify nfsd4_encode_create_session error handling]
[nfsd41: fix comment style in init_forechannel_attrs]
[nfsd41: allocate struct nfsd4_session and slot table in one piece]
[nfsd41: no need to INIT_LIST_HEAD in alloc_init_session just prior to list_add]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 148 |
1 files changed, 145 insertions, 3 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 09415bcf078e..671f9b96429b 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1099,7 +1099,108 @@ static __be32 | |||
1099 | nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, | 1099 | nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, |
1100 | struct nfsd4_create_session *sess) | 1100 | struct nfsd4_create_session *sess) |
1101 | { | 1101 | { |
1102 | return nfserr_opnotsupp; /* stub */ | 1102 | DECODE_HEAD; |
1103 | |||
1104 | u32 dummy; | ||
1105 | char *machine_name; | ||
1106 | int i; | ||
1107 | int nr_secflavs; | ||
1108 | |||
1109 | READ_BUF(16); | ||
1110 | COPYMEM(&sess->clientid, 8); | ||
1111 | READ32(sess->seqid); | ||
1112 | READ32(sess->flags); | ||
1113 | |||
1114 | /* Fore channel attrs */ | ||
1115 | READ_BUF(28); | ||
1116 | READ32(dummy); /* headerpadsz is always 0 */ | ||
1117 | READ32(sess->fore_channel.maxreq_sz); | ||
1118 | READ32(sess->fore_channel.maxresp_sz); | ||
1119 | READ32(sess->fore_channel.maxresp_cached); | ||
1120 | READ32(sess->fore_channel.maxops); | ||
1121 | READ32(sess->fore_channel.maxreqs); | ||
1122 | READ32(sess->fore_channel.nr_rdma_attrs); | ||
1123 | if (sess->fore_channel.nr_rdma_attrs == 1) { | ||
1124 | READ_BUF(4); | ||
1125 | READ32(sess->fore_channel.rdma_attrs); | ||
1126 | } else if (sess->fore_channel.nr_rdma_attrs > 1) { | ||
1127 | dprintk("Too many fore channel attr bitmaps!\n"); | ||
1128 | goto xdr_error; | ||
1129 | } | ||
1130 | |||
1131 | /* Back channel attrs */ | ||
1132 | READ_BUF(28); | ||
1133 | READ32(dummy); /* headerpadsz is always 0 */ | ||
1134 | READ32(sess->back_channel.maxreq_sz); | ||
1135 | READ32(sess->back_channel.maxresp_sz); | ||
1136 | READ32(sess->back_channel.maxresp_cached); | ||
1137 | READ32(sess->back_channel.maxops); | ||
1138 | READ32(sess->back_channel.maxreqs); | ||
1139 | READ32(sess->back_channel.nr_rdma_attrs); | ||
1140 | if (sess->back_channel.nr_rdma_attrs == 1) { | ||
1141 | READ_BUF(4); | ||
1142 | READ32(sess->back_channel.rdma_attrs); | ||
1143 | } else if (sess->back_channel.nr_rdma_attrs > 1) { | ||
1144 | dprintk("Too many back channel attr bitmaps!\n"); | ||
1145 | goto xdr_error; | ||
1146 | } | ||
1147 | |||
1148 | READ_BUF(8); | ||
1149 | READ32(sess->callback_prog); | ||
1150 | |||
1151 | /* callback_sec_params4 */ | ||
1152 | READ32(nr_secflavs); | ||
1153 | for (i = 0; i < nr_secflavs; ++i) { | ||
1154 | READ_BUF(4); | ||
1155 | READ32(dummy); | ||
1156 | switch (dummy) { | ||
1157 | case RPC_AUTH_NULL: | ||
1158 | /* Nothing to read */ | ||
1159 | break; | ||
1160 | case RPC_AUTH_UNIX: | ||
1161 | READ_BUF(8); | ||
1162 | /* stamp */ | ||
1163 | READ32(dummy); | ||
1164 | |||
1165 | /* machine name */ | ||
1166 | READ32(dummy); | ||
1167 | READ_BUF(dummy); | ||
1168 | SAVEMEM(machine_name, dummy); | ||
1169 | |||
1170 | /* uid, gid */ | ||
1171 | READ_BUF(8); | ||
1172 | READ32(sess->uid); | ||
1173 | READ32(sess->gid); | ||
1174 | |||
1175 | /* more gids */ | ||
1176 | READ_BUF(4); | ||
1177 | READ32(dummy); | ||
1178 | READ_BUF(dummy * 4); | ||
1179 | for (i = 0; i < dummy; ++i) | ||
1180 | READ32(dummy); | ||
1181 | break; | ||
1182 | case RPC_AUTH_GSS: | ||
1183 | dprintk("RPC_AUTH_GSS callback secflavor " | ||
1184 | "not supported!\n"); | ||
1185 | READ_BUF(8); | ||
1186 | /* gcbp_service */ | ||
1187 | READ32(dummy); | ||
1188 | /* gcbp_handle_from_server */ | ||
1189 | READ32(dummy); | ||
1190 | READ_BUF(dummy); | ||
1191 | p += XDR_QUADLEN(dummy); | ||
1192 | /* gcbp_handle_from_client */ | ||
1193 | READ_BUF(4); | ||
1194 | READ32(dummy); | ||
1195 | READ_BUF(dummy); | ||
1196 | p += XDR_QUADLEN(dummy); | ||
1197 | break; | ||
1198 | default: | ||
1199 | dprintk("Illegal callback secflavor\n"); | ||
1200 | return nfserr_inval; | ||
1201 | } | ||
1202 | } | ||
1203 | DECODE_TAIL; | ||
1103 | } | 1204 | } |
1104 | 1205 | ||
1105 | static __be32 | 1206 | static __be32 |
@@ -2821,8 +2922,49 @@ static __be32 | |||
2821 | nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, | 2922 | nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, |
2822 | struct nfsd4_create_session *sess) | 2923 | struct nfsd4_create_session *sess) |
2823 | { | 2924 | { |
2824 | /* stub */ | 2925 | ENCODE_HEAD; |
2825 | return nfserr; | 2926 | |
2927 | if (nfserr) | ||
2928 | return nfserr; | ||
2929 | |||
2930 | RESERVE_SPACE(24); | ||
2931 | WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN); | ||
2932 | WRITE32(sess->seqid); | ||
2933 | WRITE32(sess->flags); | ||
2934 | ADJUST_ARGS(); | ||
2935 | |||
2936 | RESERVE_SPACE(28); | ||
2937 | WRITE32(0); /* headerpadsz */ | ||
2938 | WRITE32(sess->fore_channel.maxreq_sz); | ||
2939 | WRITE32(sess->fore_channel.maxresp_sz); | ||
2940 | WRITE32(sess->fore_channel.maxresp_cached); | ||
2941 | WRITE32(sess->fore_channel.maxops); | ||
2942 | WRITE32(sess->fore_channel.maxreqs); | ||
2943 | WRITE32(sess->fore_channel.nr_rdma_attrs); | ||
2944 | ADJUST_ARGS(); | ||
2945 | |||
2946 | if (sess->fore_channel.nr_rdma_attrs) { | ||
2947 | RESERVE_SPACE(4); | ||
2948 | WRITE32(sess->fore_channel.rdma_attrs); | ||
2949 | ADJUST_ARGS(); | ||
2950 | } | ||
2951 | |||
2952 | RESERVE_SPACE(28); | ||
2953 | WRITE32(0); /* headerpadsz */ | ||
2954 | WRITE32(sess->back_channel.maxreq_sz); | ||
2955 | WRITE32(sess->back_channel.maxresp_sz); | ||
2956 | WRITE32(sess->back_channel.maxresp_cached); | ||
2957 | WRITE32(sess->back_channel.maxops); | ||
2958 | WRITE32(sess->back_channel.maxreqs); | ||
2959 | WRITE32(sess->back_channel.nr_rdma_attrs); | ||
2960 | ADJUST_ARGS(); | ||
2961 | |||
2962 | if (sess->back_channel.nr_rdma_attrs) { | ||
2963 | RESERVE_SPACE(4); | ||
2964 | WRITE32(sess->back_channel.rdma_attrs); | ||
2965 | ADJUST_ARGS(); | ||
2966 | } | ||
2967 | return 0; | ||
2826 | } | 2968 | } |
2827 | 2969 | ||
2828 | static __be32 | 2970 | static __be32 |