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_Cancel(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_cancargs * arg = &parg->arg_nlm4_cancel; 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; 00069 fsal_lock_param_t lock; 00070 int rc; 00071 00072 netobj_to_string(&arg->cookie, buffer, 1024); 00073 LogDebug(COMPONENT_NLM, 00074 "REQUEST PROCESSING: Calling nlm4_Cancel 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_nlm4.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_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; 00091 LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Cancel %s", 00092 lock_result_str(pres->res_nlm4.stat.stat)); 00093 return NFS_REQ_OK; 00094 } 00095 00096 rc = nlm_process_parameters(preq, 00097 arg->exclusive, 00098 &arg->alock, 00099 &lock, 00100 &pentry, 00101 pcontext, 00102 CARE_NOT, /* cancel doesn't care if owner is found */ 00103 &nsm_client, 00104 &nlm_client, 00105 &nlm_owner, 00106 NULL); 00107 00108 if(rc >= 0) 00109 { 00110 /* Present the error back to the client */ 00111 pres->res_nlm4.stat.stat = (nlm4_stats)rc; 00112 LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", 00113 lock_result_str(pres->res_nlm4.stat.stat)); 00114 return NFS_REQ_OK; 00115 } 00116 00117 if(state_cancel(pentry, 00118 pcontext, 00119 pexport, 00120 nlm_owner, 00121 &lock, 00122 &state_status) != STATE_SUCCESS) 00123 { 00124 /* Cancel could fail in the FSAL and make a bit of a mess, especially if 00125 * we are in out of memory situation. Such an error is logged by 00126 * Cache Inode. 00127 */ 00128 pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); 00129 } 00130 else 00131 { 00132 pres->res_nlm4.stat.stat = NLM4_GRANTED; 00133 } 00134 00135 /* Release the NLM Client and NLM Owner references we have */ 00136 dec_nsm_client_ref(nsm_client); 00137 dec_nlm_client_ref(nlm_client); 00138 dec_state_owner_ref(nlm_owner); 00139 cache_inode_put(pentry); 00140 00141 LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Cancel %s", 00142 lock_result_str(pres->res_nlm4.stat.stat)); 00143 return NFS_REQ_OK; 00144 } /* nlm4_Cancel */ 00145 00146 static void nlm4_cancel_message_resp(state_async_queue_t *arg) 00147 { 00148 state_nlm_async_data_t * nlm_arg = &arg->state_async_data.state_nlm_async_data; 00149 00150 if(isFullDebug(COMPONENT_NLM)) 00151 { 00152 char buffer[1024]; 00153 netobj_to_string(&nlm_arg->nlm_async_args.nlm_async_res.res_nlm4test.cookie, buffer, 1024); 00154 LogFullDebug(COMPONENT_NLM, 00155 "Calling nlm_send_async cookie=%s status=%s", 00156 buffer, lock_result_str(nlm_arg->nlm_async_args.nlm_async_res.res_nlm4.stat.stat)); 00157 } 00158 nlm_send_async(NLMPROC4_CANCEL_RES, 00159 nlm_arg->nlm_async_host, 00160 &(nlm_arg->nlm_async_args.nlm_async_res), 00161 NULL); 00162 nlm4_Cancel_Free(&nlm_arg->nlm_async_args.nlm_async_res); 00163 dec_nsm_client_ref(nlm_arg->nlm_async_host->slc_nsm_client); 00164 dec_nlm_client_ref(nlm_arg->nlm_async_host); 00165 gsh_free(arg); 00166 } 00167 00168 /* Asynchronous Message Entry Point */ 00169 00181 int nlm4_Cancel_Message(nfs_arg_t * parg, 00182 exportlist_t * pexport, 00183 fsal_op_context_t * pcontext, 00184 nfs_worker_data_t * pworker, 00185 struct svc_req * preq, 00186 nfs_res_t * pres) 00187 { 00188 state_nlm_client_t * nlm_client = NULL; 00189 state_nsm_client_t * nsm_client; 00190 nlm4_cancargs * arg = &parg->arg_nlm4_cancel; 00191 int rc = NFS_REQ_OK; 00192 00193 LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm_Cancel_Message"); 00194 00195 nsm_client = get_nsm_client(CARE_NO_MONITOR, preq->rq_xprt, arg->alock.caller_name); 00196 00197 if(nsm_client != NULL) 00198 nlm_client = get_nlm_client(CARE_NO_MONITOR, preq->rq_xprt, nsm_client, arg->alock.caller_name); 00199 00200 if(nlm_client == NULL) 00201 rc = NFS_REQ_DROP; 00202 else 00203 rc = nlm4_Cancel(parg, pexport, pcontext, pworker, preq, pres); 00204 00205 if(rc == NFS_REQ_OK) 00206 rc = nlm_send_async_res_nlm4(nlm_client, nlm4_cancel_message_resp, pres); 00207 00208 if(rc == NFS_REQ_DROP) 00209 { 00210 if(nsm_client != NULL) 00211 dec_nsm_client_ref(nsm_client); 00212 if(nlm_client != NULL) 00213 dec_nlm_client_ref(nlm_client); 00214 LogCrit(COMPONENT_NLM, 00215 "Could not send async response for nlm_Cancel_Message"); 00216 } 00217 00218 return NFS_REQ_DROP; 00219 } 00220 00229 void nlm4_Cancel_Free(nfs_res_t * pres) 00230 { 00231 netobj_free(&pres->res_nlm4test.cookie); 00232 return; 00233 } /* nlm4_Cancel_Free */