nfs-ganesha 1.4

nlm_Test.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_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 }