Ejemplo n.º 1
0
/**
 *
 * clean_entry_dupreq: cleans an entry in the dupreq cache.
 *
 * cleans an entry in the dupreq cache.
 *
 * @param pentry [INOUT] entry to be cleaned.
 * @param addparam [IN] additional parameter used for cleaning.
 *
 * @return 0 if ok, other values mean an error.
 *
 */
int clean_entry_dupreq(LRU_entry_t * pentry, void *addparam)
{
  hash_buffer_t buffkey;
  struct prealloc_pool *dupreq_pool = (struct prealloc_pool *) addparam;
  dupreq_entry_t *pdupreq = (dupreq_entry_t *) (pentry->buffdata.pdata);
  dupreq_key_t dupkey;
  hash_table_t * ht_dupreq = NULL ;
  
  /* Get the socket address for the key */
  memcpy((char *)&dupkey.addr, (char *)&pdupreq->addr, sizeof(dupkey.addr));
  dupkey.xid = pdupreq->xid;
  dupkey.checksum = pdupreq->checksum;

  /* I have to keep an integer as key, I wil use the pointer buffkey->pdata for this,
   * this also means that buffkey->len will be 0 */
  buffkey.pdata = (caddr_t) &dupkey;
  buffkey.len = sizeof(dupreq_key_t);

  /* Get correct HT depending on proto used */
  if( pdupreq->ipproto == IPPROTO_TCP )
     ht_dupreq = ht_dupreq_tcp ;
  else
     ht_dupreq = ht_dupreq_udp ;

  LogDupReq("Garbage collection on", &pdupreq->addr, pdupreq->xid, pdupreq->rq_prog);

  return _remove_dupreq(ht_dupreq, &buffkey, pdupreq, dupreq_pool, NFS_REQ_OK);
}                               /* clean_entry_dupreq */
Ejemplo n.º 2
0
/**
 *
 * nfs_dupreq_get: Tries to get a duplicated requests for dupreq cache
 *
 * Tries to get a duplicated requests for dupreq cache.
 *
 * @param xid [IN] the transfer id we are looking for
 * @param pstatus [OUT] the pointer to the status for the operation
 *
 * @return the result previously set if *pstatus == DUPREQ_SUCCESS
 *
 */
