76 lines
3.0 KiB
C
76 lines
3.0 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2009 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 "gdsroot.h"
|
|
#include "gtm_facility.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsbt.h"
|
|
#include "gdsfhead.h"
|
|
#include "dbfilop.h"
|
|
#include "gdsblk.h"
|
|
#include "gds_blk_downgrade.h"
|
|
#include "mupint.h"
|
|
|
|
GBLREF sm_uc_ptr_t reformat_buffer;
|
|
GBLREF int reformat_buffer_len;
|
|
GBLREF volatile int reformat_buffer_in_use; /* used only in DEBUG mode */
|
|
GBLREF unsigned char *mu_int_locals;
|
|
GBLREF int4 mu_int_ovrhd;
|
|
GBLREF sgmnt_data mu_int_data;
|
|
GBLREF gd_region *gv_cur_region;
|
|
GBLREF volatile int4 fast_lock_count;
|
|
|
|
void mu_int_write(block_id blk, uchar_ptr_t ptr)
|
|
{
|
|
file_control *fc;
|
|
|
|
assert(0 == fast_lock_count);
|
|
++fast_lock_count; /* No interrupts across this use of reformat_buffer */
|
|
/* reformat_buffer_in_use should always be incremented only AFTER incrementing fast_lock_count
|
|
* as it is the latter that prevents interrupts from using the reformat buffer. Similarly
|
|
* the decrement of fast_lock_count should be done AFTER decrementing reformat_buffer_in_use.
|
|
*/
|
|
assert(0 == reformat_buffer_in_use);
|
|
DEBUG_ONLY(reformat_buffer_in_use++;)
|
|
if (IS_GDS_BLK_DOWNGRADE_NEEDED(mu_int_data.desired_db_format))
|
|
{
|
|
if (reformat_buffer_len < mu_int_data.blk_size)
|
|
{
|
|
if (reformat_buffer)
|
|
free(reformat_buffer);
|
|
reformat_buffer = malloc(mu_int_data.blk_size);
|
|
reformat_buffer_len = mu_int_data.blk_size;
|
|
}
|
|
gds_blk_downgrade((v15_blk_hdr_ptr_t)reformat_buffer, (blk_hdr_ptr_t)ptr);
|
|
ptr = reformat_buffer;
|
|
}
|
|
fc = gv_cur_region->dyn.addr->file_cntl;
|
|
fc->op = FC_WRITE;
|
|
fc->op_buff = ptr;
|
|
/* Previously, fc->op_len was set to mu_int_data.blk_size. Although only the transaction number in the block header is
|
|
* going to be reset, we were writing the entire buffer (mu_int_data.blk_size). This demanded a encryption
|
|
* of the buffer before being written to the disk. To avoid an encryption, we are only going to write the block header
|
|
* in the desired offset(op_pos). Note that since mu_int_write is called just after an mu_int_read, the block previously
|
|
* read will be in the OS cache and hence won't cause performance issues due to unaligned writes. When the database is
|
|
* not fully upgraded from V4 to V5, we will be writing the entrie block size. This is due to the block upgrades between
|
|
* V4 and V5 that can happen in the unencrypted versions of the database. */
|
|
fc->op_len = UNIX_ONLY(mu_int_data.fully_upgraded ? SIZEOF(blk_hdr) : ) mu_int_data.blk_size;
|
|
fc->op_pos = mu_int_ovrhd + (mu_int_data.blk_size / DISK_BLOCK_SIZE * blk);
|
|
dbfilop(fc);
|
|
DEBUG_ONLY(reformat_buffer_in_use--;)
|
|
assert(0 == reformat_buffer_in_use);
|
|
--fast_lock_count;
|
|
assert(0 == fast_lock_count);
|
|
return;
|
|
}
|