nfs-ganesha 1.4
|
00001 /* 00002 * Copyright IBM Corporation, 2010 00003 * Contributor: Aneesh Kumar K.v <aneesh.kumar@linux.vnet.ibm.com> 00004 * 00005 * -------------------------- 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License 00009 * as published by the Free Software Foundation; either version 3 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, but 00013 * WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00020 * 02110-1301 USA 00021 * 00022 * 00023 */ 00024 00025 #ifdef HAVE_CONFIG_H 00026 #include "config.h" 00027 #endif 00028 00029 #ifdef _SOLARIS 00030 #include "solaris_port.h" 00031 #endif 00032 00033 #include <stdio.h> 00034 #include <string.h> 00035 #include <pthread.h> 00036 #include "log.h" 00037 #include "ganesha_rpc.h" 00038 #include "nlm4.h" 00039 #include "sal_functions.h" 00040 #include "nlm_util.h" 00041 #include "nlm_async.h" 00042 00055 int nlm4_Test(nfs_arg_t *parg, 00056 exportlist_t *pexport, 00057 fsal_op_context_t *pcontext, 00058 nfs_worker_data_t *pworker, 00059 struct svc_req *preq, 00060 nfs_res_t *pres) 00061 { 00062 nlm4_testargs * arg = &parg->arg_nlm4_test; 00063 cache_entry_t * pentry; 00064 state_status_t state_status = STATE_SUCCESS; 00065 char buffer[MAXNETOBJ_SZ * 2]; 00066 state_nsm_client_t * nsm_client; 00067 state_nlm_client_t * nlm_client; 00068 state_owner_t * nlm_owner, * holder; 00069 fsal_lock_param_t lock, conflict; 00070 int rc; 00071 00072 netobj_to_string(&arg->cookie, buffer, 1024); 00073 LogDebug(COMPONENT_NLM, 00074 "REQUEST PROCESSING: Calling nlm4_Test svid=%d off=%llx len=%llx cookie=%s", 00075 (int) arg->alock.svid, 00076 (unsigned long long) arg->alock.l_offset, 00077 (unsigned long long) arg->alock.l_len, 00078 buffer); 00079 00080 if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie)) 00081 { 00082 pres->res_nlm4test.test_stat.stat = NLM4_FAILED; 00083 LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", 00084 lock_result_str(pres->res_nlm4.stat.stat)); 00085 return NFS_REQ_OK; 00086 } 00087 00088 if(nfs_in_grace()) 00089 { 00090 pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD; 00091 LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", 00092 lock_result_str(pres->res_nlm4.stat.stat)); 00093 return NFS_REQ_OK; 00094 } 00095 00096 /* TODO FSF: 00097 * 00098 * TEST passes TRUE for care because we do need a non-NULL owner, but 00099 * we could expand the options to allow for a "free" owner to be 00100 * returned, that doesn't need to be in the hash table, so if the 00101 * owner isn't found in the Hash table, don't add it, just return 00102 * the "free" owner. 00103 */ 00104 rc = nlm_process_parameters(preq, 00105 arg->exclusive, 00106 &arg->alock, 00107 &lock, 00108 &pentry, 00109 pcontext, 00110 CARE_NO_MONITOR, 00111 &nsm_client, 00112 &nlm_client, 00113 &nlm_owner, 00114 NULL); 00115 00116 if(rc >= 0) 00117 { 00118 /* Present the error back to the client */ 00119 pres->res_nlm4.stat.stat = (nlm4_stats)rc; 00120 LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", 00121 lock_result_str(pres->res_nlm4.stat.stat)); 00122 return NFS_REQ_OK; 00123 } 00124 00125 if(state_test(pentry, 00126 pcontext, 00127 pexport, 00128 nlm_owner, 00129 &lock, 00130 &holder, 00131 &conflict, 00132 &state_status) != STATE_SUCCESS) 00133 { 00134 pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); 00135 00136 if(state_status == STATE_LOCK_CONFLICT) 00137 { 00138 nlm_process_conflict(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder, 00139 holder, 00140 &conflict); 00141 } 00142 } 00143 else 00144 { 00145 pres->res_nlm4.stat.stat = NLM4_GRANTED; 00146 } 00147 00148 LogFullDebug(COMPONENT_NLM, 00149 "Back from state_test"); 00150 00151 /* Release the NLM Client and NLM Owner references we have */ 00152 dec_nsm_client_ref(nsm_client); 00153 dec_nlm_client_ref(nlm_client); 00154 dec_state_owner_ref(nlm_owner); 00155 cache_inode_put(pentry); 00156 00157 LogDebug(COMPONENT_NLM, 00158 "REQUEST RESULT: nlm4_Test %s", 00159 lock_result_str(pres->res_nlm4.stat.stat)); 00160 return NFS_REQ_OK; 00161 } 00162 00163 static void nlm4_test_message_resp(state_async_queue_t *arg) 00164 { 00165 state_nlm_async_data_t * nlm_arg = &arg->state_async_data.state_nlm_async_data; 00166 00167 if(isFullDebug(COMPONENT_NLM)) 00168 { 00169 char buffer[1024]; 00170 netobj_to_string(&nlm_arg->nlm_async_args.nlm_async_res.res_nlm4test.cookie, buffer, 1024); 00171 LogFullDebug(COMPONENT_NLM, 00172 "Calling nlm_send_async cookie=%s status=%s", 00173 buffer, lock_result_str(nlm_arg->nlm_async_args.nlm_async_res.res_nlm4test.test_stat.stat)); 00174 } 00175 nlm_send_async(NLMPROC4_TEST_RES, 00176 nlm_arg->nlm_async_host, 00177 &(nlm_arg->nlm_async_args.nlm_async_res), 00178 NULL); 00179 nlm4_Test_Free(&nlm_arg->nlm_async_args.nlm_async_res); 00180 dec_nsm_client_ref(nlm_arg->nlm_async_host->slc_nsm_client); 00181 dec_nlm_client_ref(nlm_arg->nlm_async_host); 00182 gsh_free(arg); 00183 } 00184 00197 int nlm4_Test_Message(nfs_arg_t *parg, 00198 exportlist_t *pexport, 00199 fsal_op_context_t *pcontext, 00200 nfs_worker_data_t *pworker, 00201 struct svc_req *preq, 00202 nfs_res_t *pres) 00203 { 00204 state_nlm_client_t * nlm_client = NULL; 00205 state_nsm_client_t * nsm_client; 00206 nlm4_testargs * arg = &parg->arg_nlm4_test; 00207 int rc = NFS_REQ_OK; 00208 00209 LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm_Test_Message"); 00210 00211 nsm_client = get_nsm_client(CARE_NO_MONITOR, preq->rq_xprt, arg->alock.caller_name); 00212 00213 if(nsm_client != NULL) 00214 nlm_client = get_nlm_client(CARE_NO_MONITOR, preq->rq_xprt, nsm_client, arg->alock.caller_name); 00215 00216 if(nlm_client == NULL) 00217 rc = NFS_REQ_DROP; 00218 else 00219 rc = nlm4_Test(parg, pexport, pcontext, pworker, preq, pres); 00220 00221 if(rc == NFS_REQ_OK) 00222 rc = nlm_send_async_res_nlm4test(nlm_client, nlm4_test_message_resp, pres); 00223 00224 if(rc == NFS_REQ_DROP) 00225 { 00226 if(nsm_client != NULL) 00227 dec_nsm_client_ref(nsm_client); 00228 if(nlm_client != NULL) 00229 dec_nlm_client_ref(nlm_client); 00230 LogCrit(COMPONENT_NLM, 00231 "Could not send async response for nlm_Test_Message"); 00232 } 00233 00234 return NFS_REQ_DROP; 00235 } 00236 00245 void nlm4_Test_Free(nfs_res_t * pres) 00246 { 00247 netobj_free(&pres->res_nlm4test.cookie); 00248 if(pres->res_nlm4test.test_stat.stat == NLM4_DENIED) 00249 netobj_free(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder.oh); 00250 return; 00251 }