예제 #1
0
static int unload_fsal(struct fsal_module *fsal_hdl)
{
	int retval = EBUSY;	/* someone still has a reference */

	pthread_mutex_lock(&fsal_lock);
	pthread_mutex_lock(&fsal_hdl->lock);
	if (fsal_hdl->refs != 0 || !glist_empty(&fsal_hdl->exports))
		goto err;
	if (fsal_hdl->dl_handle == NULL) {
		retval = EACCES;	/* cannot unload static linked fsals */
		goto err;
	}
	glist_del(&fsal_hdl->fsals);
	pthread_mutex_unlock(&fsal_hdl->lock);
	pthread_mutex_destroy(&fsal_hdl->lock);
	fsal_hdl->refs = 0;

	retval = dlclose(fsal_hdl->dl_handle);
	pthread_mutex_unlock(&fsal_lock);
	return retval;

 err:
	pthread_mutex_unlock(&fsal_hdl->lock);
	pthread_mutex_unlock(&fsal_lock);
	return retval;
}
예제 #2
0
int32_t dec_session_ref(nfs41_session_t *session)
{
    int i;
    int32_t refcnt = atomic_dec_int32_t(&session->refcount);

    if (refcnt == 0) {

        /* Unlink the session from the client's list of
           sessions */
        PTHREAD_MUTEX_lock(&session->clientid_record->cid_mutex);
        glist_del(&session->session_link);
        PTHREAD_MUTEX_unlock(&session->clientid_record->cid_mutex);

        /* Decrement our reference to the clientid record */
        dec_client_id_ref(session->clientid_record);
        /* Destroy this session's mutexes and condition variable */

        for (i = 0; i < NFS41_NB_SLOTS; i++)
            PTHREAD_MUTEX_destroy(&session->slots[i].lock);

        PTHREAD_COND_destroy(&session->cb_cond);
        PTHREAD_MUTEX_destroy(&session->cb_mutex);

        /* Destroy the session's back channel (if any) */
        if (session->flags & session_bc_up)
            nfs_rpc_destroy_chan(&session->cb_chan);

        /* Free the memory for the session */
        pool_free(nfs41_session_pool, session);
    }

    return refcnt;
}
예제 #3
0
fsal_status_t  schedule_fsal_up_event_process(fsal_up_event_t *arg)
{
  int rc;
  fsal_status_t ret = {0, 0};

  /* Events which needs quick response, and locking events wich
     has its own queue gets processed here, rest will be queued. */
  if (arg->event_type == FSAL_UP_EVENT_LOCK_GRANT ||
      arg->event_type == FSAL_UP_EVENT_LOCK_AVAIL)
    {
      arg->event_process_func(&arg->event_data);

      gsh_free(arg->event_data.event_context.fsal_data.fh_desc.start);
      pool_free(fsal_up_event_pool, arg);
      return ret;
    }

  if(arg->event_type == FSAL_UP_EVENT_INVALIDATE)
    {
      arg->event_process_func(&arg->event_data);
      /* Step2 where we perform close; which could be expensive operation
         so deffer it to the separate thread. */
      arg->event_process_func = dumb_fsal_up_invalidate_step2;
    }
  if(arg->event_type == FSAL_UP_EVENT_UPDATE)
  {

   /* Invalidate first without scheduling */
    arg->event_process_func(&arg->event_data);

    if ((arg->event_data.type.update.upu_flags & FSAL_UP_NLINK) &&
        (arg->event_data.type.update.upu_stat_buf.st_nlink == 0) )
    {
      /* upu_flags must be set or st_nlink is unreliable. */
      /* Step2 where we perform close; which could be expensive operation
         so defer it to the separate thread. */
      arg->event_process_func = dumb_fsal_up_invalidate_step2;
    } else
            return ret;
  }

  /* Now queue them for further process. */
  LogFullDebug(COMPONENT_FSAL_UP, "Schedule %p", arg);

  P(fsal_up_process_tcb.tcb_mutex);
  glist_add_tail(&fsal_up_process_queue, &arg->event_list);
  rc = pthread_cond_signal(&fsal_up_process_tcb.tcb_condvar);
  LogFullDebug(COMPONENT_FSAL_UP,"Signaling tcb_condvar");
  if (rc == -1)
    {
      LogDebug(COMPONENT_FSAL_UP,
                   "Unable to signal FSAL_UP Process Thread");
      glist_del(&arg->event_list);
      ret.major = ERR_FSAL_FAULT;
    }
  V(fsal_up_process_tcb.tcb_mutex);
  return ret;
}
예제 #4
0
void free_nfs4_owner(state_owner_t * owner)
{
  if(owner->so_owner.so_nfs4_owner.so_related_owner != NULL)
    dec_state_owner_ref(owner->so_owner.so_nfs4_owner.so_related_owner);

  /* Release the saved response. */
  nfs4_Compound_FreeOne(&owner->so_owner.so_nfs4_owner.so_resp);

  /* Remove the owner from the owners per clientid list. */
  P(owner->so_owner.so_nfs4_owner.so_clientrec->cid_mutex);

  glist_del(&owner->so_owner.so_nfs4_owner.so_perclient);

  V(owner->so_owner.so_nfs4_owner.so_clientrec->cid_mutex);

  dec_client_id_ref(owner->so_owner.so_nfs4_owner.so_clientrec);
}
예제 #5
0
void free_nfs4_owner(state_owner_t *owner)
{
	state_nfs4_owner_t *nfs4_owner = &owner->so_owner.so_nfs4_owner;

	if (nfs4_owner->so_related_owner != NULL)
		dec_state_owner_ref(nfs4_owner->so_related_owner);

	/* Release the saved response. */
	nfs4_Compound_FreeOne(&nfs4_owner->so_resp);

	/* Remove the owner from the owners per clientid list. */
	PTHREAD_MUTEX_lock(&nfs4_owner->so_clientrec->cid_mutex);

	glist_del(&nfs4_owner->so_perclient);

	PTHREAD_MUTEX_unlock(&nfs4_owner->so_clientrec->cid_mutex);

	dec_client_id_ref(nfs4_owner->so_clientrec);
}
예제 #6
0
fsal_status_t GPFSFSAL_CleanUpExportContext(fsal_export_context_t * export_context) 
{
  gpfsfsal_export_context_t *p_export_context = (gpfsfsal_export_context_t *)export_context;

  if(export_context == NULL) 
  {
    LogCrit(COMPONENT_FSAL,
            "NULL mandatory argument passed to %s()", __FUNCTION__);
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_CleanUpExportContext);
  }

  if(p_export_context->mount_root_fd != 0)
    close(p_export_context->mount_root_fd);

  if(p_export_context->fe_fsal_up_ctx != NULL)
    {
      /* Start to clean up FSAL_UP stuff. There is actually more to do here...*/
      glist_del(&p_export_context->fe_list);
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_CleanUpExportContext);
}
예제 #7
0
void remove_nfs4_owner(state_owner_t        * powner,
                       const char           * str)
{
  hash_buffer_t           buffkey, old_key, old_value;
  state_nfs4_owner_name_t oname;
  int                     rc;

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

  oname.son_clientid  = powner->so_owner.so_nfs4_owner.so_clientid;
  oname.son_owner_len = powner->so_owner_len;
  oname.son_islock    = powner->so_type == STATE_LOCK_OWNER_NFSV4;
  memcpy(oname.son_owner_val, powner->so_owner_val, powner->so_owner_len);

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

  rc = HashTable_DelRef(ht_nfs4_owner,
                        &buffkey,
                        &old_key,
                        &old_value,
                        Hash_dec_state_owner_ref);

  switch(rc)
    {
      case HASHTABLE_SUCCESS:
        if(powner->so_type == STATE_LOCK_OWNER_NFSV4 &&
           powner->so_owner.so_nfs4_owner.so_related_owner != NULL)
          dec_state_owner_ref(powner->so_owner.so_nfs4_owner.so_related_owner);

        /* Release the owner_name (key) and owner (data) back to appropriate pools */
        LogFullDebug(COMPONENT_STATE, "Free %s", str);

        nfs4_Compound_FreeOne(&powner->so_owner.so_nfs4_owner.so_resp);

        P(powner->so_owner.so_nfs4_owner.so_pclientid->cid_mutex);

        glist_del(&powner->so_owner.so_nfs4_owner.so_perclient);

        V(powner->so_owner.so_nfs4_owner.so_pclientid->cid_mutex);

        dec_client_id_ref(powner->so_owner.so_nfs4_owner.so_pclientid);

        pool_free(state_owner_pool, old_value.pdata);
        pool_free(state_nfs4_owner_name_pool, old_key.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 (%s) for %s",
                  hash_table_err_to_str(rc), str);
        break;
    }
}
예제 #8
0
/* This thread processes FSAL UP events. */
void *fsal_up_process_thread(void *UnUsedArg)
{
  struct timeval             now;
  struct timespec            timeout;
  fsal_up_event_t          * fupevent;
  int                        rc;

  SetNameFunction("fsal_up_process_thread");

  if (mark_thread_existing(&fsal_up_process_tcb) == PAUSE_EXIT)
    {
      /* Oops, that didn't last long... exit. */
      mark_thread_done(&fsal_up_process_tcb);
      LogDebug(COMPONENT_INIT,
               "FSAL_UP Process Thread: Exiting before initialization");
      return NULL;
    }

  LogFullDebug(COMPONENT_INIT,
               "FSAL_UP Process Thread: my pthread id is %p",
               (caddr_t) pthread_self());

  while(1)
    {
      /* Check without tcb lock*/
      if ((fsal_up_process_tcb.tcb_state != STATE_AWAKE) ||
          glist_empty(&fsal_up_process_queue))
        {
          while(1)
            {
              P(fsal_up_process_tcb.tcb_mutex);
              if ((fsal_up_process_tcb.tcb_state == STATE_AWAKE) &&
                  !glist_empty(&fsal_up_process_queue))
                {
                  V(fsal_up_process_tcb.tcb_mutex);
                  break;
                }
              switch(thread_sm_locked(&fsal_up_process_tcb))
                {
                  case THREAD_SM_RECHECK:
                  V(fsal_up_process_tcb.tcb_mutex);
                  continue;

                  case THREAD_SM_BREAK:
                  if (glist_empty(&fsal_up_process_queue))
                    {
                      gettimeofday(&now, NULL);
                      timeout.tv_sec = 10 + now.tv_sec;
                      timeout.tv_nsec = 0;
                      rc = pthread_cond_timedwait(&fsal_up_process_tcb.tcb_condvar,
                                                  &fsal_up_process_tcb.tcb_mutex,
                                                  &timeout);
                    }
                  V(fsal_up_process_tcb.tcb_mutex);
                  continue;

                  case THREAD_SM_EXIT:
                  V(fsal_up_process_tcb.tcb_mutex);
                  return NULL;
                }
             }
          }
        P(fsal_up_process_tcb.tcb_mutex);
        fupevent = glist_first_entry(&fsal_up_process_queue,
                                     fsal_up_event_t,
                                     event_list);
        if(fupevent != NULL)
          {
            /* Pull the event off of the list */
            glist_del(&fupevent->event_list);

            /* Release the mutex */
            V(fsal_up_process_tcb.tcb_mutex);
            fupevent->event_process_func(&fupevent->event_data);
            gsh_free(fupevent->event_data.event_context.fsal_data.fh_desc.start);
            pool_free(fsal_up_event_pool, fupevent);

            continue;
          }
        V(fsal_up_process_tcb.tcb_mutex);
    }
  tcb_remove(&fsal_up_process_tcb);
}