nfs-ganesha 1.4

nlm_Cancel.c

Go to the documentation of this file.
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 */