nfsd41: destroy_session operation
authorBenny Halevy <bhalevy@panasas.com>
Fri, 3 Apr 2009 05:28:38 +0000 (08:28 +0300)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Sat, 4 Apr 2009 00:41:19 +0000 (17:41 -0700)
Implement the destory_session operation confoming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26

[use sessionid_lock spin lock]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
include/linux/nfsd/xdr4.h

index 04a395fb5dce2e2d907ba803f0754bd18b0b211e..9192e5b35f428fc26d1647a599e5a7be51b58686 100644 (file)
@@ -1422,7 +1422,34 @@ nfsd4_destroy_session(struct svc_rqst *r,
                      struct nfsd4_compound_state *cstate,
                      struct nfsd4_destroy_session *sessionid)
 {
-       return -1;      /* stub */
+       struct nfsd4_session *ses;
+       u32 status = nfserr_badsession;
+
+       /* Notes:
+        * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid
+        * - Should we return nfserr_back_chan_busy if waiting for
+        *   callbacks on to-be-destroyed session?
+        * - Do we need to clear any callback info from previous session?
+        */
+
+       dump_sessionid(__func__, &sessionid->sessionid);
+       spin_lock(&sessionid_lock);
+       ses = find_in_sessionid_hashtbl(&sessionid->sessionid);
+       if (!ses) {
+               spin_unlock(&sessionid_lock);
+               goto out;
+       }
+
+       unhash_session(ses);
+       spin_unlock(&sessionid_lock);
+
+       /* wait for callbacks */
+       shutdown_callback_client(ses->se_client);
+       nfsd4_put_session(ses);
+       status = nfs_ok;
+out:
+       dprintk("%s returns %d\n", __func__, ntohl(status));
+       return status;
 }
 
 __be32
index 64bc2150a6fab3958f8bece3f23d697fea532bfb..c6a726d04efd4ea184a2014c61c3711fa2785143 100644 (file)
@@ -1207,7 +1207,11 @@ static __be32
 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
                             struct nfsd4_destroy_session *destroy_session)
 {
-       return nfserr_opnotsupp;        /* stub */
+       DECODE_HEAD;
+       READ_BUF(NFS4_MAX_SESSIONID_LEN);
+       COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+
+       DECODE_TAIL;
 }
 
 static __be32
@@ -2971,7 +2975,6 @@ static __be32
 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
                             struct nfsd4_destroy_session *destroy_session)
 {
-       /* stub */
        return nfserr;
 }
 
index 486188810a600746b5181be1b14430ea46819479..a0a2e8317a3b3c154e92fb239748ba3880b2f775 100644 (file)
@@ -395,7 +395,7 @@ struct nfsd4_sequence {
 };
 
 struct nfsd4_destroy_session {
-       int     foo;    /* stub */
+       struct nfs4_sessionid   sessionid;
 };
 
 struct nfsd4_op {