nfs_res_t nfs_dupreq_get(long xid, struct svc_req *ptr_req, SVCXPRT *xprt, int *pstatus)
{
  hash_buffer_t buffkey;
  hash_buffer_t buffval;
  nfs_res_t res_nfs;
  dupreq_key_t dupkey;
  hash_table_t * ht_dupreq = NULL ;

  /* Get correct HT depending on proto used */
  ht_dupreq = get_ht_by_xprt( xprt ) ;
 

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

  /* Get the socket address for the key */
  if(copy_xprt_addr(&dupkey.addr, xprt) == 0)
    {
      *pstatus = DUPREQ_NOT_FOUND;
      return res_nfs;
    }

  dupkey.xid = xid;
  dupkey.checksum = 0;

  /* I have to keep an integer as key, I wil use the pointer buffkey->pdata for this,
   * this also means that buffkey->len will be 0 */
  buffkey.pdata = (caddr_t) &dupkey;
  buffkey.len = sizeof(dupreq_key_t);
  if(HashTable_Get(ht_dupreq, &buffkey, &buffval) == HASHTABLE_SUCCESS)
    {
      dupreq_entry_t *pdupreq = (dupreq_entry_t *)buffval.pdata;
      /* reset timestamp */
      pdupreq->timestamp = time(NULL);

      *pstatus = DUPREQ_SUCCESS;
      res_nfs = pdupreq->res_nfs;
      LogDupReq(" dupreq_get: Hit in the dupreq cache for", &pdupreq->addr,
		pdupreq->xid, pdupreq->rq_prog);
    }
  else
    {
      LogDupReq("Failed to get dupreq entry", &dupkey.addr, dupkey.xid, ptr_req->rq_prog);
      *pstatus = DUPREQ_NOT_FOUND;
    }
  return res_nfs;
}                               /* nfs_dupreq_get */
Ejemplo n.º 3
0
int nfs_dupreq_finish(long xid,
                      struct svc_req *ptr_req,
                      SVCXPRT *xprt,
                      nfs_res_t * p_res_nfs,
                      LRU_list_t * lru_dupreq)
{
  hash_buffer_t buffkey;
  hash_buffer_t buffval;
  LRU_entry_t *pentry = NULL;
  LRU_status_t lru_status;
  dupreq_key_t dupkey;
  dupreq_entry_t *pdupreq;
  hash_table_t * ht_dupreq = NULL ;

  /* Get correct HT depending on proto used */
  ht_dupreq = get_ht_by_xprt( xprt ) ;
 

  /* Get the socket address for the key */
  if(copy_xprt_addr(&dupkey.addr, xprt) == 0)
    return DUPREQ_NOT_FOUND;

  dupkey.xid = xid;
  dupkey.checksum = 0;

  /* I have to keep an integer as key, I wil use the pointer buffkey->pdata for this,
   * this also means that buffkey->len will be 0 */
  buffkey.pdata = (caddr_t) &dupkey;
  buffkey.len = sizeof(dupreq_key_t);
  if(HashTable_Get(ht_dupreq, &buffkey, &buffval) != HASHTABLE_SUCCESS)
    return DUPREQ_NOT_FOUND;

  pdupreq = (dupreq_entry_t *)buffval.pdata;

  LogDupReq("Finish", &pdupreq->addr, pdupreq->xid, pdupreq->rq_prog);

  P(pdupreq->dupreq_mutex);

  pdupreq->res_nfs = *p_res_nfs;
  pdupreq->timestamp = time(NULL);
  pdupreq->processing = 0;

  V(pdupreq->dupreq_mutex);

  /* Add it to lru list */
  if((pentry = LRU_new_entry(lru_dupreq, &lru_status)) == NULL)
    return DUPREQ_INSERT_MALLOC_ERROR;
  pentry->buffdata.pdata = buffval.pdata;
  pentry->buffdata.len = buffval.len;

  return DUPREQ_SUCCESS;
}                               /* nfs_dupreq_finish */
Ejemplo n.º 4
0
int nfs_dupreq_delete(long xid, struct svc_req *ptr_req, SVCXPRT *xprt,
                      struct prealloc_pool *dupreq_pool)
{
  int status;

  hash_buffer_t buffkey;
  hash_buffer_t buffval;
  dupreq_key_t dupkey;
  dupreq_entry_t *pdupreq;
  hash_table_t * ht_dupreq = NULL ;

  /* Get correct HT depending on proto used */
  ht_dupreq = get_ht_by_xprt( xprt ) ;
 
  /* Get the socket address for the key */
  if(copy_xprt_addr(&dupkey.addr, xprt) == 0)
    return DUPREQ_NOT_FOUND;

  dupkey.xid = xid;
  dupkey.checksum = 0;

  /* I have to keep an integer as key, I wil use the pointer buffkey->pdata for this,
   * this also means that buffkey->len will be 0 */
  buffkey.pdata = (caddr_t) &dupkey;
  buffkey.len = sizeof(dupreq_key_t);

  if(HashTable_Get(ht_dupreq, &buffkey, &buffval) == HASHTABLE_SUCCESS)
    {
      pdupreq = (dupreq_entry_t *) buffval.pdata;

      /* reset timestamp */
      pdupreq->timestamp = time(NULL);

      status = DUPREQ_SUCCESS;
    }
  else {
    return DUPREQ_NOT_FOUND;
  }

  LogDupReq("REMOVING", &pdupreq->addr, pdupreq->xid, pdupreq->rq_prog);

