Beispiel #1
0
int nlm4_Test_Message(nfs_arg_t * parg /* IN     */ ,
                      exportlist_t * pexport /* IN     */ ,
                      fsal_op_context_t * pcontext /* IN     */ ,
                      cache_inode_client_t * pclient /* INOUT  */ ,
                      hash_table_t * ht /* INOUT  */ ,
                      struct svc_req *preq /* IN     */ ,
                      nfs_res_t * pres /* OUT    */ )
{
  state_nlm_client_t * nlm_client;
  nlm4_testargs      * arg = &parg->arg_nlm4_test;
  int                  rc = NFS_REQ_OK;

  LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm_Test_Message");

  nlm_client = get_nlm_client(TRUE, arg->alock.caller_name);
  if(nlm_client == NULL)
    rc = NFS_REQ_DROP;
  else
    rc = nlm4_Test(parg, pexport, pcontext, pclient, ht, preq, pres);

  if(rc == NFS_REQ_OK)
    rc = nlm_send_async_res_nlm4test(nlm_client, nlm4_test_message_resp, pres);

  if(rc == NFS_REQ_DROP)
    {
      if(nlm_client != NULL)
        dec_nlm_client_ref(nlm_client);
      LogCrit(COMPONENT_NLM,
              "Could not send async response for nlm_Test_Message");
    }

  return NFS_REQ_DROP;
}
Beispiel #2
0
static void nlm4_unlock_message_resp(state_async_queue_t *arg)
{
	state_nlm_async_data_t *nlm_arg =
	    &arg->state_async_data.state_nlm_async_data;

	if (isFullDebug(COMPONENT_NLM)) {
		char buffer[1024] = "\0";

		netobj_to_string(&nlm_arg->nlm_async_args.nlm_async_res.
				 res_nlm4test.cookie, buffer, 1024);

		LogFullDebug(COMPONENT_NLM,
			     "Calling nlm_send_async cookie=%s status=%s",
			     buffer,
			     lock_result_str(nlm_arg->nlm_async_args.
					     nlm_async_res.res_nlm4.stat.stat));
	}

	nlm_send_async(NLMPROC4_UNLOCK_RES, nlm_arg->nlm_async_host,
		       &(nlm_arg->nlm_async_args.nlm_async_res), NULL);

	nlm4_Unlock_Free(&nlm_arg->nlm_async_args.nlm_async_res);
	dec_nsm_client_ref(nlm_arg->nlm_async_host->slc_nsm_client);
	dec_nlm_client_ref(nlm_arg->nlm_async_host);
	gsh_free(arg);
}
Beispiel #3
0
void dec_nlm_owner_ref_locked(state_owner_t *powner)
{
  bool_t remove = FALSE;
  char   str[HASHTABLE_DISPLAY_STRLEN];

  if(isFullDebug(COMPONENT_STATE))
    display_nlm_owner(powner, str);

  if(powner->so_refcount > 1)
    {
      powner->so_refcount--;

      LogFullDebug(COMPONENT_STATE,
                   "Decrement refcount for NLM Owner powner=%p {%s}, refcount = %d",
                   powner, str, powner->so_refcount);
    }
  else
    remove = TRUE;

  V(powner->so_mutex);

  if(remove)
    {
      hash_buffer_t buffkey, old_key, old_value;

      buffkey.pdata = (caddr_t) powner;
      buffkey.len = sizeof(*powner);

      switch(HashTable_DelRef(ht_nlm_owner, &buffkey, &old_key, &old_value, Hash_del_nlm_owner_ref))
        {
          case HASHTABLE_SUCCESS:
            LogFullDebug(COMPONENT_STATE,
                         "Free NLM Owner powner=%p {%s}, refcount = %d",
                         powner, str, powner->so_refcount);
            dec_nlm_client_ref(powner->so_owner.so_nlm_owner.so_client);
            Mem_Free(old_key.pdata);
            Mem_Free(old_value.pdata);
            break;

          case HASHTABLE_NOT_DELETED:
            /* ref count didn't end up at 0, don't free. */
            LogDebug(COMPONENT_STATE,
                     "HashTable_DelRef didn't reduce refcount to 0 for powner=%p {%s}, refcount = %d",
                      powner, str, powner->so_refcount);
            break;

          default:
            /* some problem occurred */
            LogDebug(COMPONENT_STATE,
                     "HashTable_DelRef failed for powner=%p {%s}",
                      powner, str);
            break;
        }
    }
}
Beispiel #4
0
static void nlm4_test_message_resp(nlm_async_queue_t *arg)
{
  if(isFullDebug(COMPONENT_NLM))
    {
      char buffer[1024];
      netobj_to_string(&arg->nlm_async_args.nlm_async_res.res_nlm4test.cookie, buffer, 1024);
      LogFullDebug(COMPONENT_NLM,
                   "Calling nlm_send_async cookie=%s status=%s",
                   buffer, lock_result_str(arg->nlm_async_args.nlm_async_res.res_nlm4test.test_stat.stat));
    }
  nlm_send_async(NLMPROC4_TEST_RES,
                 arg->nlm_async_host,
                 &(arg->nlm_async_args.nlm_async_res),
                 NULL);
  nlm4_Test_Free(&arg->nlm_async_args.nlm_async_res);
  dec_nlm_client_ref(arg->nlm_async_host);
  Mem_Free(arg);
}
Beispiel #5
0
/**
 * @brief Unlock Message
 *
 * @param[in]  args
 * @param[in]  req
 * @param[out] res
 *
 */
