fis-gtm/sr_port/backup_block.c

100 lines
3.6 KiB
C

/****************************************************************
* *
* Copyright 2001, 2010 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "gtm_stdio.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "gdsblk.h"
#include "shmpool.h"
#include "memcoherency.h"
#include "mupipbckup.h"
GBLREF uint4 process_id;
boolean_t backup_block(sgmnt_addrs *csa, block_id blk, cache_rec_ptr_t backup_cr, sm_uc_ptr_t backup_blk_p)
{
uint4 bsiz;
int4 required;
shmpool_buff_hdr_ptr_t sbufh_p;
shmpool_blk_hdr_ptr_t sblkh_p;
boolean_t ret = TRUE, is_bg;
sgmnt_data_ptr_t csd;
sm_uc_ptr_t bkp_src_blk;
csd = csa->hdr;
is_bg = (dba_bg == csd->acc_meth);
assert(is_bg || (dba_mm == csd->acc_meth));
/* Should have EITHER backup cr (BG mode) or buffer pointer (MM mode) */
assert((is_bg && (NULL != backup_cr) && (NULL == backup_blk_p)) ||
(!is_bg && (NULL == backup_cr) && (NULL != backup_blk_p)));
if (is_bg)
{ /* Get buffer address from the cache record */
VMS_ONLY(assert(0 == backup_cr->shmpool_blk_off));
assert(backup_cr->in_cw_set);/* ensure the buffer has been pinned (from preemption in db_csh_getn) */
backup_blk_p = GDS_ANY_REL2ABS(csa, backup_cr->buffaddr);
}
bsiz = ((blk_hdr_ptr_t)(backup_blk_p))->bsiz;
sbufh_p = csa->shmpool_buffer;
assert(bsiz <= sbufh_p->blk_size);
/* Obtain block from shared memory pool. If we can't get the block, then backup will be effectively terminated. */
sblkh_p = shmpool_blk_alloc(csa->region, SHMBLK_BACKUP);
if (((shmpool_blk_hdr_ptr_t)-1L) == sblkh_p)
return FALSE; /* Backup died for whatever reason. Backup failure already dealt with in shmpool_blk_alloc() */
/* Fill the block we have been assigned in before marking it valid */
sblkh_p->blkid = blk;
if (is_bg)
{
assert(NULL != backup_cr);
sblkh_p->use.bkup.ondsk_blkver = backup_cr->ondsk_blkver;
assert(((blk_hdr_ptr_t)backup_blk_p)->bsiz >= SIZEOF(blk_hdr));
} else /* For MM version, no dynamic conversions take place so just record block as we know it is */
sblkh_p->use.bkup.ondsk_blkver = csd->desired_db_format;
bkp_src_blk = backup_blk_p;
# ifdef GTM_CRYPT
/* If the database is encrypted, the old_block will be in the encrypted twin buffer. Fetch it from the encrypted
* twin counter part and write that to the backup buffer instead.
*/
if (csd->is_encrypted)
{
DBG_ENSURE_PTR_IS_VALID_GLOBUFF(csa, csd, backup_blk_p);
bkp_src_blk = GDS_ANY_ENCRYPTGLOBUF(backup_blk_p, csa);
DBG_ENSURE_PTR_IS_VALID_ENCTWINGLOBUFF(csa, csd, bkp_src_blk);
}
# endif
/* Adjust bsiz to be within database block size range. Asserts above will ensure this IS the case for DBG. */
if (bsiz < SIZEOF(blk_hdr))
bsiz = SIZEOF(blk_hdr);
else if (bsiz > sbufh_p->blk_size)
bsiz = sbufh_p->blk_size;
/* Copy block information to data portion of shmpool block just following header */
memcpy((sblkh_p + 1), bkp_src_blk, bsiz);
/* Need a write coherency fence here as we want to make sure the above info is stored and
* reflected to other processors before we mark the block valid.
*/
SHM_WRITE_MEMORY_BARRIER;
sblkh_p->valid_data = TRUE;
/* And another write barrier to advertise its cleanliness to other processors */
SHM_WRITE_MEMORY_BARRIER;
return TRUE;
}