  status = _remove_dupreq( ht_dupreq, &buffkey, pdupreq, dupreq_pool, ! NFS_REQ_OK);
  return status;
}
Ejemplo n.º 5
0
int nfs_dupreq_add_not_finished(long xid,
                                struct svc_req *ptr_req,
                                SVCXPRT *xprt,
                                struct prealloc_pool *dupreq_pool,
                                nfs_res_t *res_nfs)
{
  hash_buffer_t buffkey;
  hash_buffer_t buffval;
  hash_buffer_t buffdata;
  dupreq_entry_t *pdupreq = NULL;
  int status = 0;
  dupreq_key_t *pdupkey = NULL;
  
  /* Entry to be cached */
  GetFromPool(pdupreq, dupreq_pool, dupreq_entry_t);
  if(pdupreq == NULL)
    return DUPREQ_INSERT_MALLOC_ERROR;

  if((pdupkey = (dupreq_key_t *) Mem_Alloc(sizeof(dupreq_key_t))) == NULL)
    {
      ReleaseToPool(pdupreq, dupreq_pool);
      return DUPREQ_INSERT_MALLOC_ERROR;
    }

  /* Get the socket address for the key and the request */
  if(copy_xprt_addr(&pdupkey->addr, xprt) == 0 ||
     copy_xprt_addr(&pdupreq->addr, xprt) == 0)
    {
      Mem_Free(pdupkey);
      ReleaseToPool(pdupreq, dupreq_pool);
      return DUPREQ_INSERT_MALLOC_ERROR;
    }

  pdupkey->xid = xid;
  pdupreq->xid = xid;

  /* Checksum the request */
  pdupkey->checksum = 0;
  pdupreq->checksum = 0;

  /* I have to keep an integer as key, I wil use the pointer buffkey->pdata for this,
   * this also means that buffkey->len will be 0 */
  buffkey.pdata = (caddr_t) pdupkey;
  buffkey.len = sizeof(dupreq_key_t);

  /* I build the data with the request pointer that should be in state 'IN USE' */
  pdupreq->rq_prog = ptr_req->rq_prog;
  pdupreq->rq_vers = ptr_req->rq_vers;
  pdupreq->rq_proc = ptr_req->rq_proc;
  pdupreq->timestamp = time(NULL);
  pdupreq->processing = 1;
  buffdata.pdata = (caddr_t) pdupreq;
  buffdata.len = sizeof(dupreq_entry_t);

  LogDupReq("Add Not Finished", &pdupreq->addr, pdupreq->xid, pdupreq->rq_prog);

  status = HashTable_Test_And_Set(ht_dupreq, &buffkey, &buffdata,
                                  HASHTABLE_SET_HOW_SET_NO_OVERWRITE);

  if (status == HASHTABLE_ERROR_KEY_ALREADY_EXISTS)
    {
      if(HashTable_Get(ht_dupreq, &buffkey, &buffval) == HASHTABLE_SUCCESS)
        {
          P(((dupreq_entry_t *)buffval.pdata)->dupreq_mutex);
          if ( ((dupreq_entry_t *)buffval.pdata)->processing == 1)
            {
              V(((dupreq_entry_t *)buffval.pdata)->dupreq_mutex);
              status = DUPREQ_BEING_PROCESSED;
            }
          else
            {
              *res_nfs = ((dupreq_entry_t *) buffval.pdata)->res_nfs;
              V(((dupreq_entry_t *)buffval.pdata)->dupreq_mutex);
              status = DUPREQ_ALREADY_EXISTS;
            }
        }
      else
        status = DUPREQ_NOT_FOUND;
    }
  else if (status == HASHTABLE_INSERT_MALLOC_ERROR)
      status = DUPREQ_INSERT_MALLOC_ERROR;
  else
    status = DUPREQ_SUCCESS;
  if (status != DUPREQ_SUCCESS)
    ReleaseToPool(pdupreq, dupreq_pool);
  return status;
}                               /* nfs_dupreq_add_not_finished */