int nlm4_Unlock_Message(nfs_arg_t *args, struct svc_req *req, nfs_res_t *res)
{
	state_nlm_client_t *nlm_client = NULL;
	state_nsm_client_t *nsm_client;
	nlm4_unlockargs *arg = &args->arg_nlm4_unlock;
	int rc = NFS_REQ_OK;

	LogDebug(COMPONENT_NLM,
		 "REQUEST PROCESSING: Calling nlm_Unlock_Message");

	nsm_client = get_nsm_client(CARE_NO_MONITOR,
				    req->rq_xprt,
				    arg->alock.caller_name);

	if (nsm_client != NULL)
		nlm_client = get_nlm_client(CARE_NO_MONITOR,
					    req->rq_xprt, nsm_client,
					    arg->alock.caller_name);

	if (nlm_client == NULL)
		rc = NFS_REQ_DROP;
	else
		rc = nlm4_Unlock(args, req, res);

	if (rc == NFS_REQ_OK)
		rc = nlm_send_async_res_nlm4(nlm_client,
					     nlm4_unlock_message_resp,
					     res);

	if (rc == NFS_REQ_DROP) {
		if (nsm_client != NULL)
			dec_nsm_client_ref(nsm_client);

		if (nlm_client != NULL)
			dec_nlm_client_ref(nlm_client);

		LogCrit(COMPONENT_NLM,
			"Could not send async response for nlm_Unlock_Message");
	}

	return NFS_REQ_DROP;
}
Beispiel #6
0
void remove_nlm_owner(cache_inode_client_t * pclient,
                      state_owner_t        * powner,
                      const char           * str)
{
  hash_buffer_t buffkey, old_key, old_value;

  buffkey.pdata = (caddr_t) powner;
  buffkey.len = sizeof(*powner);

  switch(HashTable_DelRef(ht_nlm_owner, &buffkey, &old_key, &old_value, Hash_dec_state_owner_ref))
    {
      case HASHTABLE_SUCCESS:
        LogFullDebug(COMPONENT_STATE,
                     "Free %s size %llx",
                     str, (unsigned long long) old_value.len);
        dec_nlm_client_ref(powner->so_owner.so_nlm_owner.so_client);
        if(isFullDebug(COMPONENT_MEMLEAKS))
          {
            memset(old_key.pdata, 0, old_key.len);
            memset(old_value.pdata, 0, old_value.len);
          }
        Mem_Free(old_key.pdata);
        Mem_Free(old_value.pdata);
        break;

      case HASHTABLE_NOT_DELETED:
        /* ref count didn't end up at 0, don't free. */
        LogDebug(COMPONENT_STATE,
                 "HashTable_DelRef didn't reduce refcount to 0 for %s",
                  str);
        break;

      default:
        /* some problem occurred */
        LogDebug(COMPONENT_STATE,
                 "HashTable_DelRef failed for %s",
                  str);
        break;
    }
}
Beispiel #7
0
void free_nlm_owner(state_owner_t *powner)
{
  if(powner->so_owner.so_nlm_owner.so_client != NULL)
    dec_nlm_client_ref(powner->so_owner.so_nlm_owner.so_client);
}
Beispiel #8
0
state_owner_t *get_nlm_owner(care_t               care,
                             state_nlm_client_t * pclient, 
                             netobj             * oh,
                             uint32_t             svid)
{
  state_owner_t * pkey, *powner;

  if(pclient == NULL || oh == NULL || oh->n_len > MAX_NETOBJ_SZ)
    return NULL;

  pkey = (state_owner_t *)Mem_Alloc(sizeof(*pkey));
  if(pkey == NULL)
    return NULL;

  memset(pkey, 0, sizeof(*pkey));
  pkey->so_type                             = STATE_LOCK_OWNER_NLM;
  pkey->so_refcount                         = 1;
  pkey->so_owner.so_nlm_owner.so_client     = pclient;
  pkey->so_owner.so_nlm_owner.so_nlm_svid   = svid;
  pkey->so_owner_len                        = oh->n_len;
  memcpy(pkey->so_owner_val, oh->n_bytes, oh->n_len);

  if(isFullDebug(COMPONENT_STATE))
    {
      char str[HASHTABLE_DISPLAY_STRLEN];

      display_nlm_owner(pkey, str);

      LogFullDebug(COMPONENT_STATE,
                   "Find NLM Owner KEY {%s}", str);
    }

  /* If we found it, return it, if we don't care, return NULL */
  if(nlm_owner_Get_Pointer(pkey, &powner) == 1 || care == CARE_NOT)
    {
      /* Discard the key we created and return the found NLM Owner */
      Mem_Free(pkey);

      if(isFullDebug(COMPONENT_STATE))
        {
          char str[HASHTABLE_DISPLAY_STRLEN];

          display_nlm_owner(powner, str);
          LogFullDebug(COMPONENT_STATE,
                       "Found {%s}",
                       str);
        }

      return powner;
    }
    
  powner = (state_owner_t *)Mem_Alloc(sizeof(*pkey));
  if(powner == NULL)
    {
      Mem_Free(pkey);
      return NULL;
    }

  /* Copy everything over */
  *powner = *pkey;
  init_glist(&powner->so_lock_list);

  if(pthread_mutex_init(&powner->so_mutex, NULL) == -1)
    {
      /* Mutex initialization failed, free the key and created owner */
      Mem_Free(pkey);
      Mem_Free(powner);
      return NULL;
    }

  if(isFullDebug(COMPONENT_STATE))
    {
      char str[HASHTABLE_DISPLAY_STRLEN];

      display_nlm_owner(powner, str);
      LogFullDebug(COMPONENT_STATE,
                   "New {%s}", str);
    }

  /* Ref count the client as being used by this owner */
  inc_nlm_client_ref(pclient);
  if(nlm_owner_Set(pkey, powner) == 1)
    {
      if(isFullDebug(COMPONENT_STATE))
        {
          char str[HASHTABLE_DISPLAY_STRLEN];

          display_nlm_owner(powner, str);
          LogFullDebug(COMPONENT_STATE,
                       "Set NLM Owner {%s}",
                       str);
        }

      return powner;
    }

  dec_nlm_client_ref(pclient);
  Mem_Free(pkey);
  Mem_Free(powner);
  return NULL;
}
Beispiel #9
0
int nlm4_Unshare(nfs_arg_t *args, struct svc_req *req, nfs_res_t *res)
{
	nlm4_shareargs *arg = &args->arg_nlm4_share;
	struct fsal_obj_handle *obj;
	state_status_t state_status = STATE_SUCCESS;
	char buffer[MAXNETOBJ_SZ * 2] = "\0";
	state_nsm_client_t *nsm_client;
	state_nlm_client_t *nlm_client;
	state_owner_t *nlm_owner;
	state_t *nlm_state;
	int rc;

	/* NLM doesn't have a BADHANDLE error, nor can rpc_execute deal with
	 * responding to an NLM_*_MSG call, so we check here if the export is
	 * NULL and if so, handle the response.
	 */
	if (op_ctx->ctx_export == NULL) {
		res->res_nlm4share.stat = NLM4_STALE_FH;
		LogInfo(COMPONENT_NLM, "INVALID HANDLE: NLM4_UNSHARE");
		return NFS_REQ_OK;
	}

	res->res_nlm4share.sequence = 0;

	netobj_to_string(&arg->cookie, buffer, 1024);

	if (isDebug(COMPONENT_NLM)) {
		char str[LEN_FH_STR];
		char oh[MAXNETOBJ_SZ * 2] = "\0";

		sprint_fhandle3(str, (struct nfs_fh3 *)&arg->share.fh);
		netobj_to_string(&arg->share.oh, oh, 1024);

		LogDebug(COMPONENT_NLM,
			 "REQUEST PROCESSING: Calling NLM4_UNSHARE handle: %s, cookie=%s, reclaim=%s, owner=%s, access=%d, deny=%d",
			 str, buffer, arg->reclaim ? "yes" : "no", oh,
			 arg->share.access,
			 arg->share.mode);
	}

	copy_netobj(&res->res_nlm4share.cookie, &arg->cookie);

	rc = nlm_process_share_parms(req,
				     &arg->share,
				     op_ctx->fsal_export,
				     &obj,
				     CARE_NOT,
				     &nsm_client,
				     &nlm_client,
				     &nlm_owner,
				     &nlm_state);

	if (rc >= 0) {
		/* Present the error back to the client */
		res->res_nlm4share.stat = (nlm4_stats) rc;
		LogDebug(COMPONENT_NLM,
			 "REQUEST RESULT: NLM4_UNSHARE %s",
			 lock_result_str(res->res_nlm4share.stat));
		return NFS_REQ_OK;
	}

	state_status = state_nlm_share(obj,
				       arg->share.access,
				       arg->share.mode,
				       nlm_owner,
				       nlm_state,
				       false,
				       true);

	if (state_status != STATE_SUCCESS) {
		res->res_nlm4share.stat =
		    nlm_convert_state_error(state_status);
	} else {
		res->res_nlm4share.stat = NLM4_GRANTED;
	}

	/* Release the NLM Client and NLM Owner references we have */
	dec_nsm_client_ref(nsm_client);
	dec_nlm_client_ref(nlm_client);
	dec_state_owner_ref(nlm_owner);
	obj->obj_ops->put_ref(obj);
	dec_nlm_state_ref(nlm_state);

	LogDebug(COMPONENT_NLM, "REQUEST RESULT: NLM4_UNSHARE %s",
		 lock_result_str(res->res_nlm4share.stat));

	return NFS_REQ_OK;
}
Beispiel #10
0
state_status_t nlm_granted_callback(cache_entry_t        * pentry,
                                    state_lock_entry_t   * lock_entry,
                                    state_status_t       * pstatus)
{
  fsal_op_context_t        fsal_context, *pcontext = &fsal_context;
  state_block_data_t     * block_data     = lock_entry->sle_block_data;
  state_nlm_block_data_t * nlm_block_data = &block_data->sbd_block_data.sbd_nlm_block_data;
  state_cookie_entry_t   * cookie_entry = NULL;
  state_async_queue_t    * arg;
  nlm4_testargs          * inarg;
  state_nlm_owner_t      * nlm_grant_owner  = &lock_entry->sle_owner->so_owner.so_nlm_owner;
  state_nlm_client_t     * nlm_grant_client = nlm_grant_owner->so_client;
  granted_cookie_t         nlm_grant_cookie;
  state_status_t           dummy_status;

  if(nlm_block_data_to_fsal_context(block_data, &fsal_context) != TRUE)
    {
      *pstatus = STATE_INCONSISTENT_ENTRY;
      return *pstatus;
    }

  arg = gsh_malloc(sizeof(*arg));
  if(arg == NULL)
    {
      /* If we fail allocation the best is to delete the block entry
      * so that client can try again and get the lock. May be
      * by then we are able to allocate objects
      */
      *pstatus = STATE_MALLOC_ERROR;
      return *pstatus;
   }

  memset(arg, 0, sizeof(*arg));

  /* Get a cookie to use for this grant */
  next_granted_cookie(&nlm_grant_cookie);

  /* Add a cookie to the blocked lock pending grant.
   * It will also request lock from FSAL.
   * Could return STATE_LOCK_BLOCKED because FSAL would have had to block.
   */
  if(state_add_grant_cookie(pentry,
                            pcontext,
                            &nlm_grant_cookie,
                            sizeof(nlm_grant_cookie),
                            lock_entry,
                            &cookie_entry,
                            pstatus) != STATE_SUCCESS)
    {
      free_grant_arg(arg);
      return *pstatus;
    }

  /* Fill in the arguments for the NLMPROC4_GRANTED_MSG call */
  inc_nlm_client_ref(nlm_grant_client);
  arg->state_async_func = nlm4_send_grant_msg;
  arg->state_async_data.state_nlm_async_data.nlm_async_host = nlm_grant_client;
  arg->state_async_data.state_nlm_async_data.nlm_async_key  = cookie_entry;
  inarg = &arg->state_async_data.state_nlm_async_data.nlm_async_args.nlm_async_grant;

  if(!copy_netobj(&inarg->alock.fh, &nlm_block_data->sbd_nlm_fh))
    goto grant_fail_malloc;

  if(!fill_netobj(&inarg->alock.oh,
                  lock_entry->sle_owner->so_owner_val,
                  lock_entry->sle_owner->so_owner_len))
    goto grant_fail_malloc;

  if(!fill_netobj(&inarg->cookie,
                  (char *) &nlm_grant_cookie,
                  sizeof(nlm_grant_cookie)))
    goto grant_fail_malloc;

  inarg->alock.caller_name = gsh_strdup(nlm_grant_client->slc_nlm_caller_name);
  if(!inarg->alock.caller_name)
    goto grant_fail_malloc;

  inarg->exclusive      = lock_entry->sle_lock.lock_type == FSAL_LOCK_W;
  inarg->alock.svid     = nlm_grant_owner->so_nlm_svid;
  inarg->alock.l_offset = lock_entry->sle_lock.lock_start;
  inarg->alock.l_len    = lock_entry->sle_lock.lock_length;
  if(isDebug(COMPONENT_NLM))
    {
      char buffer[1024];

      netobj_to_string(&inarg->cookie, buffer, sizeof(buffer));

      LogDebug(COMPONENT_NLM,
               "Sending GRANTED for arg=%p svid=%d start=%llx len=%llx cookie=%s",
               arg, inarg->alock.svid,
               (unsigned long long) inarg->alock.l_offset, (unsigned long long) inarg->alock.l_len,
               buffer);
    }

  /* Now try to schedule NLMPROC4_GRANTED_MSG call */
  *pstatus = state_async_schedule(arg);

  if(*pstatus != STATE_SUCCESS)
    goto grant_fail;

  return *pstatus;

 grant_fail_malloc:
  *pstatus = STATE_MALLOC_ERROR;

 grant_fail:

  /* Something went wrong after we added a grant cookie, need to clean up */

  dec_nlm_client_ref(nlm_grant_client);

  /* Clean up NLMPROC4_GRANTED_MSG arguments */
  free_grant_arg(arg);

  /* Cancel the pending grant to release the cookie */
  if(state_cancel_grant(pcontext,
                        cookie_entry,
                        &dummy_status) != STATE_SUCCESS)
    {
      /* Not much we can do other than log that something bad happened. */
      LogCrit(COMPONENT_NLM,
              "Unable to clean up GRANTED lock after error");
    }

  return *pstatus;
}
Beispiel #11
0
int nlm_process_parameters(struct svc_req        * preq,
                           bool_t                  exclusive,
                           nlm4_lock             * alock,
                           fsal_lock_param_t     * plock,
                           cache_entry_t        ** ppentry,
                           fsal_op_context_t     * pcontext,
                           care_t                  care,
                           state_nsm_client_t   ** ppnsm_client,
                           state_nlm_client_t   ** ppnlm_client,
                           state_owner_t        ** ppowner,
                           state_block_data_t   ** ppblock_data)
{
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t      attr;
  cache_inode_status_t    cache_status;
  SVCXPRT                *ptr_svc = preq->rq_xprt;
  int                     rc;

  *ppnsm_client = NULL;
  *ppnlm_client = NULL;
  *ppowner      = NULL;

  /* Convert file handle into a cache entry */
  if(alock->fh.n_len > MAX_NETOBJ_SZ ||
     !nfs3_FhandleToFSAL((nfs_fh3 *) &alock->fh, &fsal_data.fh_desc, pcontext))
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  /* Now get the cached inode attributes */
  *ppentry = cache_inode_get(&fsal_data,
                             &attr,
                             pcontext,
                             NULL,
                             &cache_status);
  if(*ppentry == NULL)
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  *ppnsm_client = get_nsm_client(care, ptr_svc, alock->caller_name);

  if(*ppnsm_client == NULL)
    {
      /* If NSM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, alock->caller_name);

  if(*ppnlm_client == NULL)
    {
      /* If NLM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      dec_nsm_client_ref(*ppnsm_client);

      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppowner = get_nlm_owner(care, *ppnlm_client, &alock->oh, alock->svid);

  if(*ppowner == NULL)
    {
      LogDebug(COMPONENT_NLM,
               "Could not get NLM Owner");
      dec_nsm_client_ref(*ppnsm_client);
      dec_nlm_client_ref(*ppnlm_client);
      *ppnlm_client = NULL;

      /* If owner is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  if(ppblock_data != NULL)
    {
      *ppblock_data = gsh_calloc(1, sizeof(**ppblock_data));
      /* Fill in the block data, if we don't get one, we will just proceed
       * without (which will mean the lock doesn't block.
       */
      if(*ppblock_data != NULL)
        {
          if(copy_xprt_addr(&(*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_hostaddr, ptr_svc) == 0)
            {
              LogFullDebug(COMPONENT_NLM,
                           "copy_xprt_addr failed for Program %d, Version %d, Function %d",
                           (int)preq->rq_prog, (int)preq->rq_vers, (int)preq->rq_proc);
              gsh_free(*ppblock_data);
              *ppblock_data = NULL;
              rc = NLM4_FAILED;
              goto out_put;
            }
          (*ppblock_data)->sbd_granted_callback = nlm_granted_callback;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_bytes =
            (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_len = alock->fh.n_len;
          memcpy((*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf,
                 alock->fh.n_bytes,
                 alock->fh.n_len);
          /* FSF TODO: Ultimately I think the following will go away, we won't need the context, just the export */
          /* Copy credentials from pcontext */
#ifdef _USE_HPSS
	  /** @todo : PhD: Think about removing hpsscred_t from FSAL */ 
          (*ppblock_data)->sbd_credential.user  =  pcontext->credential.hpss_usercred.Uid ;
          (*ppblock_data)->sbd_credential.group =  pcontext->credential.hpss_usercred.Gid ;
#else
          (*ppblock_data)->sbd_credential = pcontext->credential;

          /* Copy the alt groups list */
          if(pcontext->credential.nbgroups != 0)
            {
              (*ppblock_data)->sbd_credential.alt_groups =
                      gsh_malloc(sizeof(gid_t) * pcontext->credential.nbgroups);
              if((*ppblock_data)->sbd_credential.alt_groups == NULL)
                {
                  gsh_free(*ppblock_data);
                  *ppblock_data = NULL;
                  rc = NLM4_FAILED;
                  goto out_put;
                }
              memcpy((*ppblock_data)->sbd_credential.alt_groups,
                     pcontext->credential.alt_groups,
                     pcontext->credential.nbgroups);
            }
#endif
        }
    }
  /* Fill in plock */
  plock->lock_type   = exclusive ? FSAL_LOCK_W : FSAL_LOCK_R;
  plock->lock_start  = alock->l_offset;
  plock->lock_length = alock->l_len;

  LogFullDebug(COMPONENT_NLM,
               "Parameters Processed");

  return -1;

 out_put:

  cache_inode_put(*ppentry);
  *ppentry = NULL;
  return rc;
}
Beispiel #12
0
int nlm_process_parameters(struct svc_req        * preq,
                           bool_t                  exclusive,
                           nlm4_lock             * alock,
                           state_lock_desc_t     * plock,
                           hash_table_t          * ht,
                           cache_entry_t        ** ppentry,
                           fsal_op_context_t     * pcontext,
                           cache_inode_client_t  * pclient,
                           care_t                  care,
                           state_nsm_client_t   ** ppnsm_client,
                           state_nlm_client_t   ** ppnlm_client,
                           state_owner_t        ** ppowner,
                           state_block_data_t   ** ppblock_data)
{
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t      attr;
  cache_inode_status_t    cache_status;
  SVCXPRT                *ptr_svc = preq->rq_xprt;

  *ppnsm_client = NULL;
  *ppnlm_client = NULL;
  *ppowner      = NULL;

  /* Convert file handle into a cache entry */
  if(alock->fh.n_len > MAX_NETOBJ_SZ ||
     !nfs3_FhandleToFSAL((nfs_fh3 *) &alock->fh, &fsal_data.handle, pcontext))
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  /* Now get the cached inode attributes */
  fsal_data.cookie = DIR_START;
  *ppentry = cache_inode_get(&fsal_data,
                             CACHE_INODE_JOKER_POLICY,
                             &attr,
                             ht,
                             pclient,
                             pcontext,
                             &cache_status);
  if(*ppentry == NULL)
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  *ppnsm_client = get_nsm_client(care, ptr_svc, alock->caller_name);

  if(*ppnsm_client == NULL)
    {
      /* If NSM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        return NLM4_DENIED_NOLOCKS;
      else
        return NLM4_GRANTED;
    }

  *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, alock->caller_name);

  if(*ppnlm_client == NULL)
    {
      /* If NLM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      dec_nsm_client_ref(*ppnsm_client);

      if(care != CARE_NOT)
        return NLM4_DENIED_NOLOCKS;
      else
        return NLM4_GRANTED;
    }

  *ppowner = get_nlm_owner(care, *ppnlm_client, &alock->oh, alock->svid);

  if(*ppowner == NULL)
    {
      LogDebug(COMPONENT_NLM,
               "Could not get NLM Owner");
      dec_nsm_client_ref(*ppnsm_client);
      dec_nlm_client_ref(*ppnlm_client);
      *ppnlm_client = NULL;

      /* If owner is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care)
        return NLM4_DENIED_NOLOCKS;
      else
        return NLM4_GRANTED;
    }

  if(ppblock_data != NULL)
    {
      *ppblock_data = (state_block_data_t *) Mem_Alloc_Label(sizeof(**ppblock_data),
                                                             "NLM_Block_Data");
      /* Fill in the block data, if we don't get one, we will just proceed
       * without (which will mean the lock doesn't block.
       */
      if(*ppblock_data != NULL)
        {
          memset(*ppblock_data, 0, sizeof(**ppblock_data));
          if(copy_xprt_addr(&(*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_hostaddr, ptr_svc) == 0)
            {
              LogFullDebug(COMPONENT_NLM,
                           "copy_xprt_addr failed for Program %d, Version %d, Function %d",
                           (int)preq->rq_prog, (int)preq->rq_vers, (int)preq->rq_proc);
              Mem_Free(*ppblock_data);
              *ppblock_data = NULL;
              return NLM4_FAILED;
            }
          (*ppblock_data)->sbd_granted_callback = nlm_granted_callback;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_bytes =
            (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf;
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_len = alock->fh.n_len;
          memcpy((*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf,
                 alock->fh.n_bytes,
                 alock->fh.n_len);
          /* FSF TODO: Ultimately I think the following will go away, we won't need the context, just the export */
          /* Copy credentials from pcontext */
          (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_credential = pcontext->credential;
        }
    }
  /* Fill in plock */
  plock->sld_type   = exclusive ? STATE_LOCK_W : STATE_LOCK_R;
  plock->sld_offset = alock->l_offset;
  plock->sld_length = alock->l_len;

  LogFullDebug(COMPONENT_NLM,
               "Parameters Processed");

  return -1;
}
Beispiel #13
0
int nlm4_Test(nfs_arg_t * parg /* IN     */ ,
              exportlist_t * pexport /* IN     */ ,
              fsal_op_context_t * pcontext /* IN     */ ,
              cache_inode_client_t * pclient /* INOUT  */ ,
              hash_table_t * ht /* INOUT  */ ,
              struct svc_req *preq /* IN     */ ,
              nfs_res_t * pres /* OUT    */ )
{
  nlm4_testargs      * arg = &parg->arg_nlm4_test;
  cache_entry_t      * pentry;
  state_status_t       state_status = CACHE_INODE_SUCCESS;
  char                 buffer[MAXNETOBJ_SZ * 2];
  state_nlm_client_t * nlm_client;
  state_owner_t      * nlm_owner, * holder;
  state_lock_desc_t    lock, conflict;
  int                  rc;

  netobj_to_string(&arg->cookie, buffer, 1024);
  LogDebug(COMPONENT_NLM,
           "REQUEST PROCESSING: Calling nlm4_Test svid=%d off=%llx len=%llx cookie=%s",
           (int) arg->alock.svid,
           (unsigned long long) arg->alock.l_offset,
           (unsigned long long) arg->alock.l_len,
           buffer);

  if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie))
    {
      pres->res_nlm4test.test_stat.stat = NLM4_FAILED;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  if(in_nlm_grace_period())
    {
      pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  /* TODO FSF:
   *
   * TEST passes TRUE for care because we do need a non-NULL owner,  but
   * we could expand the options to allow for a "free" owner to be
   * returned, that doesn't need to be in the hash table, so if the
   * owner isn't found in the Hash table, don't add it, just return
   * the "free" owner.
   */
  rc = nlm_process_parameters(preq,
                              arg->exclusive,
                              &arg->alock,
                              &lock,
                              ht,
                              &pentry,
                              pcontext,
                              pclient,
                              CARE_NO_MONITOR,
                              &nlm_client,
                              &nlm_owner,
                              NULL);

  if(rc >= 0)
    {
      /* Present the error back to the client */
      pres->res_nlm4.stat.stat = (nlm4_stats)rc;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  if(state_test(pentry,
                pcontext,
                nlm_owner,
                &lock,
                &holder,
                &conflict,
                pclient,
                &state_status) != STATE_SUCCESS)
    {
      pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status);

      if(state_status == STATE_LOCK_CONFLICT)
        {
          nlm_process_conflict(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder,
                               holder,
                               &conflict);
        }
    }
  else
    {
      pres->res_nlm4.stat.stat = NLM4_GRANTED;
    }

  LogFullDebug(COMPONENT_NLM,
               "Back from state_test");

  /* Release the NLM Client and NLM Owner references we have */
  dec_nlm_client_ref(nlm_client);
  dec_nlm_owner_ref(nlm_owner);

  LogDebug(COMPONENT_NLM,
           "REQUEST RESULT: nlm4_Test %s",
           lock_result_str(pres->res_nlm4.stat.stat));
  return NFS_REQ_OK;
}
Beispiel #14
0
/**
 *
 * nlm4_send_grant_msg: Send NLMPROC4_GRANTED_MSG
 *
 * This runs in the nlm_asyn_thread context.
 */
static void nlm4_send_grant_msg(state_async_queue_t *arg)
{
	int retval;
	char buffer[1024];
	state_status_t state_status = STATE_SUCCESS;
	state_cookie_entry_t *cookie_entry;
	state_nlm_async_data_t *nlm_arg =
	    &arg->state_async_data.state_nlm_async_data;
	struct root_op_context root_op_context;
	struct gsh_export *export;

	if (isDebug(COMPONENT_NLM)) {
		netobj_to_string(&nlm_arg->nlm_async_args.nlm_async_grant.
				 cookie, buffer, sizeof(buffer));

		LogDebug(COMPONENT_NLM,
			 "Sending GRANTED for arg=%p svid=%d start=%llx len=%llx cookie=%s",
			 arg,
			 nlm_arg->nlm_async_args.nlm_async_grant.alock.svid,
			 (unsigned long long)nlm_arg->nlm_async_args.
			 nlm_async_grant.alock.l_offset,
			 (unsigned long long)nlm_arg->nlm_async_args.
			 nlm_async_grant.alock.l_len, buffer);
	}

	retval = nlm_send_async(NLMPROC4_GRANTED_MSG,
				nlm_arg->nlm_async_host,
				&nlm_arg->nlm_async_args.nlm_async_grant,
				nlm_arg->nlm_async_key);

	dec_nlm_client_ref(nlm_arg->nlm_async_host);

	/* If success, we are done. */
	if (retval == RPC_SUCCESS)
		goto out;

	/*
	 * We are not able call granted callback. Some client may retry
	 * the lock again. So remove the existing blocked nlm entry
	 */
	LogMajor(COMPONENT_NLM,
		 "GRANTED_MSG RPC call failed with return code %d. Removing the blocking lock",
		 retval);

	state_status = state_find_grant(
			nlm_arg->nlm_async_args.nlm_async_grant.cookie.n_bytes,
			nlm_arg->nlm_async_args.nlm_async_grant.cookie.n_len,
			&cookie_entry);

	if (state_status != STATE_SUCCESS) {
		/* This must be an old NLM_GRANTED_RES */
		LogFullDebug(COMPONENT_NLM,
			     "Could not find cookie=%s status=%s", buffer,
			     state_err_str(state_status));
		goto out;
	}

	if (cookie_entry->sce_lock_entry->sle_block_data == NULL) {
		/* Wow, we're not doing well... */
		LogFullDebug(COMPONENT_NLM,
			     "Could not find block data for cookie=%s (must be an old NLM_GRANTED_RES)",
			     buffer);
		goto out;
	}

	/* Initialize a context, it is ok if the export is stale because
	 * we must clean up the cookie_entry.
	 */
	export = cookie_entry->sce_lock_entry->sle_export;
Beispiel #15
0
int nlm4_Unlock(nfs_arg_t *args, struct svc_req *req, nfs_res_t *res)
{
	nlm4_unlockargs *arg = &args->arg_nlm4_unlock;
	struct fsal_obj_handle *obj;
	state_status_t state_status = STATE_SUCCESS;
	char buffer[MAXNETOBJ_SZ * 2] = "\0";
	state_nsm_client_t *nsm_client;
	state_nlm_client_t *nlm_client;
	state_owner_t *nlm_owner;
	fsal_lock_param_t lock;
	int rc;
	state_t *state;

	/* NLM doesn't have a BADHANDLE error, nor can rpc_execute deal with
	 * responding to an NLM_*_MSG call, so we check here if the export is
	 * NULL and if so, handle the response.
	 */
	if (op_ctx->ctx_export == NULL) {
		res->res_nlm4.stat.stat = NLM4_STALE_FH;
		LogInfo(COMPONENT_NLM, "INVALID HANDLE: nlm4_Unlock");
		return NFS_REQ_OK;
	}

	netobj_to_string(&arg->cookie, buffer, sizeof(buffer));

	LogDebug(COMPONENT_NLM,
		 "REQUEST PROCESSING: Calling nlm4_Unlock svid=%d off=%llx len=%llx cookie=%s",
		 (int)arg->alock.svid,
		 (unsigned long long)arg->alock.l_offset,
		 (unsigned long long)arg->alock.l_len, buffer);

	copy_netobj(&res->res_nlm4test.cookie, &arg->cookie);

	if (nfs_in_grace()) {
		res->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD;
		LogDebug(COMPONENT_NLM,
			 "REQUEST RESULT: nlm4_Unlock %s",
			 lock_result_str(res->res_nlm4.stat.stat));
		return NFS_REQ_OK;
	}

	/* unlock doesn't care if owner is found */
	rc = nlm_process_parameters(req,
				    false,
				    &arg->alock,
				    &lock,
				    &obj,
				    CARE_NOT,
				    &nsm_client,
				    &nlm_client,
				    &nlm_owner,
				    NULL,
				    0,
				    &state);

	if (rc >= 0) {
		/* resent the error back to the client */
		res->res_nlm4.stat.stat = (nlm4_stats) rc;
		LogDebug(COMPONENT_NLM,
			 "REQUEST RESULT: nlm4_Unlock %s",
			 lock_result_str(res->res_nlm4.stat.stat));
		return NFS_REQ_OK;
	}

	if (state != NULL)
		state_status =
		  state_unlock(obj, state, nlm_owner, false, 0, &lock);

	if (state_status != STATE_SUCCESS) {
		/* Unlock could fail in the FSAL and make a bit of a mess,
		 * especially if we are in out of memory situation. Such an
		 * error is logged by Cache Inode.
		 */
		res->res_nlm4test.test_stat.stat =
		    nlm_convert_state_error(state_status);
	} else {
		res->res_nlm4.stat.stat = NLM4_GRANTED;
	}

	/* Release the NLM Client and NLM Owner references we have */
	if (state != NULL)
		dec_state_t_ref(state);
	dec_nsm_client_ref(nsm_client);
	dec_nlm_client_ref(nlm_client);
	dec_state_owner_ref(nlm_owner);
	obj->obj_ops.put_ref(obj);

	LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
		 lock_result_str(res->res_nlm4.stat.stat));
	return NFS_REQ_OK;
}
Beispiel #16
0
state_nlm_client_t *get_nlm_client(care_t               care,
                                   SVCXPRT            * xprt,
                                   state_nsm_client_t * pnsm_client,
                                   char               * caller_name)
{
  state_nlm_client_t   key;
  state_nlm_client_t * pclient;
  char                 str[HASHTABLE_DISPLAY_STRLEN];
  struct hash_latch    latch;
  hash_error_t         rc;
  hash_buffer_t        buffkey;
  hash_buffer_t        buffval;

  if(caller_name == NULL)
    return NULL;

  memset(&key, 0, sizeof(key));

  key.slc_nsm_client          = pnsm_client;
  key.slc_nlm_caller_name_len = strlen(caller_name);
  key.slc_client_type         = svc_get_xprt_type(xprt);

  if(key.slc_nlm_caller_name_len > LM_MAXSTRLEN)
    return NULL;

  key.slc_nlm_caller_name = caller_name;
  
  if(isFullDebug(COMPONENT_STATE))
    {
      display_nlm_client(&key, str);
      LogFullDebug(COMPONENT_STATE,
                   "Find {%s}", str);
    }

  buffkey.pdata = &key;
  buffkey.len   = sizeof(key);

  rc = HashTable_GetLatch(ht_nlm_client,
                          &buffkey,
                          &buffval,
                          TRUE,
                          &latch);

  /* If we found it, return it */
  if(rc == HASHTABLE_SUCCESS)
    {
      pclient = buffval.pdata;

      /* Return the found NLM Client */
      if(isFullDebug(COMPONENT_STATE))
        {
          display_nlm_client(pclient, str);
          LogFullDebug(COMPONENT_STATE,
                       "Found {%s}",
                       str);
        }

      /* Increment refcount under hash latch.
       * This prevents dec ref from removing this entry from hash if a race
       * occurs.
       */
      inc_nlm_client_ref(pclient);

      HashTable_ReleaseLatched(ht_nlm_client, &latch);

      if(care == CARE_MONITOR && !nsm_monitor(pnsm_client))
          {
            dec_nlm_client_ref(pclient);
            pclient = NULL;
          }

      return pclient;
    }

  /* An error occurred, return NULL */
  if(rc != HASHTABLE_ERROR_NO_SUCH_KEY)
    {
      display_nlm_client(&key, str);

      LogCrit(COMPONENT_STATE,
              "Error %s, could not find {%s}",
              hash_table_err_to_str(rc), str);

      return NULL;
    }

  /* Not found, but we don't care, return NULL */
  if(care == CARE_NOT)
    {
      /* Return the found NLM Client */
      if(isFullDebug(COMPONENT_STATE))
        {
          display_nlm_client(&key, str);
          LogFullDebug(COMPONENT_STATE,
                       "Ignoring {%s}",
                       str);
        }

      HashTable_ReleaseLatched(ht_nlm_client, &latch);

      return NULL;
    }

  pclient = gsh_malloc(sizeof(*pclient));

  if(pclient == NULL)
    {
      display_nlm_client(&key, str);
      LogCrit(COMPONENT_STATE,
              "No memory for {%s}",
              str);

      return NULL;
    }

  /* Copy everything over */
  memcpy(pclient, &key, sizeof(key));

  pclient->slc_nlm_caller_name = gsh_strdup(key.slc_nlm_caller_name);

  /* Take a reference to the NSM Client */
  inc_nsm_client_ref(pnsm_client);

  if(pclient->slc_nlm_caller_name == NULL)
    {
      /* Discard the created client */
      free_nlm_client(pclient);
      return NULL;
    }

  pclient->slc_refcount = 1;

  if(isFullDebug(COMPONENT_STATE))
    {
      display_nlm_client(pclient, str);
      LogFullDebug(COMPONENT_STATE,
                   "New {%s}", str);
    }

  buffkey.pdata = pclient;
  buffkey.len   = sizeof(*pclient);
  buffval.pdata = pclient;
  buffval.len   = sizeof(*pclient);

  rc = HashTable_SetLatched(ht_nlm_client,
                            &buffval,
                            &buffval,
                            &latch,
                            FALSE,
                            NULL,
                            NULL);

  /* An error occurred, return NULL */
  if(rc != HASHTABLE_SUCCESS)
    {
      display_nlm_client(pclient, str);

      LogCrit(COMPONENT_STATE,
              "Error %s, inserting {%s}",
              hash_table_err_to_str(rc), str);

      free_nlm_client(pclient);

      return NULL;
    }

  if(care != CARE_MONITOR || nsm_monitor(pnsm_client))
    return pclient;

  /* Failed to monitor, release client reference
   * and almost certainly remove it from the hash table.
   */
  dec_nlm_client_ref(pclient);

  return NULL;
}
Beispiel #17
0
int nlm4_Share(nfs_arg_t            * parg,
               exportlist_t         * pexport,
               fsal_op_context_t    * pcontext,
               nfs_worker_data_t    * pworker,
               struct svc_req       * preq,
               nfs_res_t            * pres)
{
  nlm4_shareargs     * arg = &parg->arg_nlm4_share;
  cache_entry_t      * pentry;
  state_status_t       state_status = STATE_SUCCESS;
  char                 buffer[MAXNETOBJ_SZ * 2];
  state_nsm_client_t * nsm_client;
  state_nlm_client_t * nlm_client;
  state_owner_t      * nlm_owner;
  int                  rc;
  int                  grace = nfs_in_grace();

  pres->res_nlm4share.sequence = 0;

  netobj_to_string(&arg->cookie, buffer, 1024);
  LogDebug(COMPONENT_NLM,
           "REQUEST PROCESSING: Calling nlm4_Share cookie=%s reclaim=%s",
           buffer,
           arg->reclaim ? "yes" : "no");

  if(!copy_netobj(&pres->res_nlm4share.cookie, &arg->cookie))
    {
      pres->res_nlm4share.stat = NLM4_FAILED;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Share %s",
               lock_result_str(pres->res_nlm4share.stat));
      return NFS_REQ_OK;
    }

  /* Allow only reclaim share request during recovery and visa versa.
   * Note: NLM_SHARE is indicated to be non-monitored, however, it does
   * have a reclaim flag, so we will honor the reclaim flag if used.
   */
  if((grace && !arg->reclaim) ||
     (!grace && arg->reclaim))
    {
      pres->res_nlm4share.stat = NLM4_DENIED_GRACE_PERIOD;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Share %s",
               lock_result_str(pres->res_nlm4share.stat));
      return NFS_REQ_OK;
    }

  rc = nlm_process_share_parms(preq,
                               &arg->share,
                               &pentry,
                               pcontext,
                               CARE_NO_MONITOR,
                               &nsm_client,
                               &nlm_client,
                               &nlm_owner);

  if(rc >= 0)
    {
      /* Present the error back to the client */
      pres->res_nlm4share.stat = (nlm4_stats)rc;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Share %s",
               lock_result_str(pres->res_nlm4share.stat));
      return NFS_REQ_OK;
    }

  if(state_nlm_share(pentry,
                     pcontext,
                     pexport,
                     arg->share.access,
                     arg->share.mode,
                     nlm_owner,
                     &state_status) != STATE_SUCCESS)
    {
      pres->res_nlm4share.stat = nlm_convert_state_error(state_status);
    }
  else
    {
      pres->res_nlm4share.stat = NLM4_GRANTED;
    }

  /* Release the NLM Client and NLM Owner references we have */
  dec_nsm_client_ref(nsm_client);
  dec_nlm_client_ref(nlm_client);
  dec_state_owner_ref(nlm_owner);
  cache_inode_put(pentry);

  LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Share %s",
           lock_result_str(pres->res_nlm4share.stat));
  return NFS_REQ_OK;
}
Beispiel #18
0
int nlm4_Lock(nfs_arg_t            * parg     /* IN     */ ,
              exportlist_t         * pexport  /* IN     */ ,
              fsal_op_context_t    * pcontext /* IN     */ ,
              cache_inode_client_t * pclient  /* INOUT  */ ,
              hash_table_t         * ht       /* INOUT  */ ,
              struct svc_req       * preq     /* IN     */ ,
              nfs_res_t            * pres     /* OUT    */ )
{
  nlm4_lockargs      * arg = &parg->arg_nlm4_lock;
  cache_entry_t      * pentry;
  state_status_t       state_status = CACHE_INODE_SUCCESS;
  char                 buffer[MAXNETOBJ_SZ * 2];
  state_nsm_client_t * nsm_client;
  state_nlm_client_t * nlm_client;
  state_owner_t      * nlm_owner, * holder;
  state_lock_desc_t    lock, conflict;
  int                  rc;
  state_block_data_t * pblock_data;

  netobj_to_string(&arg->cookie, buffer, 1024);
  LogDebug(COMPONENT_NLM,
           "REQUEST PROCESSING: Calling nlm4_Lock svid=%d off=%llx len=%llx cookie=%s",
           (int) arg->alock.svid,
           (unsigned long long) arg->alock.l_offset,
           (unsigned long long) arg->alock.l_len, buffer);

  if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie))
    {
      pres->res_nlm4.stat.stat = NLM4_FAILED;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  /* allow only reclaim lock request during recovery */
  if(in_nlm_grace_period() && !arg->reclaim)
    {
      pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  if(!in_nlm_grace_period() && arg->reclaim)
    {
      pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  rc = nlm_process_parameters(preq,
                              arg->exclusive,
                              &arg->alock,
                              &lock,
                              ht,
                              &pentry,
                              pcontext,
                              pclient,
                              CARE_MONITOR,
                              &nsm_client,
                              &nlm_client,
                              &nlm_owner,
                              &pblock_data);

  if(rc >= 0)
    {
      /* Present the error back to the client */
      pres->res_nlm4.stat.stat = (nlm4_stats)rc;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  /* Cast the state number into a state pointer to protect
   * locks from a client that has rebooted from the SM_NOTIFY
   * that will release old locks
   */
  if(state_lock(pentry,
                pcontext,
                nlm_owner,
                (void *) (ptrdiff_t) arg->state,
                arg->block,
                pblock_data,
                &lock,
                &holder,
                &conflict,
                pclient,
                &state_status) != STATE_SUCCESS)
    {
      pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status);

      if(state_status == STATE_LOCK_CONFLICT)
        {
          nlm_process_conflict(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder,
                               holder,
                               &conflict,
                               pclient);
        }

      /* If we didn't block, release the block data */
      if(state_status != STATE_LOCK_BLOCKED && pblock_data != NULL)
        Mem_Free(pblock_data);
    }
  else
    {
      pres->res_nlm4.stat.stat = NLM4_GRANTED;
    }

  /* Release the NLM Client and NLM Owner references we have */
  dec_nsm_client_ref(nsm_client);
  dec_nlm_client_ref(nlm_client);
  dec_state_owner_ref(nlm_owner, pclient);

  LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s",
           lock_result_str(pres->res_nlm4.stat.stat));
  return NFS_REQ_OK;
}
Beispiel #19
0
/**
 *
 * nlm4_send_grant_msg: Send NLMPROC4_GRANTED_MSG
 *
 * This runs in the nlm_asyn_thread context.
 */
static void nlm4_send_grant_msg(state_async_queue_t *arg)
{
  int                      retval;
  char                     buffer[1024];
  state_status_t           state_status = STATE_SUCCESS;
  state_cookie_entry_t   * cookie_entry;
  fsal_op_context_t        context, * pcontext = &context;
  state_nlm_async_data_t * nlm_arg = &arg->state_async_data.state_nlm_async_data;

  if(isDebug(COMPONENT_NLM))
    {
      netobj_to_string(&nlm_arg->nlm_async_args.nlm_async_grant.cookie,
                       buffer, sizeof(buffer));

      LogDebug(COMPONENT_NLM,
               "Sending GRANTED for arg=%p svid=%d start=%llx len=%llx cookie=%s",
               arg, nlm_arg->nlm_async_args.nlm_async_grant.alock.svid,
               (unsigned long long) nlm_arg->nlm_async_args.nlm_async_grant.alock.l_offset,
               (unsigned long long) nlm_arg->nlm_async_args.nlm_async_grant.alock.l_len,
               buffer);
    }

  retval = nlm_send_async(NLMPROC4_GRANTED_MSG,
                          nlm_arg->nlm_async_host,
                          &(nlm_arg->nlm_async_args.nlm_async_grant),
                          nlm_arg->nlm_async_key);

  dec_nlm_client_ref(nlm_arg->nlm_async_host);
  free_grant_arg(arg);

  /* If success, we are done. */
  if(retval == RPC_SUCCESS)
    return;

  /*
   * We are not able call granted callback. Some client may retry
   * the lock again. So remove the existing blocked nlm entry
   */
  LogMajor(COMPONENT_NLM,
           "GRANTED_MSG RPC call failed with return code %d. Removing the blocking lock",
           retval);

  if(state_find_grant(nlm_arg->nlm_async_args.nlm_async_grant.cookie.n_bytes,
                      nlm_arg->nlm_async_args.nlm_async_grant.cookie.n_len,
                      &cookie_entry,
                      &state_status) != STATE_SUCCESS)
    {
      /* This must be an old NLM_GRANTED_RES */
      LogFullDebug(COMPONENT_NLM,
                   "Could not find cookie=%s status=%s",
                   buffer, state_err_str(state_status));
      return;
    }

  PTHREAD_RWLOCK_WRLOCK(&cookie_entry->sce_pentry->state_lock);

  if(cookie_entry->sce_lock_entry->sle_block_data == NULL ||
     !nlm_block_data_to_fsal_context(cookie_entry->sce_lock_entry->sle_block_data,
                                     pcontext))
    {
      /* Wow, we're not doing well... */
      PTHREAD_RWLOCK_UNLOCK(&cookie_entry->sce_pentry->state_lock);
      LogFullDebug(COMPONENT_NLM,
                   "Could not find block data for cookie=%s (must be an old NLM_GRANTED_RES)",
                   buffer);
      return;
    }

  PTHREAD_RWLOCK_UNLOCK(&cookie_entry->sce_pentry->state_lock);

  if(state_release_grant(pcontext,
                         cookie_entry,
                         &state_status) != STATE_SUCCESS)
    {
      /* Huh? */
      LogFullDebug(COMPONENT_NLM,
                   "Could not release cookie=%s status=%s",
                   buffer, state_err_str(state_status));
    }
}
Beispiel #20
0
/**
 * @brief Get an NLM client
 *
 * @param[in] care        Care status
 * @param[in] xprt        RPC transport
 * @param[in] nsm_client  Related NSM client
 * @param[in] caller_name Caller name
 *
 * @return NLM client or NULL.
 */
state_nlm_client_t *get_nlm_client(care_t care, SVCXPRT *xprt,
				   state_nsm_client_t *nsm_client,
				   char *caller_name)
{
	state_nlm_client_t key;
	state_nlm_client_t *pclient;
	char str[LOG_BUFF_LEN];
	struct display_buffer dspbuf = {sizeof(str), str, str};
	struct hash_latch latch;
	hash_error_t rc;
	struct gsh_buffdesc buffkey;
	struct gsh_buffdesc buffval;
	struct sockaddr_storage local_addr;
	socklen_t addr_len;

	if (caller_name == NULL)
		return NULL;

	memset(&key, 0, sizeof(key));

	key.slc_nsm_client = nsm_client;
	key.slc_nlm_caller_name_len = strlen(caller_name);
	key.slc_client_type = svc_get_xprt_type(xprt);

	addr_len = sizeof(local_addr);
	if (getsockname(xprt->xp_fd, (struct sockaddr *)&local_addr, &addr_len)
	    == -1) {
		LogEvent(COMPONENT_CLIENTID, "Failed to get local addr.");
	} else {
		memcpy(&(key.slc_server_addr), &local_addr,
		       sizeof(struct sockaddr_storage));
	}

	if (key.slc_nlm_caller_name_len > LM_MAXSTRLEN)
		return NULL;

	key.slc_nlm_caller_name = caller_name;

	if (isFullDebug(COMPONENT_STATE)) {
		display_nlm_client(&dspbuf, &key);
		LogFullDebug(COMPONENT_STATE, "Find {%s}", str);
	}

	buffkey.addr = &key;
	buffkey.len = sizeof(key);

	rc = hashtable_getlatch(ht_nlm_client, &buffkey, &buffval, true,
				&latch);

	/* If we found it, return it */
	if (rc == HASHTABLE_SUCCESS) {
		pclient = buffval.addr;

		/* Return the found NLM Client */
		if (isFullDebug(COMPONENT_STATE)) {
			display_nlm_client(&dspbuf, pclient);
			LogFullDebug(COMPONENT_STATE, "Found {%s}", str);
		}

		/* Increment refcount under hash latch.
		 * This prevents dec ref from removing this entry from hash
		 * if a race occurs.
		 */
		inc_nlm_client_ref(pclient);

		hashtable_releaselatched(ht_nlm_client, &latch);

		if (care == CARE_MONITOR && !nsm_monitor(nsm_client)) {
			dec_nlm_client_ref(pclient);
			pclient = NULL;
		}

		return pclient;
	}

	/* An error occurred, return NULL */
	if (rc != HASHTABLE_ERROR_NO_SUCH_KEY) {
		display_nlm_client(&dspbuf, &key);

		LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}",
			hash_table_err_to_str(rc), str);

		return NULL;
	}

	/* Not found, but we don't care, return NULL */
	if (care == CARE_NOT) {
		/* Return the found NLM Client */
		if (isFullDebug(COMPONENT_STATE)) {
			display_nlm_client(&dspbuf, &key);
			LogFullDebug(COMPONENT_STATE, "Ignoring {%s}", str);
		}

		hashtable_releaselatched(ht_nlm_client, &latch);

		return NULL;
	}

	pclient = gsh_malloc(sizeof(*pclient));

	if (pclient == NULL) {
		display_nlm_client(&dspbuf, &key);
		LogCrit(COMPONENT_STATE, "No memory for {%s}", str);

		return NULL;
	}

	/* Copy everything over */
	memcpy(pclient, &key, sizeof(key));

	pclient->slc_nlm_caller_name = gsh_strdup(key.slc_nlm_caller_name);

	/* Take a reference to the NSM Client */
	inc_nsm_client_ref(nsm_client);

	if (pclient->slc_nlm_caller_name == NULL) {
		/* Discard the created client */
		free_nlm_client(pclient);
		return NULL;
	}

	pclient->slc_refcount = 1;

	if (isFullDebug(COMPONENT_STATE)) {
		display_nlm_client(&dspbuf, pclient);
		LogFullDebug(COMPONENT_STATE, "New {%s}", str);
	}

	buffkey.addr = pclient;
	buffkey.len = sizeof(*pclient);
	buffval.addr = pclient;
	buffval.len = sizeof(*pclient);

	rc = hashtable_setlatched(ht_nlm_client, &buffval, &buffval, &latch,
				  false, NULL, NULL);

	/* An error occurred, return NULL */
	if (rc != HASHTABLE_SUCCESS) {
		display_nlm_client(&dspbuf, pclient);

		LogCrit(COMPONENT_STATE, "Error %s, inserting {%s}",
			hash_table_err_to_str(rc), str);

		free_nlm_client(pclient);

		return NULL;
	}

	if (care != CARE_MONITOR || nsm_monitor(nsm_client))
		return pclient;

	/* Failed to monitor, release client reference
	 * and almost certainly remove it from the hash table.
	 */
	dec_nlm_client_ref(pclient);

	return NULL;
}
Beispiel #21
0
int nlm_process_share_parms(struct svc_req        * preq,
                            nlm4_share            * share,
                            cache_entry_t        ** ppentry,
                            fsal_op_context_t     * pcontext,
                            care_t                  care,
                            state_nsm_client_t   ** ppnsm_client,
                            state_nlm_client_t   ** ppnlm_client,
                            state_owner_t        ** ppowner)
{
  cache_inode_fsal_data_t fsal_data;
  fsal_attrib_list_t      attr;
  cache_inode_status_t    cache_status;
  SVCXPRT                *ptr_svc = preq->rq_xprt;
  int                     rc;

  *ppnsm_client = NULL;
  *ppnlm_client = NULL;
  *ppowner      = NULL;

  /* Convert file handle into a cache entry */
  if(share->fh.n_len > MAX_NETOBJ_SZ ||
     !nfs3_FhandleToFSAL((nfs_fh3 *) &share->fh, &fsal_data.fh_desc, pcontext))
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  /* Now get the cached inode attributes */
  *ppentry = cache_inode_get(&fsal_data,
                             &attr,
                             pcontext,
                             NULL,
                             &cache_status);

  if(*ppentry == NULL)
    {
      /* handle is not valid */
      return NLM4_STALE_FH;
    }

  *ppnsm_client = get_nsm_client(care, ptr_svc, share->caller_name);

  if(*ppnsm_client == NULL)
    {
      /* If NSM Client is not found, and we don't care (for unshare),
       * just return GRANTED (the unshare must succeed, there can't be
       * any shares).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, share->caller_name);

  if(*ppnlm_client == NULL)
    {
      /* If NLM Client is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      dec_nsm_client_ref(*ppnsm_client);

      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  *ppowner = get_nlm_owner(care, *ppnlm_client, &share->oh, 0);

  if(*ppowner == NULL)
    {
      LogDebug(COMPONENT_NLM,
               "Could not get NLM Owner");
      dec_nsm_client_ref(*ppnsm_client);
      dec_nlm_client_ref(*ppnlm_client);
      *ppnlm_client = NULL;

      /* If owner is not found, and we don't care (such as unlock),
       * just return GRANTED (the unlock must succeed, there can't be
       * any locks).
       */
      if(care != CARE_NOT)
        rc = NLM4_DENIED_NOLOCKS;
      else
        rc = NLM4_GRANTED;

      goto out_put;
    }

  LogFullDebug(COMPONENT_NLM,
               "Parameters Processed");

  return -1;

 out_put:

  cache_inode_put(*ppentry);
  *ppentry = NULL;
  return rc;
}
Beispiel #22
0
state_nlm_client_t *get_nlm_client(care_t               care,
                                   SVCXPRT            * xprt,
                                   state_nsm_client_t * pnsm_client,
                                   const char         * caller_name)
{
  state_nlm_client_t *pkey, *pclient;

  if(caller_name == NULL)
    return NULL;

  pkey = (state_nlm_client_t *)Mem_Alloc(sizeof(*pkey));
  if(pkey == NULL)
    return NULL;

  memset(pkey, 0, sizeof(*pkey));
  pkey->slc_refcount            = 1;
  pkey->slc_nsm_client          = pnsm_client;
  pkey->slc_nlm_caller_name_len = strlen(caller_name);
  pkey->slc_client_type         = get_xprt_type(xprt);

  if(pkey->slc_nlm_caller_name_len > LM_MAXSTRLEN)
    {
      /* Discard the key we created */
      Mem_Free(pkey);
      return NULL;
    }

  memcpy(pkey->slc_nlm_caller_name,
         caller_name,
         pkey->slc_nlm_caller_name_len);
  pkey->slc_nlm_caller_name[pkey->slc_nlm_caller_name_len] = '\0';
  
  if(isFullDebug(COMPONENT_STATE))
    {
      char str[HASHTABLE_DISPLAY_STRLEN];

      display_nlm_client(pkey, str);
      LogFullDebug(COMPONENT_STATE,
                   "Find NLM Client pkey {%s}", str);
    }

  /* If we found it, return it, if we don't care, return NULL */
  if(nlm_client_Get_Pointer(pkey, &pclient) == 1 || care == CARE_NOT)
    {
      /* Discard the key we created and return the found NLM Client */
      Mem_Free(pkey);

      if(isFullDebug(COMPONENT_STATE))
        {
          char str[HASHTABLE_DISPLAY_STRLEN];

          display_nlm_client(pclient, str);
          LogFullDebug(COMPONENT_STATE,
                       "Found NLM Client {%s}",
                       str);
        }

      if(care == CARE_MONITOR)
        if(!nsm_monitor(pnsm_client))
          {
            dec_nlm_client_ref(pclient);
            return NULL;
          }

      return pclient;
    }

  pclient = (state_nlm_client_t *)Mem_Alloc(sizeof(*pkey));
  if(pclient == NULL)
    {
      Mem_Free(pkey);
      return NULL;
    }

  /* Copy everything over */
  *pclient = *pkey;

  if(isFullDebug(COMPONENT_STATE))
    {
      char str[HASHTABLE_DISPLAY_STRLEN];

      display_nlm_client(pclient, str);
      LogFullDebug(COMPONENT_STATE,
                   "New NLM Client {%s}", str);
    }

  if(pthread_mutex_init(&pclient->slc_mutex, NULL) == -1)
    {
      /* Mutex initialization failed, free the key and created owner */
      Mem_Free(pkey);
      Mem_Free(pclient);
      return NULL;
    }

  /* Ref count the NSM Client as being used by this NLM Client */
  inc_nsm_client_ref(pnsm_client);

  if(nlm_client_Set(pkey, pclient) == 1)
    {
      if(isFullDebug(COMPONENT_STATE))
        {
          char str[HASHTABLE_DISPLAY_STRLEN];

          display_nlm_client(pclient, str);
          LogFullDebug(COMPONENT_STATE,
                       "Set NLM Client {%s}",
                       str);
        }

      if(care != CARE_MONITOR || nsm_monitor(pnsm_client))
        return pclient;

      dec_nlm_client_ref(pclient);
      return NULL;
    }

  dec_nsm_client_ref(pnsm_client);
  Mem_Free(pkey);
  Mem_Free(pclient);
  return NULL;
}
Beispiel #23
0
int nlm4_Unlock(nfs_arg_t * parg /* IN     */ ,
                exportlist_t * pexport /* IN     */ ,
                fsal_op_context_t * pcontext /* IN     */ ,
                cache_inode_client_t * pclient /* INOUT  */ ,
                hash_table_t * ht /* INOUT  */ ,
                struct svc_req *preq /* IN     */ ,
                nfs_res_t * pres /* OUT    */ )
{
  nlm4_unlockargs    * arg = &parg->arg_nlm4_unlock;
  cache_entry_t      * pentry;
  state_status_t       state_status = CACHE_INODE_SUCCESS;
  char                 buffer[MAXNETOBJ_SZ * 2];
  state_nsm_client_t * nsm_client;
  state_nlm_client_t * nlm_client;
  state_owner_t      * nlm_owner;
  state_lock_desc_t    lock;
  int                  rc;

  netobj_to_string(&arg->cookie, buffer, sizeof(buffer));
  LogDebug(COMPONENT_NLM,
           "REQUEST PROCESSING: Calling nlm4_Unlock svid=%d off=%llx len=%llx cookie=%s",
           (int) arg->alock.svid,
           (unsigned long long) arg->alock.l_offset,
           (unsigned long long) arg->alock.l_len,
           buffer);

  if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie))
    {
      pres->res_nlm4.stat.stat = NLM4_FAILED;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }


  if(in_nlm_grace_period())
    {
      pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  rc = nlm_process_parameters(preq,
                              FALSE, /* exlcusive doesn't matter */
                              &arg->alock,
                              &lock,
                              ht,
                              &pentry,
                              pcontext,
                              pclient,
                              CARE_NOT, /* unlock doesn't care if owner is found */
                              &nsm_client,
                              &nlm_client,
                              &nlm_owner,
                              NULL);

  if(rc >= 0)
    {
      /* Present the error back to the client */
      pres->res_nlm4.stat.stat = (nlm4_stats)rc;
      LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
               lock_result_str(pres->res_nlm4.stat.stat));
      return NFS_REQ_OK;
    }

  if(state_unlock(pentry,
                  pcontext,
                  nlm_owner,
                  NULL,
                  &lock,
                  pclient,
                  &state_status) != STATE_SUCCESS)
    {
      /* Unlock could fail in the FSAL and make a bit of a mess, especially if
       * we are in out of memory situation. Such an error is logged by
       * Cache Inode.
       */
      pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status);
    }
  else
    {
      pres->res_nlm4.stat.stat = NLM4_GRANTED;
    }

  /* Release the NLM Client and NLM Owner references we have */
  dec_nsm_client_ref(nsm_client);
  dec_nlm_client_ref(nlm_client);
  dec_state_owner_ref(nlm_owner, pclient);

  LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s",
           lock_result_str(pres->res_nlm4.stat.stat));
  return NFS_REQ_OK;
}
Beispiel #24
0
int nlm4_Share(nfs_arg_t *args, struct svc_req *req, nfs_res_t *res)
{
	nlm4_shareargs *arg = &args->arg_nlm4_share;
	struct fsal_obj_handle *obj;
	state_status_t state_status = STATE_SUCCESS;
	char buffer[MAXNETOBJ_SZ * 2];
	state_nsm_client_t *nsm_client;
	state_nlm_client_t *nlm_client;
	state_owner_t *nlm_owner;
	state_t *nlm_state;
	int rc;
	int grace = nfs_in_grace();
	/* Indicate if we let FSAL to handle requests during grace. */
	bool_t fsal_grace = false;

	/* NLM doesn't have a BADHANDLE error, nor can rpc_execute deal with
	 * responding to an NLM_*_MSG call, so we check here if the export is
	 * NULL and if so, handle the response.
	 */
	if (op_ctx->ctx_export == NULL) {
		res->res_nlm4share.stat = NLM4_STALE_FH;
		LogInfo(COMPONENT_NLM, "INVALID HANDLE: nlm4_Share");
		return NFS_REQ_OK;
	}

	res->res_nlm4share.sequence = 0;

	netobj_to_string(&arg->cookie, buffer, 1024);

	LogDebug(COMPONENT_NLM,
		 "REQUEST PROCESSING: Calling nlm4_Share cookie=%s reclaim=%s",
		 buffer,
		 arg->reclaim ? "yes" : "no");

	copy_netobj(&res->res_nlm4share.cookie, &arg->cookie);

	/* Allow only reclaim share request during recovery and visa versa.
	 * Note: NLM_SHARE is indicated to be non-monitored, however, it does
	 * have a reclaim flag, so we will honor the reclaim flag if used.
	 */
	if (grace) {
		if (op_ctx->fsal_export->exp_ops.
			fs_supports(op_ctx->fsal_export, fso_grace_method))
			fsal_grace = true;
		if (!fsal_grace && !arg->reclaim) {
			res->res_nlm4share.stat = NLM4_DENIED_GRACE_PERIOD;
			LogDebug(COMPONENT_NLM,
				 "REQUEST RESULT: nlm4_Share %s",
				 lock_result_str(res->res_nlm4share.stat));
			return NFS_REQ_OK;
		}
	} else if (arg->reclaim) {
			res->res_nlm4share.stat = NLM4_DENIED_GRACE_PERIOD;
			LogDebug(COMPONENT_NLM,
				 "REQUEST RESULT: nlm4_Share %s",
				 lock_result_str(res->res_nlm4share.stat));
			return NFS_REQ_OK;
	}

	rc = nlm_process_share_parms(req,
				     &arg->share,
				     op_ctx->fsal_export,
				     &obj,
				     CARE_NO_MONITOR,
				     &nsm_client,
				     &nlm_client,
				     &nlm_owner,
				     &nlm_state);

	if (rc >= 0) {
		/* Present the error back to the client */
		res->res_nlm4share.stat = (nlm4_stats) rc;
		LogDebug(COMPONENT_NLM,
			 "REQUEST RESULT: nlm4_Share %s",
			 lock_result_str(res->res_nlm4share.stat));
		return NFS_REQ_OK;
	}

	state_status = state_nlm_share(obj,
				       arg->share.access,
				       arg->share.mode,
				       nlm_owner,
				       nlm_state,
				       grace);

	if (state_status != STATE_SUCCESS) {
		res->res_nlm4share.stat =
		    nlm_convert_state_error(state_status);
	} else {
		res->res_nlm4share.stat = NLM4_GRANTED;
	}

	/* Release the NLM Client and NLM Owner references we have */
	dec_nsm_client_ref(nsm_client);
	dec_nlm_client_ref(nlm_client);
	dec_state_owner_ref(nlm_owner);
	obj->obj_ops.put_ref(obj);
	dec_nlm_state_ref(nlm_state);

	LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Share %s",
		 lock_result_str(res->res_nlm4share.stat));

	return NFS_REQ_OK;
}