mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:43:04 +01:00
1) Fixed the layering, as dbb_lock shouldn't belong to PIO.
2) Passed tdbb to some engine routines that were dealing with TLS. 3) Got rid of fil_length and some minor cleanup.
This commit is contained in:
parent
cd10fbee3b
commit
609f466ad3
@ -400,7 +400,7 @@ int DatabaseSnapshot::blockingAst(void* ast_object)
|
|||||||
DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
||||||
: snapshot(pool), idMap(pool), idCounter(0)
|
: snapshot(pool), idMap(pool), idCounter(0)
|
||||||
{
|
{
|
||||||
PAG_header(true);
|
PAG_header(tdbb, true);
|
||||||
|
|
||||||
Database* const dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
fb_assert(dbb);
|
fb_assert(dbb);
|
||||||
|
@ -475,7 +475,7 @@ int INF_database_info(const SCHAR* items,
|
|||||||
case isc_info_forced_writes:
|
case isc_info_forced_writes:
|
||||||
if (!header_refreshed)
|
if (!header_refreshed)
|
||||||
{
|
{
|
||||||
PAG_header(true);
|
PAG_header(tdbb, true);
|
||||||
header_refreshed = true;
|
header_refreshed = true;
|
||||||
}
|
}
|
||||||
*p++ = (dbb->dbb_flags & DBB_force_write) ? 1 : 0;
|
*p++ = (dbb->dbb_flags & DBB_force_write) ? 1 : 0;
|
||||||
@ -737,7 +737,7 @@ int INF_database_info(const SCHAR* items,
|
|||||||
case isc_info_oldest_transaction:
|
case isc_info_oldest_transaction:
|
||||||
if (!header_refreshed)
|
if (!header_refreshed)
|
||||||
{
|
{
|
||||||
PAG_header(true);
|
PAG_header(tdbb, true);
|
||||||
header_refreshed = true;
|
header_refreshed = true;
|
||||||
}
|
}
|
||||||
length = INF_convert(dbb->dbb_oldest_transaction, buffer);
|
length = INF_convert(dbb->dbb_oldest_transaction, buffer);
|
||||||
@ -746,7 +746,7 @@ int INF_database_info(const SCHAR* items,
|
|||||||
case isc_info_oldest_active:
|
case isc_info_oldest_active:
|
||||||
if (!header_refreshed)
|
if (!header_refreshed)
|
||||||
{
|
{
|
||||||
PAG_header(true);
|
PAG_header(tdbb, true);
|
||||||
header_refreshed = true;
|
header_refreshed = true;
|
||||||
}
|
}
|
||||||
length = INF_convert(dbb->dbb_oldest_active, buffer);
|
length = INF_convert(dbb->dbb_oldest_active, buffer);
|
||||||
@ -755,7 +755,7 @@ int INF_database_info(const SCHAR* items,
|
|||||||
case isc_info_oldest_snapshot:
|
case isc_info_oldest_snapshot:
|
||||||
if (!header_refreshed)
|
if (!header_refreshed)
|
||||||
{
|
{
|
||||||
PAG_header(true);
|
PAG_header(tdbb, true);
|
||||||
header_refreshed = true;
|
header_refreshed = true;
|
||||||
}
|
}
|
||||||
length = INF_convert(dbb->dbb_oldest_snapshot, buffer);
|
length = INF_convert(dbb->dbb_oldest_snapshot, buffer);
|
||||||
@ -764,7 +764,7 @@ int INF_database_info(const SCHAR* items,
|
|||||||
case isc_info_next_transaction:
|
case isc_info_next_transaction:
|
||||||
if (!header_refreshed)
|
if (!header_refreshed)
|
||||||
{
|
{
|
||||||
PAG_header(true);
|
PAG_header(tdbb, true);
|
||||||
header_refreshed = true;
|
header_refreshed = true;
|
||||||
}
|
}
|
||||||
length = INF_convert(dbb->dbb_next_transaction, buffer);
|
length = INF_convert(dbb->dbb_next_transaction, buffer);
|
||||||
|
@ -537,7 +537,7 @@ USHORT INI_get_trig_flags(const TEXT* trig_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void INI_init()
|
void INI_init(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -552,8 +552,8 @@ void INI_init()
|
|||||||
* format descriptor.
|
* format descriptor.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
CHECK_DBB(dbb);
|
CHECK_DBB(dbb);
|
||||||
|
|
||||||
const int* fld;
|
const int* fld;
|
||||||
@ -614,7 +614,7 @@ void INI_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void INI_init2()
|
void INI_init2(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -628,8 +628,8 @@ void INI_init2()
|
|||||||
* the database when it was created.
|
* the database when it was created.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
const USHORT major_version = dbb->dbb_ods_version;
|
const USHORT major_version = dbb->dbb_ods_version;
|
||||||
const USHORT minor_original = dbb->dbb_minor_original;
|
const USHORT minor_original = dbb->dbb_minor_original;
|
||||||
|
@ -30,8 +30,8 @@ namespace Jrd {
|
|||||||
|
|
||||||
void INI_format(const TEXT*, const TEXT*);
|
void INI_format(const TEXT*, const TEXT*);
|
||||||
USHORT INI_get_trig_flags(const TEXT*);
|
USHORT INI_get_trig_flags(const TEXT*);
|
||||||
void INI_init();
|
void INI_init(Jrd::thread_db*);
|
||||||
void INI_init2();
|
void INI_init2(Jrd::thread_db*);
|
||||||
|
|
||||||
#endif // JRD_INI_PROTO_H
|
#endif // JRD_INI_PROTO_H
|
||||||
|
|
||||||
|
211
src/jrd/jrd.cpp
211
src/jrd/jrd.cpp
@ -450,7 +450,7 @@ static void commit(thread_db*, jrd_tra*, const bool);
|
|||||||
static bool drop_files(const jrd_file*);
|
static bool drop_files(const jrd_file*);
|
||||||
static void find_intl_charset(thread_db*, Attachment*, const DatabaseOptions*);
|
static void find_intl_charset(thread_db*, Attachment*, const DatabaseOptions*);
|
||||||
static jrd_tra* find_transaction(thread_db*, ISC_STATUS);
|
static jrd_tra* find_transaction(thread_db*, ISC_STATUS);
|
||||||
static void init_database_locks(thread_db*, Database*);
|
static void init_database_locks(thread_db*);
|
||||||
static ISC_STATUS handle_error(ISC_STATUS*, ISC_STATUS);
|
static ISC_STATUS handle_error(ISC_STATUS*, ISC_STATUS);
|
||||||
static void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction);
|
static void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction);
|
||||||
static void verify_request_synchronization(jrd_req*& request, SSHORT level);
|
static void verify_request_synchronization(jrd_req*& request, SSHORT level);
|
||||||
@ -770,8 +770,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
ERR_post(isc_no_priv,
|
ERR_post(isc_no_priv,
|
||||||
isc_arg_string, "direct",
|
isc_arg_string, "direct",
|
||||||
isc_arg_string, "security database",
|
isc_arg_string, "security database",
|
||||||
isc_arg_string,
|
isc_arg_string, ERR_string(file_name),
|
||||||
ERR_string(file_name),
|
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,8 +787,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
ERR_post(isc_no_priv,
|
ERR_post(isc_no_priv,
|
||||||
isc_arg_string, "encryption",
|
isc_arg_string, "encryption",
|
||||||
isc_arg_string, "database",
|
isc_arg_string, "database",
|
||||||
isc_arg_string,
|
isc_arg_string, ERR_string(file_name),
|
||||||
ERR_string(file_name),
|
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,14 +871,19 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
LCK_init(tdbb, LCK_OWNER_database);
|
LCK_init(tdbb, LCK_OWNER_database);
|
||||||
dbb->dbb_flags |= DBB_lck_init_done;
|
dbb->dbb_flags |= DBB_lck_init_done;
|
||||||
|
|
||||||
INI_init();
|
INI_init(tdbb);
|
||||||
|
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
|
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
|
||||||
|
|
||||||
|
// Initialize locks
|
||||||
|
init_database_locks(tdbb);
|
||||||
|
|
||||||
SHUT_init(tdbb);
|
SHUT_init(tdbb);
|
||||||
PAG_header_init();
|
PAG_header_init(tdbb);
|
||||||
INI_init2();
|
INI_init2(tdbb);
|
||||||
PAG_init();
|
PAG_init(tdbb);
|
||||||
|
|
||||||
if (options.dpb_set_page_buffers) {
|
if (options.dpb_set_page_buffers) {
|
||||||
#ifdef SUPERSERVER
|
#ifdef SUPERSERVER
|
||||||
// Here we do not let anyone except SYSDBA (like DBO) to change dbb_page_buffers,
|
// Here we do not let anyone except SYSDBA (like DBO) to change dbb_page_buffers,
|
||||||
@ -890,17 +893,15 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
#endif
|
#endif
|
||||||
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
||||||
}
|
}
|
||||||
CCH_init(tdbb, options.dpb_buffers);
|
|
||||||
|
|
||||||
// Initialize locks
|
CCH_init(tdbb, options.dpb_buffers);
|
||||||
init_database_locks(tdbb, dbb);
|
|
||||||
|
|
||||||
// Initialize backup difference subsystem. This must be done before WAL and shadowing
|
// Initialize backup difference subsystem. This must be done before WAL and shadowing
|
||||||
// is enabled because nbackup it is a lower level subsystem
|
// is enabled because nbackup it is a lower level subsystem
|
||||||
dbb->dbb_backup_manager = FB_NEW(*dbb->dbb_permanent) BackupManager(tdbb, dbb, nbak_state_unknown);
|
dbb->dbb_backup_manager = FB_NEW(*dbb->dbb_permanent) BackupManager(tdbb, dbb, nbak_state_unknown);
|
||||||
|
|
||||||
PAG_init2(0);
|
PAG_init2(tdbb, 0);
|
||||||
PAG_header(false);
|
PAG_header(tdbb, false);
|
||||||
|
|
||||||
// initialize shadowing as soon as the database is ready for it
|
// initialize shadowing as soon as the database is ready for it
|
||||||
// but before any real work is done
|
// but before any real work is done
|
||||||
@ -921,9 +922,9 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.dpb_disable_wal) {
|
if (options.dpb_disable_wal) {
|
||||||
ERR_post(isc_lock_timeout, isc_arg_gds, isc_obj_in_use,
|
ERR_post(isc_lock_timeout,
|
||||||
isc_arg_string,
|
isc_arg_gds, isc_obj_in_use,
|
||||||
ERR_string(file_name),
|
isc_arg_string, ERR_string(file_name),
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,7 +944,8 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
ERR_post(isc_inv_client_dialect_specified, isc_arg_number,
|
ERR_post(isc_inv_client_dialect_specified, isc_arg_number,
|
||||||
options.dpb_sql_dialect,
|
options.dpb_sql_dialect,
|
||||||
isc_arg_gds, isc_valid_client_dialects,
|
isc_arg_gds, isc_valid_client_dialects,
|
||||||
isc_arg_string, "1, 2 or 3", isc_arg_end);
|
isc_arg_string, "1, 2 or 3",
|
||||||
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId.usr_sql_role_name.hasData())
|
if (userId.usr_sql_role_name.hasData())
|
||||||
@ -1083,16 +1085,14 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
CCH_exclusive_attachment(tdbb, LCK_none, LCK_WAIT);
|
CCH_exclusive_attachment(tdbb, LCK_none, LCK_WAIT);
|
||||||
if (attachment->att_flags & ATT_shutdown) {
|
if (attachment->att_flags & ATT_shutdown) {
|
||||||
if (dbb->dbb_ast_flags & DBB_shutdown) {
|
if (dbb->dbb_ast_flags & DBB_shutdown) {
|
||||||
ERR_post(isc_shutdown, isc_arg_string,
|
ERR_post(isc_shutdown, isc_arg_string, ERR_string(file_name), isc_arg_end);
|
||||||
ERR_string(file_name), isc_arg_end);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ERR_post(isc_att_shutdown);
|
ERR_post(isc_att_shutdown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!attachment_succeeded) {
|
if (!attachment_succeeded) {
|
||||||
ERR_post(isc_shutdown, isc_arg_string,
|
ERR_post(isc_shutdown, isc_arg_string, ERR_string(file_name), isc_arg_end);
|
||||||
ERR_string(file_name), isc_arg_end);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1101,8 +1101,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
|
|
||||||
if (dbb->dbb_ast_flags & (DBB_shut_attach | DBB_shut_tran))
|
if (dbb->dbb_ast_flags & (DBB_shut_attach | DBB_shut_tran))
|
||||||
{
|
{
|
||||||
ERR_post(isc_shutinprog, isc_arg_string,
|
ERR_post(isc_shutinprog, isc_arg_string, ERR_string(file_name), isc_arg_end);
|
||||||
ERR_string(file_name), isc_arg_end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbb->dbb_ast_flags & DBB_shutdown) {
|
if (dbb->dbb_ast_flags & DBB_shutdown) {
|
||||||
@ -1126,8 +1125,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
}
|
}
|
||||||
if (!allow_access) {
|
if (!allow_access) {
|
||||||
// Note we throw exception here when entering full-shutdown mode
|
// Note we throw exception here when entering full-shutdown mode
|
||||||
ERR_post(isc_shutdown, isc_arg_string,
|
ERR_post(isc_shutdown, isc_arg_string, ERR_string(file_name), isc_arg_end);
|
||||||
ERR_string(file_name), isc_arg_end);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1152,9 +1150,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.dpb_journal.hasData()) {
|
if (options.dpb_journal.hasData()) {
|
||||||
ERR_post(isc_bad_dpb_content,
|
ERR_post(isc_bad_dpb_content, isc_arg_gds, isc_cant_start_journal, isc_arg_end);
|
||||||
isc_arg_gds, isc_cant_start_journal,
|
|
||||||
isc_arg_end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.dpb_wal_action)
|
if (options.dpb_wal_action)
|
||||||
@ -1223,9 +1219,9 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
if (options.dpb_set_db_readonly) {
|
if (options.dpb_set_db_readonly) {
|
||||||
validateAccess(attachment);
|
validateAccess(attachment);
|
||||||
if (!CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD)) {
|
if (!CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD)) {
|
||||||
ERR_post(isc_lock_timeout, isc_arg_gds, isc_obj_in_use,
|
ERR_post(isc_lock_timeout,
|
||||||
isc_arg_string,
|
isc_arg_gds, isc_obj_in_use,
|
||||||
ERR_string(file_name),
|
isc_arg_string, ERR_string(file_name),
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
PAG_set_db_readonly(dbb, options.dpb_db_readonly);
|
PAG_set_db_readonly(dbb, options.dpb_db_readonly);
|
||||||
@ -1792,10 +1788,12 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
dbb->dbb_flags |= DBB_DB_SQL_dialect_3;
|
dbb->dbb_flags |= DBB_DB_SQL_dialect_3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR_post(isc_database_create_failed, isc_arg_string,
|
ERR_post(isc_database_create_failed,
|
||||||
expanded_name.c_str(), isc_arg_gds, isc_inv_dialect_specified,
|
isc_arg_string, ERR_string(expanded_name),
|
||||||
isc_arg_number, options.dpb_sql_dialect, isc_arg_gds,
|
isc_arg_gds, isc_inv_dialect_specified,
|
||||||
isc_valid_db_dialects, isc_arg_string, "1 and 3", isc_arg_end);
|
isc_arg_number, options.dpb_sql_dialect,
|
||||||
|
isc_arg_gds, isc_valid_db_dialects,
|
||||||
|
isc_arg_string, "1 and 3", isc_arg_end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1826,8 +1824,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
LCK_init(tdbb, LCK_OWNER_database);
|
LCK_init(tdbb, LCK_OWNER_database);
|
||||||
dbb->dbb_flags |= DBB_lck_init_done;
|
dbb->dbb_flags |= DBB_lck_init_done;
|
||||||
|
|
||||||
INI_init();
|
INI_init(tdbb);
|
||||||
PAG_init();
|
PAG_init(tdbb);
|
||||||
initing_security = true;
|
initing_security = true;
|
||||||
|
|
||||||
SCL_init(true, userId, tdbb);
|
SCL_init(true, userId, tdbb);
|
||||||
@ -1866,39 +1864,39 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
if (allow_overwrite)
|
if (allow_overwrite)
|
||||||
{
|
{
|
||||||
// file is a database and the user (SYSDBA or owner) has right to overwrite
|
// file is a database and the user (SYSDBA or owner) has right to overwrite
|
||||||
pageSpace->file =
|
pageSpace->file = PIO_create(dbb, expanded_name, options.dpb_overwrite, false, false);
|
||||||
PIO_create(dbb, expanded_name, options.dpb_overwrite, false, false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR_post(isc_no_priv,
|
ERR_post(isc_no_priv,
|
||||||
isc_arg_string, "overwrite",
|
isc_arg_string, "overwrite",
|
||||||
isc_arg_string, "database",
|
isc_arg_string, "database",
|
||||||
isc_arg_string,
|
isc_arg_string, ERR_string(expanded_name),
|
||||||
ERR_cstring(expanded_name.c_str()), isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
const jrd_file* first_dbb_file = pageSpace->file;
|
const jrd_file* const first_dbb_file = pageSpace->file;
|
||||||
|
|
||||||
|
// Initialize locks
|
||||||
|
init_database_locks(tdbb);
|
||||||
|
|
||||||
if (options.dpb_set_page_buffers)
|
if (options.dpb_set_page_buffers)
|
||||||
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
||||||
CCH_init(tdbb, options.dpb_buffers);
|
|
||||||
|
|
||||||
// Initialize locks
|
CCH_init(tdbb, options.dpb_buffers);
|
||||||
init_database_locks(tdbb, dbb);
|
|
||||||
|
|
||||||
// Initialize backup difference subsystem. This must be done before WAL and shadowing
|
// Initialize backup difference subsystem. This must be done before WAL and shadowing
|
||||||
// is enabled because nbackup it is a lower level subsystem
|
// is enabled because nbackup it is a lower level subsystem
|
||||||
dbb->dbb_backup_manager = FB_NEW(*dbb->dbb_permanent) BackupManager(tdbb, dbb, nbak_state_normal);
|
dbb->dbb_backup_manager = FB_NEW(*dbb->dbb_permanent) BackupManager(tdbb, dbb, nbak_state_normal);
|
||||||
|
|
||||||
dbb->dbb_backup_manager->dbCreating = true;
|
dbb->dbb_backup_manager->dbCreating = true;
|
||||||
PAG_format_header();
|
PAG_format_header(tdbb);
|
||||||
INI_init2();
|
INI_init2(tdbb);
|
||||||
PAG_format_log();
|
PAG_format_log(tdbb);
|
||||||
PAG_format_pip(tdbb, *pageSpace);
|
PAG_format_pip(tdbb, *pageSpace);
|
||||||
|
|
||||||
if (options.dpb_set_page_buffers)
|
if (options.dpb_set_page_buffers)
|
||||||
@ -1922,8 +1920,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
ERR_post(isc_no_priv,
|
ERR_post(isc_no_priv,
|
||||||
isc_arg_string, "shutdown or online",
|
isc_arg_string, "shutdown or online",
|
||||||
isc_arg_string, "database",
|
isc_arg_string, "database",
|
||||||
isc_arg_string,
|
isc_arg_string, ERR_string(file_name),
|
||||||
ERR_string(file_name), isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1946,12 +1944,12 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
|
|
||||||
if (options.dpb_set_db_readonly) {
|
if (options.dpb_set_db_readonly) {
|
||||||
if (!CCH_exclusive (tdbb, LCK_EX, WAIT_PERIOD))
|
if (!CCH_exclusive (tdbb, LCK_EX, WAIT_PERIOD))
|
||||||
ERR_post (isc_lock_timeout, isc_arg_gds, isc_obj_in_use,
|
ERR_post(isc_lock_timeout,
|
||||||
isc_arg_string,
|
isc_arg_gds, isc_obj_in_use,
|
||||||
ERR_string (file_name),
|
isc_arg_string, ERR_string(file_name),
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
|
|
||||||
PAG_set_db_readonly (dbb, options.dpb_db_readonly);
|
PAG_set_db_readonly(dbb, options.dpb_db_readonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
PAG_attachment_id(tdbb);
|
PAG_attachment_id(tdbb);
|
||||||
@ -1963,8 +1961,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
find_intl_charset(tdbb, attachment, &options);
|
find_intl_charset(tdbb, attachment, &options);
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
dbb->dbb_filename.assign(first_dbb_file->fil_string,
|
dbb->dbb_filename.assign(first_dbb_file->fil_string);
|
||||||
first_dbb_file->fil_length);
|
|
||||||
#else
|
#else
|
||||||
dbb->dbb_filename = expanded_name;
|
dbb->dbb_filename = expanded_name;
|
||||||
#endif
|
#endif
|
||||||
@ -2166,17 +2163,18 @@ ISC_STATUS GDS_DROP_DATABASE(ISC_STATUS* user_status, Attachment** handle)
|
|||||||
ERR_post(isc_no_priv,
|
ERR_post(isc_no_priv,
|
||||||
isc_arg_string, "drop",
|
isc_arg_string, "drop",
|
||||||
isc_arg_string, "database",
|
isc_arg_string, "database",
|
||||||
isc_arg_string, ERR_cstring(file_name), isc_arg_end);
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachment->att_flags & ATT_shutdown)
|
if (attachment->att_flags & ATT_shutdown)
|
||||||
{
|
{
|
||||||
if (dbb->dbb_ast_flags & DBB_shutdown)
|
if (dbb->dbb_ast_flags & DBB_shutdown)
|
||||||
{
|
{
|
||||||
ERR_post(isc_shutdown, isc_arg_string,
|
ERR_post(isc_shutdown, isc_arg_string, ERR_cstring(file_name), isc_arg_end);
|
||||||
ERR_cstring(file_name), isc_arg_end);
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ERR_post(isc_att_shutdown, isc_arg_end);
|
ERR_post(isc_att_shutdown, isc_arg_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2185,14 +2183,17 @@ ISC_STATUS GDS_DROP_DATABASE(ISC_STATUS* user_status, Attachment** handle)
|
|||||||
{
|
{
|
||||||
ERR_post(isc_lock_timeout,
|
ERR_post(isc_lock_timeout,
|
||||||
isc_arg_gds, isc_obj_in_use,
|
isc_arg_gds, isc_obj_in_use,
|
||||||
isc_arg_string, ERR_cstring(file_name), isc_arg_end);
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if same process has more attachments
|
// Check if same process has more attachments
|
||||||
|
|
||||||
if (dbb->dbb_attachments && dbb->dbb_attachments->att_next) {
|
if (dbb->dbb_attachments && dbb->dbb_attachments->att_next) {
|
||||||
ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use,
|
ERR_post(isc_no_meta_update,
|
||||||
isc_arg_string, "DATABASE", isc_arg_end);
|
isc_arg_gds, isc_obj_in_use,
|
||||||
|
isc_arg_string, "DATABASE",
|
||||||
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forced release of all transactions
|
// Forced release of all transactions
|
||||||
@ -3838,8 +3839,7 @@ bool JRD_reschedule(thread_db* tdbb, SLONG quantum, bool punt)
|
|||||||
const PathName& file_name = attachment->att_filename;
|
const PathName& file_name = attachment->att_filename;
|
||||||
if (punt) {
|
if (punt) {
|
||||||
CCH_unwind(tdbb, false);
|
CCH_unwind(tdbb, false);
|
||||||
ERR_post(isc_shutdown, isc_arg_string,
|
ERR_post(isc_shutdown, isc_arg_string, ERR_cstring(file_name), isc_arg_end);
|
||||||
ERR_cstring(file_name), isc_arg_end);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||||
@ -4204,9 +4204,9 @@ static void find_intl_charset(thread_db* tdbb, Attachment* attachment, const Dat
|
|||||||
{
|
{
|
||||||
// Report an error - we can't do what user has requested
|
// Report an error - we can't do what user has requested
|
||||||
ERR_post(isc_bad_dpb_content,
|
ERR_post(isc_bad_dpb_content,
|
||||||
isc_arg_gds, isc_charset_not_found,
|
isc_arg_gds, isc_charset_not_found,
|
||||||
isc_arg_string, ERR_cstring(options->dpb_lc_ctype),
|
isc_arg_string, ERR_cstring(options->dpb_lc_ctype),
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4390,7 +4390,8 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
|||||||
// Just in case there WAS a customer using this unsupported
|
// Just in case there WAS a customer using this unsupported
|
||||||
// feature - post an error when they try to access it in 4.0
|
// feature - post an error when they try to access it in 4.0
|
||||||
ERR_post(isc_uns_ext, isc_arg_gds, isc_random,
|
ERR_post(isc_uns_ext, isc_arg_gds, isc_random,
|
||||||
isc_arg_string, "Encryption not supported", isc_arg_end);
|
isc_arg_string, "Encryption not supported",
|
||||||
|
isc_arg_end);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4650,8 +4651,10 @@ static Database* init(thread_db* tdbb,
|
|||||||
if (attach_flag)
|
if (attach_flag)
|
||||||
return dbb;
|
return dbb;
|
||||||
|
|
||||||
ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use,
|
ERR_post(isc_no_meta_update,
|
||||||
isc_arg_string, "DATABASE", isc_arg_end);
|
isc_arg_gds, isc_obj_in_use,
|
||||||
|
isc_arg_string, "DATABASE",
|
||||||
|
isc_arg_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4730,7 +4733,7 @@ static Database* init(thread_db* tdbb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void init_database_locks(thread_db* tdbb, Database* dbb)
|
static void init_database_locks(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -4739,16 +4742,63 @@ static void init_database_locks(thread_db* tdbb, Database* dbb)
|
|||||||
**************************************
|
**************************************
|
||||||
*
|
*
|
||||||
* Functional description
|
* Functional description
|
||||||
* Initialize secondary database locks.
|
* Initialize database locks.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
fb_assert(dbb);
|
// Main database lock
|
||||||
|
|
||||||
|
PageSpace* const pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
|
fb_assert(pageSpace && pageSpace->file);
|
||||||
|
|
||||||
|
UCharBuffer file_id;
|
||||||
|
PIO_get_unique_file_id(pageSpace->file, file_id);
|
||||||
|
size_t key_length = file_id.getCount();
|
||||||
|
|
||||||
|
Lock* lock = FB_NEW_RPT(*dbb->dbb_permanent, key_length) Lock;
|
||||||
|
dbb->dbb_lock = lock;
|
||||||
|
lock->lck_type = LCK_database;
|
||||||
|
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
|
||||||
|
lock->lck_object = dbb;
|
||||||
|
lock->lck_length = key_length;
|
||||||
|
lock->lck_dbb = dbb;
|
||||||
|
lock->lck_ast = CCH_down_grade_dbb;
|
||||||
|
memcpy(lock->lck_key.lck_string, file_id.begin(), key_length);
|
||||||
|
|
||||||
|
// Try to get an exclusive lock on database.
|
||||||
|
// If this fails, insist on at least a shared lock.
|
||||||
|
|
||||||
|
dbb->dbb_flags |= DBB_exclusive;
|
||||||
|
if (!LCK_lock(tdbb, lock, LCK_EX, LCK_NO_WAIT))
|
||||||
|
{
|
||||||
|
dbb->dbb_flags &= ~DBB_exclusive;
|
||||||
|
|
||||||
|
while (!LCK_lock(tdbb, lock, LCK_SW, -1))
|
||||||
|
{
|
||||||
|
tdbb->tdbb_status_vector[0] = 0; // Clean status vector from lock manager error code
|
||||||
|
|
||||||
|
// If we are in a single-threaded maintenance mode then clean up and stop waiting
|
||||||
|
SCHAR spare_memory[MIN_PAGE_SIZE * 2];
|
||||||
|
SCHAR* header_page_buffer = (SCHAR*) FB_ALIGN((IPTR) spare_memory, MIN_PAGE_SIZE);
|
||||||
|
Ods::header_page* header_page = reinterpret_cast<Ods::header_page*>(header_page_buffer);
|
||||||
|
|
||||||
|
PIO_header(dbb, header_page_buffer, MIN_PAGE_SIZE);
|
||||||
|
|
||||||
|
if ((header_page->hdr_flags & Ods::hdr_shutdown_mask) == Ods::hdr_shutdown_single)
|
||||||
|
{
|
||||||
|
ERR_post(isc_shutdown,
|
||||||
|
isc_arg_string, ERR_cstring(pageSpace->file->fil_string),
|
||||||
|
isc_arg_end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lock shared by all dbb owners, used to signal other processes
|
// Lock shared by all dbb owners, used to signal other processes
|
||||||
// to dump their monitoring data and synchronize operations
|
// to dump their monitoring data and synchronize operations
|
||||||
Lock* lock = FB_NEW_RPT(*dbb->dbb_permanent, sizeof(SLONG)) Lock();
|
|
||||||
|
lock = FB_NEW_RPT(*dbb->dbb_permanent, sizeof(SLONG)) Lock();
|
||||||
dbb->dbb_monitor_lock = lock;
|
dbb->dbb_monitor_lock = lock;
|
||||||
lock->lck_type = LCK_monitor;
|
lock->lck_type = LCK_monitor;
|
||||||
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
|
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
|
||||||
@ -4760,7 +4810,8 @@ static void init_database_locks(thread_db* tdbb, Database* dbb)
|
|||||||
LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT);
|
LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT);
|
||||||
|
|
||||||
// Lock that identifies a dbb instance
|
// Lock that identifies a dbb instance
|
||||||
const size_t key_length = sizeof(FB_GUID);
|
|
||||||
|
key_length = sizeof(FB_GUID);
|
||||||
lock = FB_NEW_RPT(*dbb->dbb_permanent, key_length) Lock();
|
lock = FB_NEW_RPT(*dbb->dbb_permanent, key_length) Lock();
|
||||||
dbb->dbb_instance_lock = lock;
|
dbb->dbb_instance_lock = lock;
|
||||||
lock->lck_type = LCK_instance;
|
lock->lck_type = LCK_instance;
|
||||||
|
@ -50,7 +50,6 @@ public:
|
|||||||
//int *fil_trace; /* Trace file, if any */
|
//int *fil_trace; /* Trace file, if any */
|
||||||
Firebird::Mutex fil_mutex;
|
Firebird::Mutex fil_mutex;
|
||||||
USHORT fil_flags;
|
USHORT fil_flags;
|
||||||
USHORT fil_length; /* Length of expanded file name */
|
|
||||||
SCHAR fil_string[1]; /* Expanded file name */
|
SCHAR fil_string[1]; /* Expanded file name */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,7 +83,6 @@ public:
|
|||||||
void* fil_io_events[MAX_FILE_IO]; /* Overlapped I/O events */
|
void* fil_io_events[MAX_FILE_IO]; /* Overlapped I/O events */
|
||||||
#endif
|
#endif
|
||||||
USHORT fil_flags;
|
USHORT fil_flags;
|
||||||
USHORT fil_length; /* Length of expanded file name */
|
|
||||||
SCHAR fil_string[1]; /* Expanded file name */
|
SCHAR fil_string[1]; /* Expanded file name */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ void PIO_extend(Jrd::Database*, Jrd::jrd_file*, const ULONG, const USHORT);
|
|||||||
void PIO_flush(Jrd::Database*, Jrd::jrd_file*);
|
void PIO_flush(Jrd::Database*, Jrd::jrd_file*);
|
||||||
void PIO_force_write(Jrd::jrd_file*, const bool, const bool);
|
void PIO_force_write(Jrd::jrd_file*, const bool, const bool);
|
||||||
ULONG PIO_get_number_of_pages(const Jrd::jrd_file*, const USHORT);
|
ULONG PIO_get_number_of_pages(const Jrd::jrd_file*, const USHORT);
|
||||||
|
void PIO_get_unique_file_id(const Jrd::jrd_file*, Firebird::UCharBuffer&);
|
||||||
void PIO_header(Jrd::Database*, SCHAR*, int);
|
void PIO_header(Jrd::Database*, SCHAR*, int);
|
||||||
USHORT PIO_init_data(Jrd::Database*, Jrd::jrd_file*, ISC_STATUS*, ULONG, USHORT);
|
USHORT PIO_init_data(Jrd::Database*, Jrd::jrd_file*, ISC_STATUS*, ULONG, USHORT);
|
||||||
Jrd::jrd_file* PIO_open(Jrd::Database*, const Firebird::PathName&,
|
Jrd::jrd_file* PIO_open(Jrd::Database*, const Firebird::PathName&,
|
||||||
|
@ -117,7 +117,7 @@ using namespace Firebird;
|
|||||||
// that can successfully change BOTH O_DIRECT and O_SYNC using fcntl()
|
// that can successfully change BOTH O_DIRECT and O_SYNC using fcntl()
|
||||||
|
|
||||||
static jrd_file* seek_file(jrd_file*, BufferDesc*, FB_UINT64*, ISC_STATUS*);
|
static jrd_file* seek_file(jrd_file*, BufferDesc*, FB_UINT64*, ISC_STATUS*);
|
||||||
static jrd_file* setup_file(Database*, const PathName&, int);
|
static jrd_file* setup_file(Database*, const PathName&, int, bool);
|
||||||
static bool unix_error(const TEXT*, const jrd_file*, ISC_STATUS, ISC_STATUS*);
|
static bool unix_error(const TEXT*, const jrd_file*, ISC_STATUS, ISC_STATUS*);
|
||||||
#if !(defined HAVE_PREAD && defined HAVE_PWRITE)
|
#if !(defined HAVE_PREAD && defined HAVE_PWRITE)
|
||||||
static SLONG pread(int, SCHAR *, SLONG, SLONG);
|
static SLONG pread(int, SCHAR *, SLONG, SLONG);
|
||||||
@ -273,17 +273,8 @@ jrd_file* PIO_create(Database* dbb, const PathName& file_name,
|
|||||||
|
|
||||||
PathName expanded_name(file_name);
|
PathName expanded_name(file_name);
|
||||||
ISC_expand_filename(expanded_name, false);
|
ISC_expand_filename(expanded_name, false);
|
||||||
jrd_file* file;
|
|
||||||
try
|
return setup_file(dbb, expanded_name, desc, false);
|
||||||
{
|
|
||||||
file = setup_file(dbb, expanded_name, desc);
|
|
||||||
}
|
|
||||||
catch (const Exception&)
|
|
||||||
{
|
|
||||||
close(desc);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -381,9 +372,9 @@ void PIO_force_write(jrd_file* file, const bool forcedWrites, const bool notUseF
|
|||||||
{
|
{
|
||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string, "fcntl() SYNC/DIRECT",
|
isc_arg_string, "fcntl() SYNC/DIRECT",
|
||||||
isc_arg_cstring, file->fil_length,
|
isc_arg_string, ERR_cstring(file->fil_string),
|
||||||
ERR_string(file->fil_string, file->fil_length), isc_arg_gds,
|
isc_arg_gds, isc_io_access_err,
|
||||||
isc_io_access_err, isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
}
|
}
|
||||||
#else //FCNTL_BROKEN
|
#else //FCNTL_BROKEN
|
||||||
maybeCloseFile(file->fil_desc);
|
maybeCloseFile(file->fil_desc);
|
||||||
@ -392,8 +383,9 @@ void PIO_force_write(jrd_file* file, const bool forcedWrites, const bool notUseF
|
|||||||
if (file->fil_desc == -1)
|
if (file->fil_desc == -1)
|
||||||
{
|
{
|
||||||
ERR_post(isc_io_error, isc_arg_string, "re open() for SYNC/DIRECT",
|
ERR_post(isc_io_error, isc_arg_string, "re open() for SYNC/DIRECT",
|
||||||
isc_arg_cstring, file->fil_length, ERR_string(file->fil_string, file->fil_length),
|
isc_arg_string, ERR_cstring(file->fil_string),
|
||||||
isc_arg_gds, isc_io_open_err, isc_arg_unix, errno, isc_arg_end);
|
isc_arg_gds, isc_io_open_err,
|
||||||
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
}
|
}
|
||||||
#endif //FCNTL_BROKEN
|
#endif //FCNTL_BROKEN
|
||||||
|
|
||||||
@ -442,6 +434,32 @@ length = statistics.st_blocks * statistics.st_blksize;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIO_get_unique_file_id(const Jrd::jrd_file* file, UCharBuffer& id)
|
||||||
|
{
|
||||||
|
/**************************************
|
||||||
|
*
|
||||||
|
* P I O _ g e t _ u n i q u e _ f i l e _ i d
|
||||||
|
*
|
||||||
|
**************************************
|
||||||
|
*
|
||||||
|
* Functional description
|
||||||
|
* Return a binary string that uniquely identifies the file.
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
struct stat statistics;
|
||||||
|
fstat(file->fil_desc, &statistics);
|
||||||
|
|
||||||
|
const size_t len1 = sizeof(statistics.st_dev);
|
||||||
|
const size_t len2 = sizeof(statistics.st_ino);
|
||||||
|
|
||||||
|
UCHAR* p = id.getBuffer(len1 + len2);
|
||||||
|
|
||||||
|
memcpy(p, &statistics.st_dev, len1);
|
||||||
|
p += len1;
|
||||||
|
memcpy(p, &statistics.st_ino, len2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIO_header(Database* dbb, SCHAR * address, int length)
|
void PIO_header(Database* dbb, SCHAR * address, int length)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
@ -601,7 +619,7 @@ jrd_file* PIO_open(Database* dbb,
|
|||||||
if (desc == -1) {
|
if (desc == -1) {
|
||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string, "open",
|
isc_arg_string, "open",
|
||||||
isc_arg_cstring, file_name.length(), ERR_cstring(file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_open_err, isc_arg_unix, errno, isc_arg_end);
|
isc_arg_gds, isc_io_open_err, isc_arg_unix, errno, isc_arg_end);
|
||||||
}
|
}
|
||||||
/* If this is the primary file, set Database flag to indicate that it is
|
/* If this is the primary file, set Database flag to indicate that it is
|
||||||
@ -627,24 +645,13 @@ jrd_file* PIO_open(Database* dbb,
|
|||||||
{
|
{
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "open",
|
isc_arg_string, "open",
|
||||||
isc_arg_cstring, file_name.length(),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
ERR_cstring (file_name),
|
|
||||||
isc_arg_gds, isc_io_open_err,
|
isc_arg_gds, isc_io_open_err,
|
||||||
isc_arg_unix, ENOENT, isc_arg_end);
|
isc_arg_unix, ENOENT, isc_arg_end);
|
||||||
}
|
}
|
||||||
#endif /* SUPPORT_RAW_DEVICES */
|
#endif /* SUPPORT_RAW_DEVICES */
|
||||||
|
|
||||||
jrd_file *file;
|
return setup_file(dbb, string, desc, readOnly);
|
||||||
try {
|
|
||||||
file = setup_file(dbb, string, desc);
|
|
||||||
if (readOnly)
|
|
||||||
file->fil_flags |= FIL_readonly;
|
|
||||||
}
|
|
||||||
catch (const Exception&) {
|
|
||||||
close(desc);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -891,7 +898,10 @@ static void maybeCloseFile(int& desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static jrd_file* setup_file(Database* dbb, const PathName& file_name, int desc)
|
static jrd_file* setup_file(Database* dbb,
|
||||||
|
const PathName& file_name,
|
||||||
|
int desc,
|
||||||
|
bool read_only)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -903,88 +913,26 @@ static jrd_file* setup_file(Database* dbb, const PathName& file_name, int desc)
|
|||||||
* Set up file and lock blocks for a file.
|
* Set up file and lock blocks for a file.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
|
jrd_file* file = NULL;
|
||||||
|
|
||||||
/* Allocate file block and copy file name string */
|
try
|
||||||
|
{
|
||||||
|
file = FB_NEW_RPT(*dbb->dbb_permanent, file_name.length() + 1) jrd_file();
|
||||||
|
file->fil_desc = desc;
|
||||||
|
file->fil_max_page = MAX_ULONG;
|
||||||
|
strcpy(file->fil_string, file_name.c_str());
|
||||||
|
|
||||||
jrd_file* file = FB_NEW_RPT(*dbb->dbb_permanent, file_name.length() + 1) jrd_file();
|
if (read_only)
|
||||||
file->fil_desc = desc;
|
file->fil_flags |= FIL_readonly;
|
||||||
file->fil_max_page = MAX_ULONG;
|
}
|
||||||
file->fil_length = file_name.length();
|
catch (const Exception&)
|
||||||
strcpy(file->fil_string, file_name.c_str());
|
{
|
||||||
|
close(desc);
|
||||||
/* If this isn't the primary file, we're done */
|
delete file;
|
||||||
|
throw;
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
|
||||||
if (pageSpace && pageSpace->file)
|
|
||||||
return file;
|
|
||||||
|
|
||||||
/* Build unique lock string for file and construct lock block */
|
|
||||||
|
|
||||||
struct stat statistics;
|
|
||||||
fstat(desc, &statistics);
|
|
||||||
UCHAR lock_string[32];
|
|
||||||
UCHAR* p = lock_string;
|
|
||||||
|
|
||||||
USHORT l = sizeof(statistics.st_dev);
|
|
||||||
memcpy(p, &statistics.st_dev, l);
|
|
||||||
p += l;
|
|
||||||
|
|
||||||
l = sizeof(statistics.st_ino);
|
|
||||||
memcpy(p, &statistics.st_ino, l);
|
|
||||||
p += l;
|
|
||||||
|
|
||||||
l = p - lock_string;
|
|
||||||
fb_assert(l <= sizeof(lock_string)); // In case we add more information.
|
|
||||||
|
|
||||||
Lock* lock = FB_NEW_RPT(*dbb->dbb_permanent, l) Lock();
|
|
||||||
dbb->dbb_lock = lock;
|
|
||||||
lock->lck_type = LCK_database;
|
|
||||||
lock->lck_owner_handle = LCK_get_owner_handle(NULL, lock->lck_type);
|
|
||||||
lock->lck_object = dbb;
|
|
||||||
lock->lck_length = l;
|
|
||||||
lock->lck_dbb = dbb;
|
|
||||||
lock->lck_ast = CCH_down_grade_dbb;
|
|
||||||
memcpy(lock->lck_key.lck_string, lock_string, l);
|
|
||||||
|
|
||||||
/* Try to get an exclusive lock on database. If this fails, insist
|
|
||||||
on at least a shared lock */
|
|
||||||
|
|
||||||
dbb->dbb_flags |= DBB_exclusive;
|
|
||||||
if (!LCK_lock(NULL, lock, LCK_EX, LCK_NO_WAIT)) {
|
|
||||||
dbb->dbb_flags &= ~DBB_exclusive;
|
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
|
||||||
|
|
||||||
while (!LCK_lock(tdbb, lock, LCK_SW, -1)) {
|
|
||||||
tdbb->tdbb_status_vector[0] = 0; // Clean status vector from lock manager error code
|
|
||||||
// If we are in a single-threaded maintenance mode then clean up and stop waiting
|
|
||||||
SCHAR spare_memory[MIN_PAGE_SIZE * 2];
|
|
||||||
SCHAR *header_page_buffer = (SCHAR*) FB_ALIGN((IPTR)spare_memory, MIN_PAGE_SIZE);
|
|
||||||
|
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
|
||||||
try {
|
|
||||||
pageSpace->file = file;
|
|
||||||
PIO_header(dbb, header_page_buffer, MIN_PAGE_SIZE);
|
|
||||||
/* Rewind file pointer */
|
|
||||||
if (lseek (file->fil_desc, LSEEK_OFFSET_CAST 0, 0) == (off_t)-1)
|
|
||||||
ERR_post (isc_io_error,
|
|
||||||
isc_arg_string, "lseek",
|
|
||||||
isc_arg_cstring, file_name.length(), ERR_cstring (file_name),
|
|
||||||
isc_arg_gds, isc_io_read_err,
|
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
|
||||||
if ((reinterpret_cast<Ods::header_page*>(header_page_buffer)->hdr_flags & Ods::hdr_shutdown_mask) == Ods::hdr_shutdown_single)
|
|
||||||
ERR_post(isc_shutdown, isc_arg_cstring, file_name.length(), ERR_cstring(file_name), isc_arg_end);
|
|
||||||
pageSpace->file = NULL; // Will be set again later by the caller
|
|
||||||
}
|
|
||||||
catch (const Exception&) {
|
|
||||||
delete dbb->dbb_lock;
|
|
||||||
dbb->dbb_lock = NULL;
|
|
||||||
delete file;
|
|
||||||
pageSpace->file = NULL; // Will be set again later by the caller
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb_assert(file);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,7 +959,7 @@ static bool unix_error(const TEXT* string,
|
|||||||
*status++ = isc_arg_string;
|
*status++ = isc_arg_string;
|
||||||
*status++ = (ISC_STATUS) string; // pointer to ISC_STATUS!!!
|
*status++ = (ISC_STATUS) string; // pointer to ISC_STATUS!!!
|
||||||
*status++ = isc_arg_string;
|
*status++ = isc_arg_string;
|
||||||
*status++ = (ISC_STATUS)(U_IPTR) ERR_string(file->fil_string, file->fil_length);
|
*status++ = (ISC_STATUS)(U_IPTR) ERR_cstring(file->fil_string);
|
||||||
*status++ = isc_arg_gds;
|
*status++ = isc_arg_gds;
|
||||||
*status++ = operation;
|
*status++ = operation;
|
||||||
*status++ = isc_arg_unix;
|
*status++ = isc_arg_unix;
|
||||||
@ -1023,8 +971,7 @@ static bool unix_error(const TEXT* string,
|
|||||||
|
|
||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string, string,
|
isc_arg_string, string,
|
||||||
isc_arg_string, ERR_string(file->fil_string,
|
isc_arg_string, ERR_cstring(file->fil_string),
|
||||||
file->fil_length),
|
|
||||||
isc_arg_gds, operation,
|
isc_arg_gds, operation,
|
||||||
isc_arg_unix, errno,
|
isc_arg_unix, errno,
|
||||||
isc_arg_end);
|
isc_arg_end);
|
||||||
@ -1180,7 +1127,7 @@ static bool raw_devices_validate_database(int desc, const PathName& file_name)
|
|||||||
if (desc == -1)
|
if (desc == -1)
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "raw_devices_validate_database",
|
isc_arg_string, "raw_devices_validate_database",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_read_err,
|
isc_arg_gds, isc_io_read_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
|
|
||||||
@ -1189,7 +1136,7 @@ static bool raw_devices_validate_database(int desc, const PathName& file_name)
|
|||||||
if (lseek (desc, LSEEK_OFFSET_CAST 0, 0) == (off_t) -1)
|
if (lseek (desc, LSEEK_OFFSET_CAST 0, 0) == (off_t) -1)
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "lseek",
|
isc_arg_string, "lseek",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_read_err,
|
isc_arg_gds, isc_io_read_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
const ssize_t bytes = read (desc, header, sizeof(header));
|
const ssize_t bytes = read (desc, header, sizeof(header));
|
||||||
@ -1198,14 +1145,14 @@ static bool raw_devices_validate_database(int desc, const PathName& file_name)
|
|||||||
if (bytes == -1 && !SYSCALL_INTERRUPTED(errno))
|
if (bytes == -1 && !SYSCALL_INTERRUPTED(errno))
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "read",
|
isc_arg_string, "read",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_read_err,
|
isc_arg_gds, isc_io_read_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "read_retry",
|
isc_arg_string, "read_retry",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_read_err,
|
isc_arg_gds, isc_io_read_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
|
|
||||||
@ -1214,7 +1161,7 @@ static bool raw_devices_validate_database(int desc, const PathName& file_name)
|
|||||||
if (lseek (desc, LSEEK_OFFSET_CAST 0, 0) == (off_t)-1)
|
if (lseek (desc, LSEEK_OFFSET_CAST 0, 0) == (off_t)-1)
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "lseek",
|
isc_arg_string, "lseek",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_read_err,
|
isc_arg_gds, isc_io_read_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
|
|
||||||
@ -1256,7 +1203,7 @@ static int raw_devices_unlink_database(const PathName& file_name)
|
|||||||
if (!SYSCALL_INTERRUPTED(errno))
|
if (!SYSCALL_INTERRUPTED(errno))
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "open",
|
isc_arg_string, "open",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_open_err,
|
isc_arg_gds, isc_io_open_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
}
|
}
|
||||||
@ -1272,7 +1219,7 @@ static int raw_devices_unlink_database(const PathName& file_name)
|
|||||||
continue;
|
continue;
|
||||||
ERR_post (isc_io_error,
|
ERR_post (isc_io_error,
|
||||||
isc_arg_string, "write",
|
isc_arg_string, "write",
|
||||||
isc_arg_string, file_name.length(), ERR_cstring (file_name),
|
isc_arg_string, ERR_cstring(file_name),
|
||||||
isc_arg_gds, isc_io_write_err,
|
isc_arg_gds, isc_io_write_err,
|
||||||
isc_arg_unix, errno, isc_arg_end);
|
isc_arg_unix, errno, isc_arg_end);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ static void release_io_event(jrd_file*, OVERLAPPED*);
|
|||||||
#endif
|
#endif
|
||||||
static bool maybe_close_file(HANDLE&);
|
static bool maybe_close_file(HANDLE&);
|
||||||
static jrd_file* seek_file(jrd_file*, BufferDesc*, ISC_STATUS*, OVERLAPPED*, OVERLAPPED**);
|
static jrd_file* seek_file(jrd_file*, BufferDesc*, ISC_STATUS*, OVERLAPPED*, OVERLAPPED**);
|
||||||
static jrd_file* setup_file(Database*, const Firebird::PathName&, HANDLE);
|
static jrd_file* setup_file(Database*, const Firebird::PathName&, HANDLE, bool);
|
||||||
static bool nt_error(TEXT*, const jrd_file*, ISC_STATUS, ISC_STATUS*);
|
static bool nt_error(TEXT*, const jrd_file*, ISC_STATUS, ISC_STATUS*);
|
||||||
|
|
||||||
#ifdef SUPERSERVER_V2
|
#ifdef SUPERSERVER_V2
|
||||||
@ -229,7 +229,7 @@ jrd_file* PIO_create(Database* dbb, const Firebird::PathName& string,
|
|||||||
{
|
{
|
||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string, "CreateFile (create)",
|
isc_arg_string, "CreateFile (create)",
|
||||||
isc_arg_cstring, string.length(), ERR_cstring(string),
|
isc_arg_string, ERR_cstring(string),
|
||||||
isc_arg_gds, isc_io_create_err, isc_arg_win32, GetLastError(),
|
isc_arg_gds, isc_io_create_err, isc_arg_win32, GetLastError(),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
@ -239,16 +239,8 @@ jrd_file* PIO_create(Database* dbb, const Firebird::PathName& string,
|
|||||||
|
|
||||||
Firebird::PathName workspace(string);
|
Firebird::PathName workspace(string);
|
||||||
ISC_expand_filename(workspace, false);
|
ISC_expand_filename(workspace, false);
|
||||||
jrd_file *file;
|
|
||||||
try {
|
|
||||||
file = setup_file(dbb, workspace, desc);
|
|
||||||
}
|
|
||||||
catch (const Firebird::Exception&) {
|
|
||||||
CloseHandle(desc);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return file;
|
return setup_file(dbb, workspace, desc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -385,9 +377,8 @@ void PIO_force_write(jrd_file* file, const bool forceWrite, const bool notUseFSC
|
|||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string,
|
isc_arg_string,
|
||||||
"CreateFile (force write)",
|
"CreateFile (force write)",
|
||||||
isc_arg_cstring,
|
isc_arg_string,
|
||||||
file->fil_length,
|
ERR_cstring(file->fil_string),
|
||||||
ERR_string(file->fil_string, file->fil_length),
|
|
||||||
isc_arg_gds, isc_io_access_err,
|
isc_arg_gds, isc_io_access_err,
|
||||||
isc_arg_win32,
|
isc_arg_win32,
|
||||||
GetLastError(),
|
GetLastError(),
|
||||||
@ -591,8 +582,7 @@ jrd_file* PIO_open(Database* dbb,
|
|||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string,
|
isc_arg_string,
|
||||||
"CreateFile (open)",
|
"CreateFile (open)",
|
||||||
isc_arg_cstring,
|
isc_arg_string,
|
||||||
file_name.length(),
|
|
||||||
ERR_cstring(file_name),
|
ERR_cstring(file_name),
|
||||||
isc_arg_gds,
|
isc_arg_gds,
|
||||||
isc_io_open_err, isc_arg_win32, GetLastError(), 0);
|
isc_io_open_err, isc_arg_win32, GetLastError(), 0);
|
||||||
@ -610,18 +600,7 @@ jrd_file* PIO_open(Database* dbb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jrd_file *file;
|
return setup_file(dbb, string, desc, readOnly);
|
||||||
try {
|
|
||||||
file = setup_file(dbb, string, desc);
|
|
||||||
|
|
||||||
if (readOnly)
|
|
||||||
file->fil_flags |= FIL_readonly;
|
|
||||||
}
|
|
||||||
catch (const Firebird::Exception&) {
|
|
||||||
CloseHandle(desc);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -933,6 +912,39 @@ ULONG PIO_get_number_of_pages(const jrd_file* file, const USHORT pagesize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIO_get_unique_file_id(const Jrd::jrd_file* file, Firebird::UCharBuffer& id)
|
||||||
|
{
|
||||||
|
/**************************************
|
||||||
|
*
|
||||||
|
* P I O _ g e t _ u n i q u e _ f i l e _ i d
|
||||||
|
*
|
||||||
|
**************************************
|
||||||
|
*
|
||||||
|
* Functional description
|
||||||
|
* Return a binary string that uniquely identifies the file.
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
BY_HANDLE_FILE_INFORMATION file_info;
|
||||||
|
GetFileInformationByHandle(file->fil_desc, &file_info);
|
||||||
|
|
||||||
|
// The identifier is [nFileIndexHigh, nFileIndexLow]
|
||||||
|
// MSDN says: After a process opens a file, the identifier is constant until
|
||||||
|
// the file is closed. An application can use this identifier and the
|
||||||
|
// volume serial number to determine whether two handles refer to the same file.
|
||||||
|
const size_t len1 = sizeof(file_info.dwVolumeSerialNumber);
|
||||||
|
const size_t len2 = sizeof(file_info.nFileIndexHigh);
|
||||||
|
const size_t len3 = sizeof(file_info.nFileIndexLow);
|
||||||
|
|
||||||
|
UCHAR* p = id.getBuffer(len1 + len2 + len3);
|
||||||
|
|
||||||
|
memcpy(p, &file_info.dwVolumeSerialNumber, len1);
|
||||||
|
p += len1;
|
||||||
|
memcpy(p, &file_info.nFileIndexHigh, len2);
|
||||||
|
p += len2;
|
||||||
|
memcpy(p, &file_info.nFileIndexLow, len3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SUPERSERVER_V2
|
#ifdef SUPERSERVER_V2
|
||||||
static void release_io_event(jrd_file* file, OVERLAPPED* overlapped)
|
static void release_io_event(jrd_file* file, OVERLAPPED* overlapped)
|
||||||
{
|
{
|
||||||
@ -1034,9 +1046,10 @@ static jrd_file* seek_file(jrd_file* file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static jrd_file* setup_file(Database* dbb,
|
static jrd_file* setup_file(Database* dbb,
|
||||||
const Firebird::PathName& file_name,
|
const Firebird::PathName& file_name,
|
||||||
HANDLE desc)
|
HANDLE desc,
|
||||||
|
bool read_only)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1048,95 +1061,37 @@ static jrd_file* setup_file(Database* dbb,
|
|||||||
* Set up file and lock blocks for a file.
|
* Set up file and lock blocks for a file.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
|
jrd_file* file = NULL;
|
||||||
|
|
||||||
/* Allocate file block and copy file name string */
|
try
|
||||||
|
{
|
||||||
jrd_file* file = FB_NEW_RPT(*dbb->dbb_permanent, file_name.length() + 1) jrd_file();
|
file = FB_NEW_RPT(*dbb->dbb_permanent, file_name.length() + 1) jrd_file();
|
||||||
file->fil_desc = desc;
|
file->fil_desc = desc;
|
||||||
file->fil_max_page = MAX_ULONG;
|
file->fil_max_page = MAX_ULONG;
|
||||||
file->fil_length = file_name.length();
|
strcpy(file->fil_string, file_name.c_str());
|
||||||
strcpy(file->fil_string, file_name.c_str());
|
|
||||||
#ifdef SUPERSERVER_V2
|
#ifdef SUPERSERVER_V2
|
||||||
memset(file->fil_io_events, 0, MAX_FILE_IO * sizeof(void*));
|
memset(file->fil_io_events, 0, MAX_FILE_IO * sizeof(void*));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If this isn't the primary file, we're done */
|
if (read_only)
|
||||||
|
file->fil_flags |= FIL_readonly;
|
||||||
|
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
// If this isn't the primary file, we're done
|
||||||
if (pageSpace && pageSpace->file)
|
|
||||||
return file;
|
|
||||||
|
|
||||||
/* Build unique lock string for file and construct lock block */
|
const PageSpace* const pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
|
if (pageSpace && pageSpace->file)
|
||||||
|
return file;
|
||||||
|
|
||||||
BY_HANDLE_FILE_INFORMATION file_info;
|
file->fil_ext_lock = FB_NEW(*dbb->dbb_permanent) Firebird::RWLock();
|
||||||
GetFileInformationByHandle(desc, &file_info);
|
}
|
||||||
UCHAR lock_string[32];
|
catch (const Firebird::Exception&)
|
||||||
UCHAR* p = lock_string;
|
{
|
||||||
|
CloseHandle(desc);
|
||||||
// The identifier is [nFileIndexHigh, nFileIndexLow]
|
delete file;
|
||||||
// MSDN says: After a process opens a file, the identifier is constant until
|
throw;
|
||||||
// the file is closed. An application can use this identifier and the
|
|
||||||
// volume serial number to determine whether two handles refer to the same file.
|
|
||||||
size_t l = sizeof(file_info.dwVolumeSerialNumber);
|
|
||||||
memcpy(p, &file_info.dwVolumeSerialNumber, l);
|
|
||||||
p += l;
|
|
||||||
|
|
||||||
l = sizeof(file_info.nFileIndexHigh);
|
|
||||||
memcpy(p, &file_info.nFileIndexHigh, l);
|
|
||||||
p += l;
|
|
||||||
|
|
||||||
l = sizeof(file_info.nFileIndexLow);
|
|
||||||
memcpy(p, &file_info.nFileIndexLow, l);
|
|
||||||
p += l;
|
|
||||||
|
|
||||||
// We know p only was incremented, so can use safely size_t instead of ptrdiff_t
|
|
||||||
l = p - lock_string;
|
|
||||||
fb_assert(l <= sizeof(lock_string)); // In case we continue adding information.
|
|
||||||
|
|
||||||
file->fil_ext_lock = FB_NEW(*dbb->dbb_permanent) Firebird::RWLock();
|
|
||||||
|
|
||||||
Lock* lock = FB_NEW_RPT(*dbb->dbb_permanent, l) Lock;
|
|
||||||
dbb->dbb_lock = lock;
|
|
||||||
lock->lck_type = LCK_database;
|
|
||||||
lock->lck_owner_handle = LCK_get_owner_handle(NULL, lock->lck_type);
|
|
||||||
lock->lck_object = dbb;
|
|
||||||
lock->lck_length = l;
|
|
||||||
lock->lck_dbb = dbb;
|
|
||||||
lock->lck_ast = CCH_down_grade_dbb;
|
|
||||||
memcpy(lock->lck_key.lck_string, lock_string, l);
|
|
||||||
|
|
||||||
/* Try to get an exclusive lock on database. If this fails, insist
|
|
||||||
on at least a shared lock */
|
|
||||||
|
|
||||||
dbb->dbb_flags |= DBB_exclusive;
|
|
||||||
if (!LCK_lock(NULL, lock, LCK_EX, LCK_NO_WAIT)) {
|
|
||||||
dbb->dbb_flags &= ~DBB_exclusive;
|
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
|
||||||
|
|
||||||
while (!LCK_lock(tdbb, lock, LCK_SW, -1)) {
|
|
||||||
tdbb->tdbb_status_vector[0] = 0; // Clean status vector from lock manager error code
|
|
||||||
// If we are in a single-threaded maintenance mode then clean up and stop waiting
|
|
||||||
SCHAR spare_memory[MIN_PAGE_SIZE * 2];
|
|
||||||
SCHAR *header_page_buffer = (SCHAR*) FB_ALIGN((IPTR)spare_memory, MIN_PAGE_SIZE);
|
|
||||||
|
|
||||||
pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
|
||||||
try {
|
|
||||||
pageSpace->file = file;
|
|
||||||
PIO_header(dbb, header_page_buffer, MIN_PAGE_SIZE);
|
|
||||||
if ((reinterpret_cast<Ods::header_page*>(header_page_buffer)->hdr_flags & Ods::hdr_shutdown_mask) == Ods::hdr_shutdown_single)
|
|
||||||
ERR_post(isc_shutdown, isc_arg_cstring, file_name.length(), ERR_cstring(file_name), 0);
|
|
||||||
pageSpace->file = NULL; // Will be set again later by the caller
|
|
||||||
}
|
|
||||||
catch (const Firebird::Exception&) {
|
|
||||||
delete dbb->dbb_lock;
|
|
||||||
dbb->dbb_lock = NULL;
|
|
||||||
delete file;
|
|
||||||
pageSpace->file = NULL; // Will be set again later by the caller
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb_assert(file);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,8 +1140,7 @@ static bool nt_error(TEXT* string,
|
|||||||
*status_vector++ = isc_arg_string;
|
*status_vector++ = isc_arg_string;
|
||||||
*status_vector++ = (ISC_STATUS) string;
|
*status_vector++ = (ISC_STATUS) string;
|
||||||
*status_vector++ = isc_arg_string;
|
*status_vector++ = isc_arg_string;
|
||||||
*status_vector++ =
|
*status_vector++ = (ISC_STATUS)(U_IPTR) ERR_cstring(file->fil_string);
|
||||||
(ISC_STATUS)(U_IPTR) ERR_string(file->fil_string, file->fil_length);
|
|
||||||
*status_vector++ = isc_arg_gds;
|
*status_vector++ = isc_arg_gds;
|
||||||
*status_vector++ = operation;
|
*status_vector++ = operation;
|
||||||
*status_vector++ = isc_arg_win32;
|
*status_vector++ = isc_arg_win32;
|
||||||
@ -1197,7 +1151,7 @@ static bool nt_error(TEXT* string,
|
|||||||
|
|
||||||
ERR_post(isc_io_error,
|
ERR_post(isc_io_error,
|
||||||
isc_arg_string, string,
|
isc_arg_string, string,
|
||||||
isc_arg_string, ERR_string(file->fil_string, file->fil_length),
|
isc_arg_string, ERR_cstring(file->fil_string),
|
||||||
isc_arg_gds, operation, isc_arg_win32, GetLastError(), 0);
|
isc_arg_gds, operation, isc_arg_win32, GetLastError(), 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1041,7 +1041,7 @@ int PAG_delete_clump_entry(SLONG page_num, USHORT type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PAG_format_header()
|
void PAG_format_header(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1053,8 +1053,8 @@ void PAG_format_header()
|
|||||||
* Create the header page for a new file.
|
* Create the header page for a new file.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
CHECK_DBB(dbb);
|
CHECK_DBB(dbb);
|
||||||
|
|
||||||
/* Initialize header page */
|
/* Initialize header page */
|
||||||
@ -1091,7 +1091,7 @@ void PAG_format_header()
|
|||||||
|
|
||||||
// CVC: This function is mostly obsolete. Ann requested to keep it and the code that calls it.
|
// CVC: This function is mostly obsolete. Ann requested to keep it and the code that calls it.
|
||||||
// We won't read the log, anyway.
|
// We won't read the log, anyway.
|
||||||
void PAG_format_log()
|
void PAG_format_log(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/***********************************************
|
/***********************************************
|
||||||
*
|
*
|
||||||
@ -1104,7 +1104,7 @@ void PAG_format_log()
|
|||||||
* Set all parameters to 0
|
* Set all parameters to 0
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
|
|
||||||
WIN window(LOG_PAGE_NUMBER);
|
WIN window(LOG_PAGE_NUMBER);
|
||||||
log_info_page* logp = (log_info_page*) CCH_fake(tdbb, &window, 1);
|
log_info_page* logp = (log_info_page*) CCH_fake(tdbb, &window, 1);
|
||||||
@ -1207,7 +1207,7 @@ bool PAG_get_clump(SLONG page_num, USHORT type, USHORT* inout_len, UCHAR* entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PAG_header(bool info)
|
void PAG_header(thread_db* tdbb, bool info)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1220,8 +1220,8 @@ void PAG_header(bool info)
|
|||||||
* Done through the page cache.
|
* Done through the page cache.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
Attachment* attachment = tdbb->getAttachment();
|
Attachment* attachment = tdbb->getAttachment();
|
||||||
fb_assert(attachment);
|
fb_assert(attachment);
|
||||||
@ -1332,7 +1332,7 @@ void PAG_header(bool info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PAG_header_init()
|
void PAG_header_init(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1347,10 +1347,10 @@ void PAG_header_init()
|
|||||||
* Done using a physical page read.
|
* Done using a physical page read.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
Attachment* attachment = tdbb->getAttachment();
|
Attachment* const attachment = tdbb->getAttachment();
|
||||||
fb_assert(attachment);
|
fb_assert(attachment);
|
||||||
|
|
||||||
// Allocate a spare buffer which is large enough,
|
// Allocate a spare buffer which is large enough,
|
||||||
@ -1434,7 +1434,7 @@ void PAG_header_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PAG_init()
|
void PAG_init(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1446,8 +1446,8 @@ void PAG_init()
|
|||||||
* Initialize stuff for page handling.
|
* Initialize stuff for page handling.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
CHECK_DBB(dbb);
|
CHECK_DBB(dbb);
|
||||||
|
|
||||||
PageManager& pageMgr = dbb->dbb_page_manager;
|
PageManager& pageMgr = dbb->dbb_page_manager;
|
||||||
@ -1518,7 +1518,7 @@ void PAG_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PAG_init2(USHORT shadow_number)
|
void PAG_init2(thread_db* tdbb, USHORT shadow_number)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1531,8 +1531,8 @@ void PAG_init2(USHORT shadow_number)
|
|||||||
* search for additional files.
|
* search for additional files.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
SET_TDBB(tdbb);
|
||||||
Database* dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||||
|
|
||||||
/* allocate a spare buffer which is large enough,
|
/* allocate a spare buffer which is large enough,
|
||||||
|
@ -44,14 +44,14 @@ int PAG_replace_entry_first(Ods::header_page*, USHORT, USHORT, const UCHAR*);
|
|||||||
Ods::pag* PAG_allocate(Jrd::win *);
|
Ods::pag* PAG_allocate(Jrd::win *);
|
||||||
SLONG PAG_attachment_id(Jrd::thread_db*);
|
SLONG PAG_attachment_id(Jrd::thread_db*);
|
||||||
int PAG_delete_clump_entry(SLONG, USHORT);
|
int PAG_delete_clump_entry(SLONG, USHORT);
|
||||||
void PAG_format_header();
|
void PAG_format_header(Jrd::thread_db*);
|
||||||
void PAG_format_log();
|
void PAG_format_log(Jrd::thread_db*);
|
||||||
void PAG_format_pip(Jrd::thread_db*, Jrd::PageSpace& pageSpace);
|
void PAG_format_pip(Jrd::thread_db*, Jrd::PageSpace& pageSpace);
|
||||||
bool PAG_get_clump(SLONG, USHORT, USHORT*, UCHAR*);
|
bool PAG_get_clump(SLONG, USHORT, USHORT*, UCHAR*);
|
||||||
void PAG_header(bool);
|
void PAG_header(Jrd::thread_db*, bool);
|
||||||
void PAG_header_init();
|
void PAG_header_init(Jrd::thread_db*);
|
||||||
void PAG_init();
|
void PAG_init(Jrd::thread_db*);
|
||||||
void PAG_init2(USHORT);
|
void PAG_init2(Jrd::thread_db*, USHORT);
|
||||||
SLONG PAG_last_page();
|
SLONG PAG_last_page();
|
||||||
void PAG_release_page(const Jrd::PageNumber&, const Jrd::PageNumber&);
|
void PAG_release_page(const Jrd::PageNumber&, const Jrd::PageNumber&);
|
||||||
void PAG_set_force_write(Jrd::Database*, bool);
|
void PAG_set_force_write(Jrd::Database*, bool);
|
||||||
|
@ -132,7 +132,6 @@ int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3)
|
|||||||
* These entrypoints are *NOT* designed for customer use!
|
* These entrypoints are *NOT* designed for customer use!
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
char filename[MAXPATHLEN];
|
|
||||||
Shadow* shadow;
|
Shadow* shadow;
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
HANDLE desc;
|
HANDLE desc;
|
||||||
@ -159,23 +158,19 @@ int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
|
|
||||||
desc =
|
desc =
|
||||||
(HANDLE) ((file->fil_flags & FIL_force_write) ?
|
(HANDLE) ((file->fil_flags & FIL_force_write) ?
|
||||||
file->fil_force_write_desc : file->fil_desc);
|
file->fil_force_write_desc : file->fil_desc);
|
||||||
|
|
||||||
CloseHandle(desc);
|
CloseHandle(desc);
|
||||||
desc = INVALID_HANDLE_VALUE;
|
|
||||||
#else
|
#else
|
||||||
close(file->fil_desc);
|
close(file->fil_desc);
|
||||||
#endif
|
#endif
|
||||||
strncpy((char *) filename, file->fil_string, file->fil_length);
|
|
||||||
filename[file->fil_length] = 0;
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
DeleteFile(filename);
|
DeleteFile(file->fil_string);
|
||||||
#else
|
#else
|
||||||
unlink(filename);
|
unlink(file->fil_string);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -184,29 +179,27 @@ int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3)
|
|||||||
/* Close & delete specified shadow file */
|
/* Close & delete specified shadow file */
|
||||||
|
|
||||||
tdbb = JRD_get_thread_data();
|
tdbb = JRD_get_thread_data();
|
||||||
|
|
||||||
if (!(shadow = dbb->dbb_shadow))
|
if (!(shadow = dbb->dbb_shadow))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (; shadow; shadow = shadow->sdw_next)
|
for (; shadow; shadow = shadow->sdw_next)
|
||||||
if (shadow->sdw_number == *(ULONG *) arg1) {
|
if (shadow->sdw_number == *(ULONG *) arg1) {
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
|
|
||||||
desc =
|
desc =
|
||||||
(HANDLE) ((shadow->sdw_file->fil_flags & FIL_force_write) ?
|
(HANDLE) ((shadow->sdw_file->fil_flags & FIL_force_write) ?
|
||||||
shadow->sdw_file->fil_force_write_desc :
|
shadow->sdw_file->fil_force_write_desc :
|
||||||
shadow->sdw_file->fil_desc);
|
shadow->sdw_file->fil_desc);
|
||||||
|
|
||||||
CloseHandle(desc);
|
CloseHandle(desc);
|
||||||
desc = INVALID_HANDLE_VALUE;
|
|
||||||
#else
|
#else
|
||||||
close(shadow->sdw_file->fil_desc);
|
close(shadow->sdw_file->fil_desc);
|
||||||
#endif
|
#endif
|
||||||
strncpy((char *) filename, shadow->sdw_file->fil_string,
|
|
||||||
shadow->sdw_file->fil_length);
|
|
||||||
filename[shadow->sdw_file->fil_length] = 0;
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
DeleteFile(filename);
|
DeleteFile(shadow->sdw_file->fil_string);
|
||||||
#else
|
#else
|
||||||
unlink(filename);
|
unlink(shadow->sdw_file->fil_string);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1057,8 @@ void SDW_start(const TEXT* file_name,
|
|||||||
|
|
||||||
/* get the ancillary files and reset the error environment */
|
/* get the ancillary files and reset the error environment */
|
||||||
|
|
||||||
PAG_init2(shadow_number);
|
PAG_init2(tdbb, shadow_number);
|
||||||
|
|
||||||
if (spare_buffer)
|
if (spare_buffer)
|
||||||
delete[] spare_buffer;
|
delete[] spare_buffer;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user