nfs-ganesha 1.4

nfs41_op_sequence.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public License
00011  * as published by the Free Software Foundation; either version 3 of
00012  * the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00022  * 02110-1301 USA
00023  *
00024  * ---------------------------------------
00025  */
00026 
00035 #ifdef HAVE_CONFIG_H
00036 #include "config.h"
00037 #endif
00038 
00039 #ifdef _SOLARIS
00040 #include "solaris_port.h"
00041 #endif
00042 
00043 #include "sal_functions.h"
00044 
00062 int nfs41_op_sequence(struct nfs_argop4 *op,
00063                       compound_data_t * data, struct nfs_resop4 *resp)
00064 {
00065 #define arg_SEQUENCE4  op->nfs_argop4_u.opsequence
00066 #define res_SEQUENCE4  resp->nfs_resop4_u.opsequence
00067 
00068   nfs41_session_t *psession;
00069 
00070   resp->resop = NFS4_OP_SEQUENCE;
00071   res_SEQUENCE4.sr_status = NFS4_OK;
00072 
00073   /* OP_SEQUENCE is always the first operation of the request */
00074   if(data->oppos != 0)
00075     {
00076       res_SEQUENCE4.sr_status = NFS4ERR_SEQUENCE_POS;
00077       return res_SEQUENCE4.sr_status;
00078     }
00079 
00080   if(!nfs41_Session_Get_Pointer(arg_SEQUENCE4.sa_sessionid, &psession))
00081     {
00082       res_SEQUENCE4.sr_status = NFS4ERR_BADSESSION;
00083       return res_SEQUENCE4.sr_status;
00084     }
00085 
00088   /* Check if lease is expired and reserve it */
00089   P(psession->pclientid_record->cid_mutex);
00090 
00091   if(!reserve_lease(psession->pclientid_record))
00092     {
00093       V(psession->pclientid_record->cid_mutex);
00094 
00095       dec_client_id_ref(psession->pclientid_record);
00096 
00097       if(isDebug(COMPONENT_SESSIONS))
00098         LogDebug(COMPONENT_SESSIONS,
00099                  "SEQUENCE returning NFS4ERR_EXPIRED");
00100       else
00101         LogDebug(COMPONENT_CLIENTID,
00102                  "SEQUENCE returning NFS4ERR_EXPIRED");
00103 
00104       res_SEQUENCE4.sr_status = NFS4ERR_EXPIRED;
00105       return res_SEQUENCE4.sr_status;
00106     }
00107 
00108   data->preserved_clientid = psession->pclientid_record;
00109 
00110   V(psession->pclientid_record->cid_mutex);
00111 
00112   /* Check is slot is compliant with ca_maxrequests */
00113   if(arg_SEQUENCE4.sa_slotid >= psession->fore_channel_attrs.ca_maxrequests)
00114     {
00115       res_SEQUENCE4.sr_status = NFS4ERR_BADSLOT;
00116       return res_SEQUENCE4.sr_status;
00117     }
00118 
00119   /* By default, no DRC replay */
00120   data->use_drc = FALSE;
00121 
00122   P(psession->slots[arg_SEQUENCE4.sa_slotid].lock);
00123   if(psession->slots[arg_SEQUENCE4.sa_slotid].sequence + 1 != arg_SEQUENCE4.sa_sequenceid)
00124     {
00125       if(psession->slots[arg_SEQUENCE4.sa_slotid].sequence == arg_SEQUENCE4.sa_sequenceid)
00126         {
00127           if(psession->slots[arg_SEQUENCE4.sa_slotid].cache_used == TRUE)
00128             {
00129               /* Replay operation through the DRC */
00130               data->use_drc = TRUE;
00131               data->pcached_res = &psession->slots[arg_SEQUENCE4.sa_slotid].cached_result;
00132 
00133               LogFullDebug(COMPONENT_SESSIONS,
00134                            "Use sesson slot %"PRIu32"=%p for DRC",
00135                            arg_SEQUENCE4.sa_slotid, data->pcached_res);
00136 
00137               res_SEQUENCE4.sr_status = NFS4_OK;
00138               return res_SEQUENCE4.sr_status;
00139             }
00140           else
00141             {
00142               /* Illegal replay */
00143               res_SEQUENCE4.sr_status = NFS4ERR_RETRY_UNCACHED_REP;
00144               return res_SEQUENCE4.sr_status;
00145             }
00146         }
00147       V(psession->slots[arg_SEQUENCE4.sa_slotid].lock);
00148       res_SEQUENCE4.sr_status = NFS4ERR_SEQ_MISORDERED;
00149       return res_SEQUENCE4.sr_status;
00150     }
00151 
00152   /* Keep memory of the session in the COMPOUND's data */
00153   data->psession = psession;
00154 
00155   /* Update the sequence id within the slot */
00156   psession->slots[arg_SEQUENCE4.sa_slotid].sequence += 1;
00157 
00158   memcpy((char *)res_SEQUENCE4.SEQUENCE4res_u.sr_resok4.sr_sessionid,
00159          (char *)arg_SEQUENCE4.sa_sessionid, NFS4_SESSIONID_SIZE);
00160   res_SEQUENCE4.SEQUENCE4res_u.sr_resok4.sr_sequenceid =
00161       psession->slots[arg_SEQUENCE4.sa_slotid].sequence;
00162   res_SEQUENCE4.SEQUENCE4res_u.sr_resok4.sr_slotid = arg_SEQUENCE4.sa_slotid;
00163   res_SEQUENCE4.SEQUENCE4res_u.sr_resok4.sr_highest_slotid = NFS41_NB_SLOTS - 1;
00164   res_SEQUENCE4.SEQUENCE4res_u.sr_resok4.sr_target_highest_slotid = arg_SEQUENCE4.sa_slotid;    /* Maybe not the best choice */
00165   res_SEQUENCE4.SEQUENCE4res_u.sr_resok4.sr_status_flags = 0;   /* What is to be set here ? */
00166 
00167   if(arg_SEQUENCE4.sa_cachethis == TRUE)
00168     {
00169       data->pcached_res = &psession->slots[arg_SEQUENCE4.sa_slotid].cached_result;
00170       psession->slots[arg_SEQUENCE4.sa_slotid].cache_used = TRUE;
00171 
00172       LogFullDebug(COMPONENT_SESSIONS,
00173                    "Use sesson slot %"PRIu32"=%p for DRC",
00174                    arg_SEQUENCE4.sa_slotid, data->pcached_res);
00175     }
00176   else
00177     {
00178       data->pcached_res = NULL;
00179       psession->slots[arg_SEQUENCE4.sa_slotid].cache_used = FALSE;
00180 
00181       LogFullDebug(COMPONENT_SESSIONS,
00182                    "Don't use sesson slot %"PRIu32"=NULL for DRC",
00183                    arg_SEQUENCE4.sa_slotid);
00184     }
00185   V(psession->slots[arg_SEQUENCE4.sa_slotid].lock);
00186 
00187   res_SEQUENCE4.sr_status = NFS4_OK;
00188   return res_SEQUENCE4.sr_status;
00189 }                               /* nfs41_op_sequence */
00190 
00201 void nfs41_op_sequence_Free(SEQUENCE4res * resp)
00202 {
00203   /* Nothing to be done */
00204   return;
00205 }                               /* nfs4_op_sequence_Free */