aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2009-04-03 01:28:28 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-04-03 20:41:18 -0400
commitec6b5d7b5064fde27aee798b81107ea3a830de85 (patch)
treede1571b6773201268796fe5bf3db9bb0f8d23812 /fs/nfsd/nfs4xdr.c
parent14778a133e3be332be77d981552a79260a61ee17 (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.c148
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
1099nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, 1099nfsd4_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
1105static __be32 1206static __be32
@@ -2821,8 +2922,49 @@ static __be32
2821nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, 2922nfsd4_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
2828static __be32 2970static __be32