nfs-ganesha 1.4
|
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 */