From 609f466ad3a7e743f494c5e49b68ceda72af0b23 Mon Sep 17 00:00:00 2001 From: dimitr Date: Wed, 9 Jul 2008 08:40:31 +0000 Subject: [PATCH] 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. --- src/jrd/DatabaseSnapshot.cpp | 2 +- src/jrd/inf.cpp | 10 +- src/jrd/ini.epp | 12 +- src/jrd/ini_proto.h | 4 +- src/jrd/jrd.cpp | 211 ++++++++++++++++++++++------------- src/jrd/os/pio.h | 2 - src/jrd/os/pio_proto.h | 1 + src/jrd/os/posix/unix.cpp | 187 +++++++++++-------------------- src/jrd/os/win32/winnt.cpp | 182 +++++++++++------------------- src/jrd/pag.cpp | 36 +++--- src/jrd/pag_proto.h | 12 +- src/jrd/qatest.cpp | 21 ++-- src/jrd/sdw.cpp | 3 +- 13 files changed, 314 insertions(+), 369 deletions(-) diff --git a/src/jrd/DatabaseSnapshot.cpp b/src/jrd/DatabaseSnapshot.cpp index 4ab4ccf317..5fc7f58342 100644 --- a/src/jrd/DatabaseSnapshot.cpp +++ b/src/jrd/DatabaseSnapshot.cpp @@ -400,7 +400,7 @@ int DatabaseSnapshot::blockingAst(void* ast_object) DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool) : snapshot(pool), idMap(pool), idCounter(0) { - PAG_header(true); + PAG_header(tdbb, true); Database* const dbb = tdbb->getDatabase(); fb_assert(dbb); diff --git a/src/jrd/inf.cpp b/src/jrd/inf.cpp index f984939e51..cc06097f13 100644 --- a/src/jrd/inf.cpp +++ b/src/jrd/inf.cpp @@ -475,7 +475,7 @@ int INF_database_info(const SCHAR* items, case isc_info_forced_writes: if (!header_refreshed) { - PAG_header(true); + PAG_header(tdbb, true); header_refreshed = true; } *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: if (!header_refreshed) { - PAG_header(true); + PAG_header(tdbb, true); header_refreshed = true; } length = INF_convert(dbb->dbb_oldest_transaction, buffer); @@ -746,7 +746,7 @@ int INF_database_info(const SCHAR* items, case isc_info_oldest_active: if (!header_refreshed) { - PAG_header(true); + PAG_header(tdbb, true); header_refreshed = true; } length = INF_convert(dbb->dbb_oldest_active, buffer); @@ -755,7 +755,7 @@ int INF_database_info(const SCHAR* items, case isc_info_oldest_snapshot: if (!header_refreshed) { - PAG_header(true); + PAG_header(tdbb, true); header_refreshed = true; } length = INF_convert(dbb->dbb_oldest_snapshot, buffer); @@ -764,7 +764,7 @@ int INF_database_info(const SCHAR* items, case isc_info_next_transaction: if (!header_refreshed) { - PAG_header(true); + PAG_header(tdbb, true); header_refreshed = true; } length = INF_convert(dbb->dbb_next_transaction, buffer); diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 958fd968cc..dc71ad7655 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); CHECK_DBB(dbb); 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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); const USHORT major_version = dbb->dbb_ods_version; const USHORT minor_original = dbb->dbb_minor_original; diff --git a/src/jrd/ini_proto.h b/src/jrd/ini_proto.h index 526f4fd43e..9302799a29 100644 --- a/src/jrd/ini_proto.h +++ b/src/jrd/ini_proto.h @@ -30,8 +30,8 @@ namespace Jrd { void INI_format(const TEXT*, const TEXT*); USHORT INI_get_trig_flags(const TEXT*); -void INI_init(); -void INI_init2(); +void INI_init(Jrd::thread_db*); +void INI_init2(Jrd::thread_db*); #endif // JRD_INI_PROTO_H diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 38e4b3d421..63de067d79 100644 --- a/src/jrd/jrd.cpp +++ b/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 void find_intl_charset(thread_db*, Attachment*, const DatabaseOptions*); 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 void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction); 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, isc_arg_string, "direct", isc_arg_string, "security database", - isc_arg_string, - ERR_string(file_name), + isc_arg_string, ERR_string(file_name), isc_arg_end); } @@ -788,8 +787,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, ERR_post(isc_no_priv, isc_arg_string, "encryption", isc_arg_string, "database", - isc_arg_string, - ERR_string(file_name), + isc_arg_string, ERR_string(file_name), isc_arg_end); } } @@ -873,14 +871,19 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, LCK_init(tdbb, LCK_OWNER_database); dbb->dbb_flags |= DBB_lck_init_done; - INI_init(); + INI_init(tdbb); PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); pageSpace->file = PIO_open(dbb, expanded_name, file_name, false); + + // Initialize locks + init_database_locks(tdbb); + SHUT_init(tdbb); - PAG_header_init(); - INI_init2(); - PAG_init(); + PAG_header_init(tdbb); + INI_init2(tdbb); + PAG_init(tdbb); + if (options.dpb_set_page_buffers) { #ifdef SUPERSERVER // 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 dbb->dbb_page_buffers = options.dpb_page_buffers; } - CCH_init(tdbb, options.dpb_buffers); - // Initialize locks - init_database_locks(tdbb, dbb); + CCH_init(tdbb, options.dpb_buffers); // Initialize backup difference subsystem. This must be done before WAL and shadowing // 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); - PAG_init2(0); - PAG_header(false); + PAG_init2(tdbb, 0); + PAG_header(tdbb, false); // initialize shadowing as soon as the database is ready for it // 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) { - ERR_post(isc_lock_timeout, isc_arg_gds, isc_obj_in_use, - isc_arg_string, - ERR_string(file_name), + ERR_post(isc_lock_timeout, + isc_arg_gds, isc_obj_in_use, + isc_arg_string, ERR_string(file_name), 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, options.dpb_sql_dialect, 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()) @@ -1083,16 +1085,14 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, CCH_exclusive_attachment(tdbb, LCK_none, LCK_WAIT); if (attachment->att_flags & ATT_shutdown) { if (dbb->dbb_ast_flags & DBB_shutdown) { - ERR_post(isc_shutdown, isc_arg_string, - ERR_string(file_name), isc_arg_end); + ERR_post(isc_shutdown, isc_arg_string, ERR_string(file_name), isc_arg_end); } else { ERR_post(isc_att_shutdown); } } if (!attachment_succeeded) { - ERR_post(isc_shutdown, isc_arg_string, - ERR_string(file_name), isc_arg_end); + ERR_post(isc_shutdown, isc_arg_string, ERR_string(file_name), isc_arg_end); } } #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)) { - ERR_post(isc_shutinprog, isc_arg_string, - ERR_string(file_name), isc_arg_end); + ERR_post(isc_shutinprog, isc_arg_string, ERR_string(file_name), isc_arg_end); } if (dbb->dbb_ast_flags & DBB_shutdown) { @@ -1126,8 +1125,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, } if (!allow_access) { // Note we throw exception here when entering full-shutdown mode - ERR_post(isc_shutdown, isc_arg_string, - ERR_string(file_name), isc_arg_end); + ERR_post(isc_shutdown, isc_arg_string, 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()) { - ERR_post(isc_bad_dpb_content, - isc_arg_gds, isc_cant_start_journal, - isc_arg_end); + ERR_post(isc_bad_dpb_content, isc_arg_gds, isc_cant_start_journal, isc_arg_end); } if (options.dpb_wal_action) @@ -1223,9 +1219,9 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status, if (options.dpb_set_db_readonly) { validateAccess(attachment); if (!CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD)) { - ERR_post(isc_lock_timeout, isc_arg_gds, isc_obj_in_use, - isc_arg_string, - ERR_string(file_name), + ERR_post(isc_lock_timeout, + isc_arg_gds, isc_obj_in_use, + isc_arg_string, ERR_string(file_name), isc_arg_end); } 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; break; default: - ERR_post(isc_database_create_failed, isc_arg_string, - expanded_name.c_str(), isc_arg_gds, isc_inv_dialect_specified, - isc_arg_number, options.dpb_sql_dialect, isc_arg_gds, - isc_valid_db_dialects, isc_arg_string, "1 and 3", isc_arg_end); + ERR_post(isc_database_create_failed, + isc_arg_string, ERR_string(expanded_name), + isc_arg_gds, isc_inv_dialect_specified, + isc_arg_number, options.dpb_sql_dialect, + isc_arg_gds, isc_valid_db_dialects, + isc_arg_string, "1 and 3", isc_arg_end); break; } @@ -1826,8 +1824,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, LCK_init(tdbb, LCK_OWNER_database); dbb->dbb_flags |= DBB_lck_init_done; - INI_init(); - PAG_init(); + INI_init(tdbb); + PAG_init(tdbb); initing_security = true; SCL_init(true, userId, tdbb); @@ -1866,39 +1864,39 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, if (allow_overwrite) { // file is a database and the user (SYSDBA or owner) has right to overwrite - pageSpace->file = - PIO_create(dbb, expanded_name, options.dpb_overwrite, false, false); + pageSpace->file = PIO_create(dbb, expanded_name, options.dpb_overwrite, false, false); } else { ERR_post(isc_no_priv, - isc_arg_string, "overwrite", - isc_arg_string, "database", - isc_arg_string, - ERR_cstring(expanded_name.c_str()), isc_arg_end); + isc_arg_string, "overwrite", + isc_arg_string, "database", + isc_arg_string, ERR_string(expanded_name), + isc_arg_end); } } else 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) dbb->dbb_page_buffers = options.dpb_page_buffers; - CCH_init(tdbb, options.dpb_buffers); - // Initialize locks - init_database_locks(tdbb, dbb); + CCH_init(tdbb, options.dpb_buffers); // Initialize backup difference subsystem. This must be done before WAL and shadowing // 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->dbCreating = true; - PAG_format_header(); - INI_init2(); - PAG_format_log(); + PAG_format_header(tdbb); + INI_init2(tdbb); + PAG_format_log(tdbb); PAG_format_pip(tdbb, *pageSpace); if (options.dpb_set_page_buffers) @@ -1922,8 +1920,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, ERR_post(isc_no_priv, isc_arg_string, "shutdown or online", isc_arg_string, "database", - isc_arg_string, - ERR_string(file_name), isc_arg_end); + isc_arg_string, ERR_string(file_name), + isc_arg_end); } } @@ -1946,12 +1944,12 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, if (options.dpb_set_db_readonly) { if (!CCH_exclusive (tdbb, LCK_EX, WAIT_PERIOD)) - ERR_post (isc_lock_timeout, isc_arg_gds, isc_obj_in_use, - isc_arg_string, - ERR_string (file_name), - isc_arg_end); + ERR_post(isc_lock_timeout, + isc_arg_gds, isc_obj_in_use, + isc_arg_string, ERR_string(file_name), + 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); @@ -1963,8 +1961,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status, find_intl_charset(tdbb, attachment, &options); #ifdef WIN_NT - dbb->dbb_filename.assign(first_dbb_file->fil_string, - first_dbb_file->fil_length); + dbb->dbb_filename.assign(first_dbb_file->fil_string); #else dbb->dbb_filename = expanded_name; #endif @@ -2166,17 +2163,18 @@ ISC_STATUS GDS_DROP_DATABASE(ISC_STATUS* user_status, Attachment** handle) ERR_post(isc_no_priv, isc_arg_string, "drop", 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 (dbb->dbb_ast_flags & DBB_shutdown) { - ERR_post(isc_shutdown, isc_arg_string, - ERR_cstring(file_name), isc_arg_end); + ERR_post(isc_shutdown, isc_arg_string, ERR_cstring(file_name), isc_arg_end); } - else { + else + { 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, 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 if (dbb->dbb_attachments && dbb->dbb_attachments->att_next) { - ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use, - isc_arg_string, "DATABASE", isc_arg_end); + ERR_post(isc_no_meta_update, + isc_arg_gds, isc_obj_in_use, + isc_arg_string, "DATABASE", + isc_arg_end); } // 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; if (punt) { CCH_unwind(tdbb, false); - ERR_post(isc_shutdown, isc_arg_string, - ERR_cstring(file_name), isc_arg_end); + ERR_post(isc_shutdown, isc_arg_string, ERR_cstring(file_name), isc_arg_end); } else { 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 ERR_post(isc_bad_dpb_content, - isc_arg_gds, isc_charset_not_found, - isc_arg_string, ERR_cstring(options->dpb_lc_ctype), - isc_arg_end); + isc_arg_gds, isc_charset_not_found, + isc_arg_string, ERR_cstring(options->dpb_lc_ctype), + 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 // feature - post an error when they try to access it in 4.0 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 break; @@ -4650,8 +4651,10 @@ static Database* init(thread_db* tdbb, if (attach_flag) return dbb; - ERR_post(isc_no_meta_update, isc_arg_gds, isc_obj_in_use, - isc_arg_string, "DATABASE", isc_arg_end); + ERR_post(isc_no_meta_update, + isc_arg_gds, isc_obj_in_use, + isc_arg_string, "DATABASE", + isc_arg_end); } } #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 - * Initialize secondary database locks. + * Initialize database locks. * **************************************/ 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(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 // 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; lock->lck_type = LCK_monitor; 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); // 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(); dbb->dbb_instance_lock = lock; lock->lck_type = LCK_instance; diff --git a/src/jrd/os/pio.h b/src/jrd/os/pio.h index b5ce2d5968..22cca70b3e 100644 --- a/src/jrd/os/pio.h +++ b/src/jrd/os/pio.h @@ -50,7 +50,6 @@ public: //int *fil_trace; /* Trace file, if any */ Firebird::Mutex fil_mutex; USHORT fil_flags; - USHORT fil_length; /* Length of 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 */ #endif USHORT fil_flags; - USHORT fil_length; /* Length of expanded file name */ SCHAR fil_string[1]; /* Expanded file name */ }; diff --git a/src/jrd/os/pio_proto.h b/src/jrd/os/pio_proto.h index dce7e9a6eb..6f47f6fc91 100644 --- a/src/jrd/os/pio_proto.h +++ b/src/jrd/os/pio_proto.h @@ -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_force_write(Jrd::jrd_file*, const bool, const bool); 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); USHORT PIO_init_data(Jrd::Database*, Jrd::jrd_file*, ISC_STATUS*, ULONG, USHORT); Jrd::jrd_file* PIO_open(Jrd::Database*, const Firebird::PathName&, diff --git a/src/jrd/os/posix/unix.cpp b/src/jrd/os/posix/unix.cpp index 17adbe41da..5e21ef80e6 100644 --- a/src/jrd/os/posix/unix.cpp +++ b/src/jrd/os/posix/unix.cpp @@ -117,7 +117,7 @@ using namespace Firebird; // 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* 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*); #if !(defined HAVE_PREAD && defined HAVE_PWRITE) 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); ISC_expand_filename(expanded_name, false); - jrd_file* file; - try - { - file = setup_file(dbb, expanded_name, desc); - } - catch (const Exception&) - { - close(desc); - throw; - } - return file; + + return setup_file(dbb, expanded_name, desc, false); } @@ -381,9 +372,9 @@ void PIO_force_write(jrd_file* file, const bool forcedWrites, const bool notUseF { ERR_post(isc_io_error, isc_arg_string, "fcntl() SYNC/DIRECT", - isc_arg_cstring, file->fil_length, - ERR_string(file->fil_string, file->fil_length), isc_arg_gds, - isc_io_access_err, isc_arg_unix, errno, isc_arg_end); + isc_arg_string, ERR_cstring(file->fil_string), + isc_arg_gds, isc_io_access_err, + isc_arg_unix, errno, isc_arg_end); } #else //FCNTL_BROKEN 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) { 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_gds, isc_io_open_err, isc_arg_unix, errno, isc_arg_end); + isc_arg_string, ERR_cstring(file->fil_string), + isc_arg_gds, isc_io_open_err, + isc_arg_unix, errno, isc_arg_end); } #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) { /************************************** @@ -601,7 +619,7 @@ jrd_file* PIO_open(Database* dbb, if (desc == -1) { ERR_post(isc_io_error, 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); } /* 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, 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, ENOENT, isc_arg_end); } #endif /* SUPPORT_RAW_DEVICES */ - jrd_file *file; - try { - file = setup_file(dbb, string, desc); - if (readOnly) - file->fil_flags |= FIL_readonly; - } - catch (const Exception&) { - close(desc); - throw; - } - return file; + return setup_file(dbb, string, desc, readOnly); } @@ -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. * **************************************/ + 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(); - file->fil_desc = desc; - file->fil_max_page = MAX_ULONG; - file->fil_length = file_name.length(); - strcpy(file->fil_string, file_name.c_str()); - -/* If this isn't the primary file, we're done */ - - 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(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; - } - } + if (read_only) + file->fil_flags |= FIL_readonly; + } + catch (const Exception&) + { + close(desc); + delete file; + throw; } + fb_assert(file); return file; } @@ -1011,7 +959,7 @@ static bool unix_error(const TEXT* string, *status++ = isc_arg_string; *status++ = (ISC_STATUS) string; // pointer to ISC_STATUS!!! *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++ = operation; *status++ = isc_arg_unix; @@ -1023,8 +971,7 @@ static bool unix_error(const TEXT* string, ERR_post(isc_io_error, 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_unix, errno, isc_arg_end); @@ -1180,7 +1127,7 @@ static bool raw_devices_validate_database(int desc, const PathName& file_name) if (desc == -1) ERR_post (isc_io_error, 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_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) ERR_post (isc_io_error, 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_unix, errno, isc_arg_end); 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)) ERR_post (isc_io_error, 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_unix, errno, isc_arg_end); } ERR_post (isc_io_error, 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_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) ERR_post (isc_io_error, 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_unix, errno, isc_arg_end); @@ -1256,7 +1203,7 @@ static int raw_devices_unlink_database(const PathName& file_name) if (!SYSCALL_INTERRUPTED(errno)) ERR_post (isc_io_error, 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_unix, errno, isc_arg_end); } @@ -1272,7 +1219,7 @@ static int raw_devices_unlink_database(const PathName& file_name) continue; ERR_post (isc_io_error, 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_unix, errno, isc_arg_end); } diff --git a/src/jrd/os/win32/winnt.cpp b/src/jrd/os/win32/winnt.cpp index f6b5872f51..df52bda42c 100644 --- a/src/jrd/os/win32/winnt.cpp +++ b/src/jrd/os/win32/winnt.cpp @@ -107,7 +107,7 @@ static void release_io_event(jrd_file*, OVERLAPPED*); #endif static bool maybe_close_file(HANDLE&); 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*); #ifdef SUPERSERVER_V2 @@ -229,7 +229,7 @@ jrd_file* PIO_create(Database* dbb, const Firebird::PathName& string, { ERR_post(isc_io_error, 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(), 0); } @@ -239,16 +239,8 @@ jrd_file* PIO_create(Database* dbb, const Firebird::PathName& string, Firebird::PathName workspace(string); 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, isc_arg_string, "CreateFile (force write)", - 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_access_err, isc_arg_win32, GetLastError(), @@ -591,8 +582,7 @@ jrd_file* PIO_open(Database* dbb, ERR_post(isc_io_error, isc_arg_string, "CreateFile (open)", - isc_arg_cstring, - file_name.length(), + isc_arg_string, ERR_cstring(file_name), isc_arg_gds, isc_io_open_err, isc_arg_win32, GetLastError(), 0); @@ -610,18 +600,7 @@ jrd_file* PIO_open(Database* dbb, } } - jrd_file *file; - try { - file = setup_file(dbb, string, desc); - - if (readOnly) - file->fil_flags |= FIL_readonly; - } - catch (const Firebird::Exception&) { - CloseHandle(desc); - throw; - } - return file; + return setup_file(dbb, string, desc, readOnly); } @@ -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 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, - const Firebird::PathName& file_name, - HANDLE desc) +static jrd_file* setup_file(Database* dbb, + const Firebird::PathName& file_name, + 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. * **************************************/ + jrd_file* file = NULL; -/* Allocate file block and copy file name string */ - - jrd_file* file = FB_NEW_RPT(*dbb->dbb_permanent, file_name.length() + 1) jrd_file(); - file->fil_desc = desc; - file->fil_max_page = MAX_ULONG; - file->fil_length = file_name.length(); - strcpy(file->fil_string, file_name.c_str()); + 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()); #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 -/* 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 (pageSpace && pageSpace->file) - return file; + // If this isn't the primary file, we're done -/* 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; - GetFileInformationByHandle(desc, &file_info); - UCHAR lock_string[32]; - UCHAR* p = lock_string; - - // 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. - 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(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; - } - } + file->fil_ext_lock = FB_NEW(*dbb->dbb_permanent) Firebird::RWLock(); + } + catch (const Firebird::Exception&) + { + CloseHandle(desc); + delete file; + throw; } + fb_assert(file); return file; } @@ -1185,8 +1140,7 @@ static bool nt_error(TEXT* string, *status_vector++ = isc_arg_string; *status_vector++ = (ISC_STATUS) string; *status_vector++ = isc_arg_string; - *status_vector++ = - (ISC_STATUS)(U_IPTR) ERR_string(file->fil_string, file->fil_length); + *status_vector++ = (ISC_STATUS)(U_IPTR) ERR_cstring(file->fil_string); *status_vector++ = isc_arg_gds; *status_vector++ = operation; *status_vector++ = isc_arg_win32; @@ -1197,7 +1151,7 @@ static bool nt_error(TEXT* string, ERR_post(isc_io_error, 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); return true; diff --git a/src/jrd/pag.cpp b/src/jrd/pag.cpp index e72a26261d..3aee6eb42b 100644 --- a/src/jrd/pag.cpp +++ b/src/jrd/pag.cpp @@ -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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); CHECK_DBB(dbb); /* 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. // 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 * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); + SET_TDBB(tdbb); WIN window(LOG_PAGE_NUMBER); 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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); Attachment* attachment = tdbb->getAttachment(); 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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); - Attachment* attachment = tdbb->getAttachment(); + Attachment* const attachment = tdbb->getAttachment(); fb_assert(attachment); // 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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); CHECK_DBB(dbb); 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. * **************************************/ - thread_db* tdbb = JRD_get_thread_data(); - Database* dbb = tdbb->getDatabase(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); ISC_STATUS* status = tdbb->tdbb_status_vector; /* allocate a spare buffer which is large enough, diff --git a/src/jrd/pag_proto.h b/src/jrd/pag_proto.h index e189ed6179..0c3a76d507 100644 --- a/src/jrd/pag_proto.h +++ b/src/jrd/pag_proto.h @@ -44,14 +44,14 @@ int PAG_replace_entry_first(Ods::header_page*, USHORT, USHORT, const UCHAR*); Ods::pag* PAG_allocate(Jrd::win *); SLONG PAG_attachment_id(Jrd::thread_db*); int PAG_delete_clump_entry(SLONG, USHORT); -void PAG_format_header(); -void PAG_format_log(); +void PAG_format_header(Jrd::thread_db*); +void PAG_format_log(Jrd::thread_db*); void PAG_format_pip(Jrd::thread_db*, Jrd::PageSpace& pageSpace); bool PAG_get_clump(SLONG, USHORT, USHORT*, UCHAR*); -void PAG_header(bool); -void PAG_header_init(); -void PAG_init(); -void PAG_init2(USHORT); +void PAG_header(Jrd::thread_db*, bool); +void PAG_header_init(Jrd::thread_db*); +void PAG_init(Jrd::thread_db*); +void PAG_init2(Jrd::thread_db*, USHORT); SLONG PAG_last_page(); void PAG_release_page(const Jrd::PageNumber&, const Jrd::PageNumber&); void PAG_set_force_write(Jrd::Database*, bool); diff --git a/src/jrd/qatest.cpp b/src/jrd/qatest.cpp index 79497ad3d9..0746262850 100644 --- a/src/jrd/qatest.cpp +++ b/src/jrd/qatest.cpp @@ -132,7 +132,6 @@ int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3) * These entrypoints are *NOT* designed for customer use! * **************************************/ - char filename[MAXPATHLEN]; Shadow* shadow; #ifdef WIN_NT HANDLE desc; @@ -159,23 +158,19 @@ int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3) return -1; #ifdef WIN_NT - desc = (HANDLE) ((file->fil_flags & FIL_force_write) ? file->fil_force_write_desc : file->fil_desc); CloseHandle(desc); - desc = INVALID_HANDLE_VALUE; #else close(file->fil_desc); #endif - strncpy((char *) filename, file->fil_string, file->fil_length); - filename[file->fil_length] = 0; #ifdef WIN_NT - DeleteFile(filename); + DeleteFile(file->fil_string); #else - unlink(filename); + unlink(file->fil_string); #endif return 0; @@ -184,29 +179,27 @@ int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3) /* Close & delete specified shadow file */ tdbb = JRD_get_thread_data(); + if (!(shadow = dbb->dbb_shadow)) return -1; + for (; shadow; shadow = shadow->sdw_next) if (shadow->sdw_number == *(ULONG *) arg1) { #ifdef WIN_NT - desc = (HANDLE) ((shadow->sdw_file->fil_flags & FIL_force_write) ? shadow->sdw_file->fil_force_write_desc : shadow->sdw_file->fil_desc); CloseHandle(desc); - desc = INVALID_HANDLE_VALUE; #else close(shadow->sdw_file->fil_desc); #endif - strncpy((char *) filename, shadow->sdw_file->fil_string, - shadow->sdw_file->fil_length); - filename[shadow->sdw_file->fil_length] = 0; + #ifdef WIN_NT - DeleteFile(filename); + DeleteFile(shadow->sdw_file->fil_string); #else - unlink(filename); + unlink(shadow->sdw_file->fil_string); #endif return 0; } diff --git a/src/jrd/sdw.cpp b/src/jrd/sdw.cpp index e3c6205ef1..4d7c38ca70 100644 --- a/src/jrd/sdw.cpp +++ b/src/jrd/sdw.cpp @@ -1057,7 +1057,8 @@ void SDW_start(const TEXT* file_name, /* get the ancillary files and reset the error environment */ - PAG_init2(shadow_number); + PAG_init2(tdbb, shadow_number); + if (spare_buffer) delete[] spare_buffer;