8
0
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:
dimitr 2008-07-09 08:40:31 +00:00
parent cd10fbee3b
commit 609f466ad3
13 changed files with 314 additions and 369 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 */
}; };

View File

@ -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&,

View File

@ -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);
} }

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;