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>
This commit is contained in:
committed by
J. Bruce Fields
parent
14778a133e
commit
ec6b5d7b50
@@ -1099,7 +1099,108 @@ static __be32
|
||||
nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
|
||||
struct nfsd4_create_session *sess)
|
||||
{
|
||||
return nfserr_opnotsupp; /* stub */
|
||||
DECODE_HEAD;
|
||||
|
||||
u32 dummy;
|
||||
char *machine_name;
|
||||
int i;
|
||||
int nr_secflavs;
|
||||
|
||||
READ_BUF(16);
|
||||
COPYMEM(&sess->clientid, 8);
|
||||
READ32(sess->seqid);
|
||||
READ32(sess->flags);
|
||||
|
||||
/* Fore channel attrs */
|
||||
READ_BUF(28);
|
||||
READ32(dummy); /* headerpadsz is always 0 */
|
||||
READ32(sess->fore_channel.maxreq_sz);
|
||||
READ32(sess->fore_channel.maxresp_sz);
|
||||
READ32(sess->fore_channel.maxresp_cached);
|
||||
READ32(sess->fore_channel.maxops);
|
||||
READ32(sess->fore_channel.maxreqs);
|
||||
READ32(sess->fore_channel.nr_rdma_attrs);
|
||||
if (sess->fore_channel.nr_rdma_attrs == 1) {
|
||||
READ_BUF(4);
|
||||
READ32(sess->fore_channel.rdma_attrs);
|
||||
} else if (sess->fore_channel.nr_rdma_attrs > 1) {
|
||||
dprintk("Too many fore channel attr bitmaps!\n");
|
||||
goto xdr_error;
|
||||
}
|
||||
|
||||
/* Back channel attrs */
|
||||
READ_BUF(28);
|
||||
READ32(dummy); /* headerpadsz is always 0 */
|
||||
READ32(sess->back_channel.maxreq_sz);
|
||||
READ32(sess->back_channel.maxresp_sz);
|
||||
READ32(sess->back_channel.maxresp_cached);
|
||||
READ32(sess->back_channel.maxops);
|
||||
READ32(sess->back_channel.maxreqs);
|
||||
READ32(sess->back_channel.nr_rdma_attrs);
|
||||
if (sess->back_channel.nr_rdma_attrs == 1) {
|
||||
READ_BUF(4);
|
||||
READ32(sess->back_channel.rdma_attrs);
|
||||
} else if (sess->back_channel.nr_rdma_attrs > 1) {
|
||||
dprintk("Too many back channel attr bitmaps!\n");
|
||||
goto xdr_error;
|
||||
}
|
||||
|
||||
READ_BUF(8);
|
||||
READ32(sess->callback_prog);
|
||||
|
||||
/* callback_sec_params4 */
|
||||
READ32(nr_secflavs);
|
||||
for (i = 0; i < nr_secflavs; ++i) {
|
||||
READ_BUF(4);
|
||||
READ32(dummy);
|
||||
switch (dummy) {
|
||||
case RPC_AUTH_NULL:
|
||||
/* Nothing to read */
|
||||
break;
|
||||
case RPC_AUTH_UNIX:
|
||||
READ_BUF(8);
|
||||
/* stamp */
|
||||
READ32(dummy);
|
||||
|
||||
/* machine name */
|
||||
READ32(dummy);
|
||||
READ_BUF(dummy);
|
||||
SAVEMEM(machine_name, dummy);
|
||||
|
||||
/* uid, gid */
|
||||
READ_BUF(8);
|
||||
READ32(sess->uid);
|
||||
READ32(sess->gid);
|
||||
|
||||
/* more gids */
|
||||
READ_BUF(4);
|
||||
READ32(dummy);
|
||||
READ_BUF(dummy * 4);
|
||||
for (i = 0; i < dummy; ++i)
|
||||
READ32(dummy);
|
||||
break;
|
||||
case RPC_AUTH_GSS:
|
||||
dprintk("RPC_AUTH_GSS callback secflavor "
|
||||
"not supported!\n");
|
||||
READ_BUF(8);
|
||||
/* gcbp_service */
|
||||
READ32(dummy);
|
||||
/* gcbp_handle_from_server */
|
||||
READ32(dummy);
|
||||
READ_BUF(dummy);
|
||||
p += XDR_QUADLEN(dummy);
|
||||
/* gcbp_handle_from_client */
|
||||
READ_BUF(4);
|
||||
READ32(dummy);
|
||||
READ_BUF(dummy);
|
||||
p += XDR_QUADLEN(dummy);
|
||||
break;
|
||||
default:
|
||||
dprintk("Illegal callback secflavor\n");
|
||||
return nfserr_inval;
|
||||
}
|
||||
}
|
||||
DECODE_TAIL;
|
||||
}
|
||||
|
||||
static __be32
|
||||
@@ -2821,8 +2922,49 @@ static __be32
|
||||
nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
|
||||
struct nfsd4_create_session *sess)
|
||||
{
|
||||
/* stub */
|
||||
return nfserr;
|
||||
ENCODE_HEAD;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
RESERVE_SPACE(24);
|
||||
WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
|
||||
WRITE32(sess->seqid);
|
||||
WRITE32(sess->flags);
|
||||
ADJUST_ARGS();
|
||||
|
||||
RESERVE_SPACE(28);
|
||||
WRITE32(0); /* headerpadsz */
|
||||
WRITE32(sess->fore_channel.maxreq_sz);
|
||||
WRITE32(sess->fore_channel.maxresp_sz);
|
||||
WRITE32(sess->fore_channel.maxresp_cached);
|
||||
WRITE32(sess->fore_channel.maxops);
|
||||
WRITE32(sess->fore_channel.maxreqs);
|
||||
WRITE32(sess->fore_channel.nr_rdma_attrs);
|
||||
ADJUST_ARGS();
|
||||
|
||||
if (sess->fore_channel.nr_rdma_attrs) {
|
||||
RESERVE_SPACE(4);
|
||||
WRITE32(sess->fore_channel.rdma_attrs);
|
||||
ADJUST_ARGS();
|
||||
}
|
||||
|
||||
RESERVE_SPACE(28);
|
||||
WRITE32(0); /* headerpadsz */
|
||||
WRITE32(sess->back_channel.maxreq_sz);
|
||||
WRITE32(sess->back_channel.maxresp_sz);
|
||||
WRITE32(sess->back_channel.maxresp_cached);
|
||||
WRITE32(sess->back_channel.maxops);
|
||||
WRITE32(sess->back_channel.maxreqs);
|
||||
WRITE32(sess->back_channel.nr_rdma_attrs);
|
||||
ADJUST_ARGS();
|
||||
|
||||
if (sess->back_channel.nr_rdma_attrs) {
|
||||
RESERVE_SPACE(4);
|
||||
WRITE32(sess->back_channel.rdma_attrs);
|
||||
ADJUST_ARGS();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
Reference in New Issue
Block a user