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 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but 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 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 */ 00025 00037 #ifdef HAVE_CONFIG_H 00038 #include "config.h" 00039 #endif 00040 00041 #ifdef _SOLARIS 00042 #include "solaris_port.h" 00043 #endif 00044 00045 #include <stdio.h> 00046 #include <string.h> 00047 #include <pthread.h> 00048 #include "HashData.h" 00049 #include "HashTable.h" 00050 #include "log.h" 00051 #include "ganesha_rpc.h" 00052 #include "nfs4.h" 00053 #include "nfs_core.h" 00054 #include "sal_functions.h" 00055 #include "nfs_proto_functions.h" 00056 #include "nfs_proto_tools.h" 00057 00075 #define arg_LOCKU4 op->nfs_argop4_u.oplocku 00076 #define res_LOCKU4 resp->nfs_resop4_u.oplocku 00077 00078 int nfs41_op_locku(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp) 00079 { 00080 state_status_t state_status; 00081 state_t * pstate_found = NULL; 00082 state_owner_t * plock_owner; 00083 fsal_lock_param_t lock_desc; 00084 unsigned int rc = 0; 00085 const char * tag = "LOCKU"; 00086 00087 LogDebug(COMPONENT_NFS_V4_LOCK, 00088 "Entering NFS v4.1 LOCKU handler -----------------------------------------------------"); 00089 00090 /* Initialize to sane default */ 00091 resp->resop = NFS4_OP_LOCKU; 00092 res_LOCKU4.status = NFS4_OK; 00093 00094 /* 00095 * Do basic checks on a filehandle 00096 * LOCKU is done only on a file 00097 */ 00098 res_LOCKU4.status = nfs4_sanity_check_FH(data, REGULAR_FILE); 00099 if(res_LOCKU4.status != NFS4_OK) 00100 return res_LOCKU4.status; 00101 00102 /* Convert lock parameters to internal types */ 00103 switch(arg_LOCKU4.locktype) 00104 { 00105 case READ_LT: 00106 case READW_LT: 00107 lock_desc.lock_type = FSAL_LOCK_R; 00108 break; 00109 00110 case WRITE_LT: 00111 case WRITEW_LT: 00112 lock_desc.lock_type = FSAL_LOCK_W; 00113 break; 00114 } 00115 00116 lock_desc.lock_start = arg_LOCKU4.offset; 00117 00118 if(arg_LOCKU4.length != STATE_LOCK_OFFSET_EOF) 00119 lock_desc.lock_length = arg_LOCKU4.length; 00120 else 00121 lock_desc.lock_length = 0; 00122 00123 /* Check stateid correctness and get pointer to state */ 00124 if((rc = nfs4_Check_Stateid(&arg_LOCKU4.lock_stateid, 00125 data->current_entry, 00126 &pstate_found, 00127 data, 00128 STATEID_SPECIAL_FOR_LOCK, 00129 tag)) != NFS4_OK) 00130 { 00131 res_LOCKU4.status = rc; 00132 return res_LOCKU4.status; 00133 } 00134 00135 plock_owner = pstate_found->state_powner; 00136 00137 /* Lock length should not be 0 */ 00138 if(arg_LOCKU4.length == 0LL) 00139 { 00140 res_LOCKU4.status = NFS4ERR_INVAL; 00141 return res_LOCKU4.status; 00142 } 00143 00144 /* Check for range overflow 00145 * Remember that a length with all bits set to 1 means "lock until the end of file" (RFC3530, page 157) */ 00146 if(lock_desc.lock_length > (STATE_LOCK_OFFSET_EOF - lock_desc.lock_start)) 00147 { 00148 res_LOCKU4.status = NFS4ERR_INVAL; 00149 return res_LOCKU4.status; 00150 } 00151 00152 LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, 00153 tag, 00154 data->current_entry, 00155 data->pcontext, 00156 plock_owner, 00157 &lock_desc); 00158 00159 /* Now we have a lock owner and a stateid. 00160 * Go ahead and push unlock into SAL (and FSAL). 00161 */ 00162 if(state_unlock(data->current_entry, 00163 data->pcontext, 00164 data->pexport, 00165 plock_owner, 00166 pstate_found, 00167 &lock_desc, 00168 &state_status) != STATE_SUCCESS) 00169 { 00170 res_LOCKU4.status = nfs4_Errno_state(state_status); 00171 return res_LOCKU4.status; 00172 } 00173 00174 /* Successful exit */ 00175 res_LOCKU4.status = NFS4_OK; 00176 00177 /* Handle stateid/seqid for success */ 00178 update_stateid(pstate_found, 00179 &res_LOCKU4.LOCKU4res_u.lock_stateid, 00180 data, 00181 tag); 00182 00183 return res_LOCKU4.status; 00184 00185 } /* nfs41_op_locku */ 00186 00197 void nfs41_op_locku_Free(LOCKU4res * resp) 00198 { 00199 return; 00200 } /* nfs41_op_locku_Free */