Esempio n. 1
0
int
dbs_file_extend (dbe_storage_t * dbs, extent_t ** new_ext_ret, int is_in_sys_em)
{
  extent_map_t * em;
  	  extent_t * new_ext = NULL;
  int n, n_allocated = 0;
  int32 em_n_free;
  dp_addr_t ext_first = dbs->dbs_n_pages;
  ASSERT_IN_DBS (dbs);
  if (dbf_no_disk)
    return 0;
  if (dbs->dbs_disks)
    {
      n = dbs_seg_extend (dbs, EXTENT_SZ);
      if (n != EXTENT_SZ)
	return 0;
    }
  else
    {
      mutex_enter (dbs->dbs_file_mtx);
      n = fd_extend (dbs, dbs->dbs_fd, EXTENT_SZ);
      mutex_leave (dbs->dbs_file_mtx);
      if (EXTENT_SZ != n)
	return 0;
      dbs->dbs_file_length += PAGE_SZ * EXTENT_SZ;
      dbs->dbs_n_pages+= EXTENT_SZ;
      dbs->dbs_n_free_pages+= EXTENT_SZ;
    }
  wi_storage_offsets ();
  em = dbs->dbs_extent_map;
  if (!em)
    {
      return n;
    }
  if (!is_in_sys_em)
    mutex_enter (em->em_mtx);

  if (dbs_check_extent_free_pages)
    {
      em_n_free = em_free_count (em, EXT_INDEX);
      if (em->em_n_free_pages != em_n_free)
	{
	  log_error ("The %s free pages incorrect %d != %d actually free", em->em_name, em->em_n_free_pages, em_n_free);
	  em->em_n_free_pages = em_n_free;
	}
    }

  if (em->em_n_free_pages < 16)
    {
      /* extending and the system extent has little space.  Make this ext a system index ext.  If allocating some other ext, retry and take the next ext for that.  */
      int fill;
      buffer_desc_t * last;
      last = page_set_last (em->em_buf);
      fill = LONG_REF (last->bd_buffer + DP_BLOB_LEN);
      if (fill + sizeof (extent_t) > PAGE_DATA_SZ)
	{
	  dp_addr_t em_dp = ext_first + n_allocated;
	  n_allocated++;
	  last = page_set_extend (dbs, &em->em_buf, em_dp, DPF_EXTENT_MAP);
	  LONG_SET (last->bd_buffer + DP_BLOB_LEN, sizeof (extent_t));
	  new_ext = (extent_t *) (last->bd_buffer + DP_DATA);
	}
      else
	{
	  new_ext = (extent_t*) (last->bd_buffer + fill + DP_DATA);
	  LONG_SET (last->bd_buffer + DP_BLOB_LEN, fill + sizeof (extent_t));
	}
      em->em_n_pages += EXTENT_SZ;
      em->em_n_free_pages += EXTENT_SZ;
      new_ext->ext_flags = EXT_INDEX;
      new_ext->ext_dp = ext_first;
      if (gethash (DP_ADDR2VOID (new_ext->ext_dp), dbs->dbs_dp_to_extent_map))
	GPF_T1 ("ext for new dp range already exists in dbs");
      sethash (DP_ADDR2VOID (new_ext->ext_dp), em->em_dp_to_ext, (void*)new_ext);
      sethash (DP_ADDR2VOID (new_ext->ext_dp), dbs->dbs_dp_to_extent_map, (void*)em);
      new_ext->ext_prev = EXT_EXTENDS_NONE;
      if (n_allocated)
	{
	  new_ext->ext_pages[0] = 1;
	  em->em_n_free_pages--;
	}
    }
  /* there is a guarantee of at least 16 pages in the dbs sys extent map */
  if (dbs->dbs_n_pages > dbs->dbs_n_pages_in_sets)
    {
      /* add a page of global free set and backup set */
      buffer_desc_t * last = page_set_extend (dbs, &dbs->dbs_free_set, 0, DPF_FREE_SET);
      page_set_checksum_init (last->bd_buffer + DP_DATA);
      if (n_allocated)
	dbs_page_allocated (dbs, ext_first);
      last->bd_page = last->bd_physical_page = em_try_get_dp (em, EXT_INDEX, DP_ANY);
      if (!last->bd_page) GPF_T1 ("0 dp for page set page");
      EM_DEC_FREE (em, EXT_INDEX);

      last = page_set_extend (dbs, &dbs->dbs_incbackup_set, 0, DPF_INCBACKUP_SET);
      page_set_checksum_init (last->bd_buffer + DP_DATA);
      last->bd_page = last->bd_physical_page = em_try_get_dp (em, EXT_INDEX, DP_ANY);
      if (!last->bd_page) GPF_T1 ("0 dp for page set page");
      EM_DEC_FREE (em, EXT_INDEX);
      dbs->dbs_n_pages_in_sets += BITS_ON_PAGE;
    }
  if (dbs->dbs_n_pages > dbs->dbs_n_pages_in_extent_set)
    {
      buffer_desc_t * last = page_set_extend (dbs, &dbs->dbs_extent_set, 0, DPF_EXTENT_SET);
      last->bd_page = last->bd_physical_page = em_try_get_dp (em, EXT_INDEX, DP_ANY);
      if (!last->bd_page) GPF_T1 ("0 dp for extents alloc page");
      EM_DEC_FREE (em, EXT_INDEX);
      LONG_SET (last->bd_buffer + DP_DATA, 1); /* the newly made ext is the 1st of this page of the ext set, so set the bm 1st bit to 1 */
      page_set_checksum_init (last->bd_buffer + DP_DATA);
      dbs->dbs_n_pages_in_extent_set += EXTENT_SZ * BITS_ON_PAGE;
    }
  if (new_ext)
    {
      dbs_extent_allocated (dbs, ext_first);
    }
  *new_ext_ret = new_ext;
  if (!is_in_sys_em)
    mutex_leave (em->em_mtx);
  return n;
}
Esempio n. 2
0
int
DBGP_NAME (page_wait_access) (DBGP_PARAMS it_cursor_t * itc, dp_addr_t dp,  buffer_desc_t * buf_from,
    buffer_desc_t ** buf_ret, int mode, int max_change)
{
  buffer_desc_t decoy;
  buffer_desc_t *buf;
  dp_addr_t phys_dp;
  itc->itc_to_reset = RWG_NO_WAIT;
  itc->itc_max_transit_change = max_change;
  itc->itc_must_kill_trx = 0;
  if (!dp)
    GPF_T1 ("Zero DP in page_fault_map_sem");

  if (buf_from)
    {
      ITC_IN_TRANSIT (itc, dp, buf_from->bd_page);
    }
  else
    ASSERT_IN_MAP (itc->itc_tree, dp);

  buf = IT_DP_TO_BUF (itc->itc_tree, dp);
  if (!buf)
    {
      ra_req_t * ra = NULL;
      IT_DP_REMAP (itc->itc_tree, dp, phys_dp);
#ifdef MTX_DEBUG
      em_check_dp (itc->itc_tree->it_extent_map, phys_dp);
      if (phys_dp != dp)
	em_check_dp (itc->itc_tree->it_extent_map, dp);
#endif
      if ((DP_DELETED == phys_dp || dbs_is_free_page (itc->itc_tree->it_storage, phys_dp))
	  && !strchr (wi_inst.wi_open_mode, 'a'))
	{
	  log_error ("Reference to page with free remap dp = %ld, remap = %ld",
		     (long) phys_dp, (long) dp);
	  if (0 && DBS_PAGE_IN_RANGE (itc->itc_tree->it_storage, phys_dp))
	    dbs_page_allocated (itc->itc_tree->it_storage, phys_dp);
	  else
	    {
	      *buf_ret = PF_OF_DELETED;
	      itc->itc_must_kill_trx = 1;
	      itc->itc_to_reset = RWG_WAIT_ANY;
	      ITC_LEAVE_MAPS (itc);
	      return RWG_WAIT_ANY;
	    }
	}
      memset (&decoy, 0, sizeof (buffer_desc_t));
      decoy.bd_being_read = 1;
      if (PA_READ == mode)
	decoy.bd_readers = 1;
      else
	BD_SET_IS_WRITE (&decoy, 1);
      sethash (DP_ADDR2VOID (dp), &IT_DP_MAP (itc->itc_tree, dp)->itm_dp_to_buf, (void*)&decoy);
      ITC_LEAVE_MAPS (itc);
      buf = bp_get_buffer (NULL, BP_BUF_REQUIRED);
      is_read_pending++;
      buf->bd_being_read = 1;
      buf->bd_page = dp;
      buf->bd_storage = itc->itc_tree->it_storage;
      buf->bd_physical_page = phys_dp;
      BD_SET_IS_WRITE (buf, 0);
      buf->bd_write_waiting = NULL;
      if (buf_from && !itc->itc_landed)
	ra = itc_read_aside (itc, buf_from, dp);
      itc->itc_n_reads++;
      ITC_MARK_READ (itc);
      buf->bd_tree = itc->itc_tree;
      buf_disk_read (buf);
      is_read_pending--;
      if (ra)
	itc_read_ahead_blob (itc, ra, RAB_SPECULATIVE);

      if (buf_from)
	{
	  ITC_IN_TRANSIT (itc, dp, buf_from->bd_page)
	    }
	  else