diff --git a/src/burp/restore.epp b/src/burp/restore.epp index f992afd2b2..bdd59a7a19 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -4204,53 +4204,85 @@ bool get_files(BurpGlobals* tdgbl) att_type attribute; scan_attr_t scan_next_attr; - STORE (REQUEST_HANDLE tdgbl->handles_get_files_req_handle1) - X IN RDB$FILES - X.RDB$FILE_FLAGS = 0; + BASED_ON RDB$FILES.RDB$FILE_NAME filename = ""; + SSHORT flags = 0, sequence = 0, number = 0; + SLONG start = 0, length = 0; - skip_init(&scan_next_attr); - while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_end) + skip_init(&scan_next_attr); + while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_end) + { + switch (attribute) { - switch (attribute) - { - case att_file_filename: - GET_TEXT(X.RDB$FILE_NAME); - BURP_verbose (116, X.RDB$FILE_NAME); - // msg 116 restoring file %s - break; + case att_file_filename: + GET_TEXT(filename); + break; - case att_file_sequence: - X.RDB$FILE_SEQUENCE = (USHORT) get_int32(tdgbl); - break; + case att_file_sequence: + sequence = (SSHORT) get_int32(tdgbl); + break; - case att_file_start: - X.RDB$FILE_START = get_int32(tdgbl); - break; + case att_file_start: + start = get_int32(tdgbl); + break; - case att_file_length: - X.RDB$FILE_LENGTH = get_int32(tdgbl); - break; + case att_file_length: + length = get_int32(tdgbl); + break; - case att_file_flags: - X.RDB$FILE_FLAGS |= get_int32(tdgbl); - break; + case att_file_flags: + flags |= (SSHORT) get_int32(tdgbl); + break; - case att_shadow_number: - X.RDB$SHADOW_NUMBER = (USHORT) get_int32(tdgbl); - if (tdgbl->gbl_sw_kill && X.RDB$SHADOW_NUMBER) - X.RDB$FILE_FLAGS |= FILE_inactive; - break; + case att_shadow_number: + number = (SSHORT) get_int32(tdgbl); + if (tdgbl->gbl_sw_kill && number) + flags |= FILE_inactive; + break; - default: - bad_attribute(scan_next_attr, attribute, 85); - // msg 85 file - break; - } + default: + bad_attribute(scan_next_attr, attribute, 85); + // msg 85 file + break; } - END_STORE; - ON_ERROR - general_on_error (); - END_ERROR; + } + + const bool multiFileSupport = (tdgbl->runtimeODS <= DB_VERSION_DDL13_1); + + if ((multiFileSupport || !sequence) && filename[0]) + { + BURP_verbose (116, filename); + // msg 116 restoring file %s + + STORE (REQUEST_HANDLE tdgbl->handles_get_files_req_handle1) + X IN RDB$FILES + + strncpy(X.RDB$FILE_NAME, filename, sizeof(X.RDB$FILE_NAME)); + X.RDB$FILE_FLAGS = flags; + X.RDB$SHADOW_NUMBER = number; + + if (multiFileSupport) + { + X.RDB$FILE_SEQUENCE.NULL = FALSE; + X.RDB$FILE_SEQUENCE = sequence; + + X.RDB$FILE_START.NULL = FALSE; + X.RDB$FILE_START = start; + + X.RDB$FILE_LENGTH.NULL = FALSE; + X.RDB$FILE_LENGTH = length; + } + else + { + X.RDB$FILE_SEQUENCE.NULL = TRUE; + X.RDB$FILE_START.NULL = TRUE; + X.RDB$FILE_LENGTH.NULL = TRUE; + } + + END_STORE; + ON_ERROR + general_on_error (); + END_ERROR; + } return true; } diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index e355ded4c0..5a3cd5eed3 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -80,9 +80,6 @@ static void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* dsql_fld* field, ValueSourceClause* clause, string& source, BlrDebugWriter::BlrData& value); static void deleteKeyConstraint(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& constraintName, const MetaName& indexName); -static void defineFile(thread_db* tdbb, jrd_tra* transaction, SLONG shadowNumber, bool manualShadow, - bool conditionalShadow, SLONG& dbAlloc, - const PathName& name, SLONG start, SLONG length); static bool fieldExists(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& fieldName); static bool isItSqlRole(thread_db* tdbb, jrd_tra* transaction, const MetaName& inputName, @@ -490,46 +487,6 @@ static void deleteKeyConstraint(thread_db* tdbb, jrd_tra* transaction, } } -// Define a database or shadow file. -static void defineFile(thread_db* tdbb, jrd_tra* transaction, SLONG shadowNumber, bool manualShadow, - bool conditionalShadow, SLONG& dbAlloc, const PathName& name, SLONG start, SLONG length) -{ - PathName expandedName = name; - - if (!ISC_expand_filename(expandedName, false)) - status_exception::raise(Arg::PrivateDyn(231)); // File name is invalid. - - if (tdbb->getDatabase()->dbb_filename == expandedName) - status_exception::raise(Arg::PrivateDyn(166)); - - AutoCacheRequest request(tdbb, drq_l_files, DYN_REQUESTS); - - FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) - FIRST 1 X IN RDB$FILES - WITH X.RDB$FILE_NAME EQ expandedName.c_str() - { - status_exception::raise(Arg::PrivateDyn(166)); - } - END_FOR - - request.reset(tdbb, drq_s_files, DYN_REQUESTS); - - STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) - X IN RDB$FILES - { - expandedName.copyTo(X.RDB$FILE_NAME, sizeof(X.RDB$FILE_NAME)); - X.RDB$SHADOW_NUMBER = shadowNumber; - X.RDB$FILE_FLAGS = (manualShadow ? FILE_manual : 0) | - (conditionalShadow ? FILE_conditional : 0); - - dbAlloc = MAX(dbAlloc, start); - X.RDB$FILE_START = dbAlloc; - X.RDB$FILE_LENGTH = length; - dbAlloc += length; - } - END_STORE -} - // Checks to see if the given field already exists in a relation. static bool fieldExists(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& fieldName) @@ -10462,7 +10419,7 @@ string CreateShadowNode::internalPrint(NodePrinter& printer) const NODE_PRINT(printer, number); NODE_PRINT(printer, manual); NODE_PRINT(printer, conditional); - NODE_PRINT(printer, files); + NODE_PRINT(printer, fileName); return "CreateShadowNode"; } @@ -10486,7 +10443,7 @@ void CreateShadowNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScrat // run all statements under savepoint control AutoSavePoint savePoint(tdbb, transaction); - // If a shadow set identified by the shadow number already exists return error. + // If a shadow set identified by the shadow number already exists return error AutoCacheRequest request(tdbb, drq_l_shadow, DYN_REQUESTS); @@ -10502,25 +10459,34 @@ void CreateShadowNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScrat } END_FOR - SLONG start = 0; + PathName expandedName = fileName.ToPathName(); - for (NestConst* i = files.begin(); i != files.end(); ++i) + if (!ISC_expand_filename(expandedName, false)) + status_exception::raise(Arg::PrivateDyn(231)); // File name is invalid + + if (tdbb->getDatabase()->dbb_filename == expandedName) + status_exception::raise(Arg::PrivateDyn(166)); + + request.reset(tdbb, drq_l_files, DYN_REQUESTS); + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + FIRST 1 X IN RDB$FILES + WITH X.RDB$FILE_NAME EQ expandedName.c_str() { - bool first = i == files.begin(); - DbFileClause* file = *i; - - if (!first && i[-1]->length == 0 && file->start == 0) - { - // Preceding file did not specify length, so %s must include starting page number - status_exception::raise( - Arg::Gds(isc_sqlerr) << Arg::Num(-607) << - Arg::Gds(isc_dsql_command_err) << - Arg::Gds(isc_dsql_file_length_err) << file->name); - } - - defineFile(tdbb, transaction, number, manual && first, conditional && first, - start, file->name.c_str(), file->start, file->length); + status_exception::raise(Arg::PrivateDyn(166)); } + END_FOR + + request.reset(tdbb, drq_s_files, DYN_REQUESTS); + + STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + X IN RDB$FILES + { + expandedName.copyTo(X.RDB$FILE_NAME, sizeof(X.RDB$FILE_NAME)); + X.RDB$SHADOW_NUMBER = number; + X.RDB$FILE_FLAGS = (manual ? FILE_manual : 0) | (conditional ? FILE_conditional : 0); + } + END_STORE savePoint.release(); // everything is ok } @@ -12742,13 +12708,11 @@ string AlterDatabaseNode::internalPrint(NodePrinter& printer) const DdlNode::internalPrint(printer); NODE_PRINT(printer, create); - NODE_PRINT(printer, createLength); NODE_PRINT(printer, linger); NODE_PRINT(printer, clauses); NODE_PRINT(printer, differenceFile); NODE_PRINT(printer, setDefaultCharSet); NODE_PRINT(printer, setDefaultCollation); - NODE_PRINT(printer, files); NODE_PRINT(printer, cryptPlugin); NODE_PRINT(printer, keyName); @@ -12924,18 +12888,6 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc } } - SLONG dbAlloc = PageSpace::maxAlloc(tdbb->getDatabase()); - SLONG start = create ? createLength + 1 : 0; - for (NestConst* i = files.begin(); i != files.end(); ++i) - { - DbFileClause* file = *i; - - start = MAX(start, file->start); - defineFile(tdbb, transaction, 0, false, false, dbAlloc, - file->name.c_str(), start, file->length); - start += file->length; - } - if (differenceFile.hasData()) defineDifference(tdbb, transaction, differenceFile.c_str()); @@ -13064,7 +13016,6 @@ void AlterDatabaseNode::changeBackupMode(thread_db* tdbb, jrd_tra* transaction, X IN RDB$FILES { X.RDB$FILE_FLAGS = FILE_difference | FILE_backing_up; - X.RDB$FILE_START = 0; } END_STORE @@ -13116,7 +13067,6 @@ void AlterDatabaseNode::defineDifference(thread_db* tdbb, jrd_tra* transaction, strcpy(FIL.RDB$FILE_NAME, file.c_str()); FIL.RDB$FILE_FLAGS = FILE_difference; - FIL.RDB$FILE_START = 0; } END_STORE } diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index ffa46aa959..7f3f1b15df 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -101,40 +101,6 @@ public: }; -class DbFileClause : public Printable -{ -public: - DbFileClause(MemoryPool& p, const DbFileClause& o) - : name(p, o.name), - start(o.start), - length(o.length) - { - } - - explicit DbFileClause(MemoryPool& p, const Firebird::string& aName) - : name(p, aName), - start(0), - length(0) - { - } - -public: - virtual Firebird::string internalPrint(NodePrinter& printer) const - { - NODE_PRINT(printer, name); - NODE_PRINT(printer, start); - NODE_PRINT(printer, length); - - return "DbFileClause"; - } - -public: - Firebird::string name; // File name - SLONG start; // Starting page - SLONG length; // File length in pages -}; - - class ExternalClause : public Printable { public: @@ -1967,12 +1933,13 @@ public: class CreateShadowNode : public DdlNode { public: - CreateShadowNode(MemoryPool& p, const SSHORT aNumber) + CreateShadowNode(MemoryPool& p, SSHORT aNumber, bool aManual, bool aConditional, + const Firebird::string& aFileName) : DdlNode(p), number(aNumber), - manual(false), - conditional(false), - files(p) + manual(aManual), + conditional(aConditional), + fileName(p, aFileName) { } @@ -1996,7 +1963,7 @@ public: SSHORT number; bool manual; bool conditional; - Firebird::Array > files; + Firebird::string fileName; bool createIfNotExistsOnly = false; }; @@ -2425,14 +2392,9 @@ public: public: AlterDatabaseNode(MemoryPool& p) : DdlNode(p), - create(false), - createLength(0), - linger(-1), - clauses(0), differenceFile(p), setDefaultCharSet(p), setDefaultCollation(p), - files(p), cryptPlugin(p), keyName(p), pubTables(p) @@ -2468,13 +2430,12 @@ private: void checkClauses(thread_db* tdbb); public: - bool create; // Is the node created with a CREATE DATABASE command? - SLONG createLength, linger; - unsigned clauses; + bool create = false; // Is the node created with a CREATE DATABASE command? + SLONG linger = -1; + unsigned clauses = 0; Firebird::string differenceFile; MetaName setDefaultCharSet; MetaName setDefaultCollation; - Firebird::Array > files; MetaName cryptPlugin; MetaName keyName; Firebird::TriState ssDefiner; diff --git a/src/dsql/parse.y b/src/dsql/parse.y index bcfbd50833..c44adee3e8 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -767,8 +767,6 @@ using namespace Firebird; Firebird::string* stringPtr; Jrd::IntlString* intlStringPtr; Jrd::Lim64String* lim64ptr; - Jrd::DbFileClause* dbFileClause; - Firebird::Array >* dbFilesClause; Jrd::ExternalClause* externalClause; Firebird::NonPooledPair* namedArgument; Firebird::NonPooledPair*, Jrd::ValueListNode*>* namedArguments; @@ -1807,16 +1805,8 @@ index_condition_opt // CREATE SHADOW %type shadow_clause shadow_clause - : pos_short_integer manual_auto conditional utf_string first_file_length - { - $$ = newNode($1); - $$->manual = $2; - $$->conditional = $3; - $$->files.add(newNode(*$4)); - $$->files.front()->length = $5; - } - sec_shadow_files(NOTRIAL(&$6->files)) - { $$ = $6; } + : pos_short_integer manual_auto conditional utf_string + { $$ = newNode($1, $2, $3, *$4); } ; %type manual_auto @@ -1832,24 +1822,6 @@ conditional | CONDITIONAL { $$ = true; } ; -%type first_file_length -first_file_length - : /* nothing */ { $$ = 0; } - | LENGTH equals long_integer page_noise { $$ = $3; } - ; - -%type sec_shadow_files() -sec_shadow_files($dbFilesClause) - : // nothing - | db_file_list($dbFilesClause) - ; - -%type db_file_list() -db_file_list($dbFilesClause) - : db_file { $dbFilesClause->add($1); } - | db_file_list db_file { $dbFilesClause->add($2); } - ; - // CREATE DOMAIN @@ -2279,8 +2251,6 @@ db_initial_option($alterDatabaseNode) | ROLE utf_string | PASSWORD utf_string | SET NAMES utf_string - | LENGTH equals long_integer page_noise - { $alterDatabaseNode->createLength = $3; } ; %type db_rem_desc1() @@ -2297,9 +2267,7 @@ db_rem_desc($alterDatabaseNode) %type db_rem_option() db_rem_option($alterDatabaseNode) - : db_file - { $alterDatabaseNode->files.add($1); } - | DEFAULT CHARACTER SET symbol_character_set_name + : DEFAULT CHARACTER SET symbol_character_set_name { $alterDatabaseNode->setDefaultCharSet = *$4; } | DEFAULT CHARACTER SET symbol_character_set_name COLLATION symbol_collation_name { @@ -2310,49 +2278,6 @@ db_rem_option($alterDatabaseNode) { $alterDatabaseNode->differenceFile = *$3; } ; -%type db_file -db_file - : FILE utf_string - { - DbFileClause* clause = newNode(*$2); - $$ = clause; - } - file_desc1($3) - { $$ = $3; } - ; - -%type file_desc1() -file_desc1($dbFileClause) - : // nothing - | file_desc($dbFileClause) - ; - -%type file_desc() -file_desc($dbFileClause) - : file_clause($dbFileClause) - | file_desc file_clause($dbFileClause) - ; - -%type file_clause() -file_clause($dbFileClause) - : STARTING file_clause_noise long_integer - { $dbFileClause->start = $3; } - | LENGTH equals long_integer page_noise - { $dbFileClause->length = $3; } - ; - -file_clause_noise - : // nothing - | AT - | AT PAGE - ; - -page_noise - : // nothing - | PAGE - | PAGES - ; - // CREATE TABLE @@ -4770,8 +4695,7 @@ alter_db($alterDatabaseNode) %type db_alter_clause() db_alter_clause($alterDatabaseNode) - : ADD db_file_list(NOTRIAL(&$alterDatabaseNode->files)) - | ADD DIFFERENCE FILE utf_string + : ADD DIFFERENCE FILE utf_string { $alterDatabaseNode->differenceFile = *$4; } | DROP DIFFERENCE FILE { $alterDatabaseNode->clauses |= AlterDatabaseNode::CLAUSE_DROP_DIFFERENCE; } diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp index c966e4ea7e..6f097e8e54 100644 --- a/src/jrd/cch.cpp +++ b/src/jrd/cch.cpp @@ -2489,15 +2489,6 @@ bool CCH_write_all_shadows(thread_db* tdbb, Shadow* shadow, BufferDesc* bdb, Ods PAG_add_header_entry(tdbb, header, HDR_root_file_name, (USHORT) strlen((const char*) q), q); - jrd_file* next_file = shadow_file->fil_next; - if (next_file) - { - q = (UCHAR *) next_file->fil_string; - const SLONG last = next_file->fil_min_page - 1; - PAG_add_header_entry(tdbb, header, HDR_file, (USHORT) strlen((const char*) q), q); - PAG_add_header_entry(tdbb, header, HDR_last_page, sizeof(last), (const UCHAR*) &last); - } - header->hdr_flags |= hdr_active_shadow; header->hdr_header.pag_pageno = bdb->bdb_page.getPageNum(); } diff --git a/src/jrd/dfw.epp b/src/jrd/dfw.epp index 2609eef97e..1edc4ff4ee 100644 --- a/src/jrd/dfw.epp +++ b/src/jrd/dfw.epp @@ -56,7 +56,7 @@ * BUGCHECK(291) took place. To avoid that issue, it was decided not to modify data * in system transaction. An exception is RDB$FORMATS relation, which is always modified * by transaction zero. Also an aspect of 'dirty' access from system transaction was - * taken into an account in add_file(), make_version() and create_index(). + * taken into an account in make_version() and create_index(). * */ @@ -449,7 +449,6 @@ private: * *================================================================== */ -static bool add_file(thread_db*, SSHORT, DeferredWork*, jrd_tra*); static bool add_shadow(thread_db*, SSHORT, DeferredWork*, jrd_tra*); static bool delete_shadow(thread_db*, SSHORT, DeferredWork*, jrd_tra*); static bool compute_security(thread_db*, SSHORT, DeferredWork*, jrd_tra*); @@ -1272,7 +1271,6 @@ namespace static const deferred_task task_table[] = { - { dfw_add_file, add_file }, { dfw_add_shadow, add_shadow }, { dfw_delete_index, modify_index }, { dfw_delete_rfr, delete_rfr }, @@ -1876,133 +1874,6 @@ void DFW_update_index(const TEXT* name, USHORT id, const SelectivityList& select } -static bool add_file(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra* transaction) -{ -/************************************** - * - * a d d _ f i l e - * - ************************************** - * - * Functional description - * Add a file to a database. - * This file could be a regular database - * file or a shadow file. Either way we - * require exclusive access to the database. - * - **************************************/ - USHORT section, shadow_number; - SLONG start, min_start; - - SET_TDBB(tdbb); - Database* const dbb = tdbb->getDatabase(); - - switch (phase) - { - case 0: - CCH_release_exclusive(tdbb); - return false; - - case 1: - case 2: - return true; - - case 3: - if (!CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD, NULL)) - raiseDatabaseInUseError(true); - return true; - - case 4: - CCH_flush(tdbb, FLUSH_FINI, 0); - start = PageSpace::maxAlloc(dbb) + 1; - AutoRequest handle; - AutoRequest handle2; - - // Check the file name for node name. This has already - // been done for shadows in add_shadow() - - if (work->dfw_type != dfw_add_shadow) { - check_filename(work->dfw_name, true); - } - - // User transaction may be safely used instead of system, cause - // we requested and got exclusive database access. AP-2008. - - // get any files to extend into - - FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) X IN RDB$FILES - WITH X.RDB$FILE_NAME EQ work->dfw_name.c_str() - // First expand the file name This has already been done - // for shadows in add_shadow ()) - if (work->dfw_type != dfw_add_shadow) - { - MODIFY X USING - ISC_expand_filename(X.RDB$FILE_NAME, 0, - X.RDB$FILE_NAME, sizeof(X.RDB$FILE_NAME), false); - END_MODIFY - } - - // Check the previous file length - FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction) - FIRST 1 Y IN RDB$FILES - WITH Y.RDB$SHADOW_NUMBER EQ X.RDB$SHADOW_NUMBER - AND Y.RDB$FILE_SEQUENCE NOT MISSING - SORTED BY DESCENDING Y.RDB$FILE_SEQUENCE - { - if (!Y.RDB$FILE_START.NULL && !Y.RDB$FILE_LENGTH.NULL) - { - min_start = Y.RDB$FILE_START + (Y.RDB$FILE_LENGTH ? Y.RDB$FILE_LENGTH : 1); - start = MAX(min_start, start); - } - } - END_FOR - - // If there is no starting position specified, or if it is - // too low a value, raise the error. - if (X.RDB$FILE_START < start) - { - ERR_post(Arg::Gds(isc_file_starting_page_err) << - Arg::Str(X.RDB$FILE_NAME) << Arg::Num(start)); - } - - start = X.RDB$FILE_START; - - shadow_number = X.RDB$SHADOW_NUMBER; - if ((shadow_number && - (section = SDW_add_file(tdbb, X.RDB$FILE_NAME, start, shadow_number))) || - (section = PAG_add_file(tdbb, X.RDB$FILE_NAME, start))) - { - MODIFY X USING - X.RDB$FILE_SEQUENCE = section; - X.RDB$FILE_START = start; - END_MODIFY - } - END_FOR - - if (section) - { - handle.reset(); - section--; - FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) X IN RDB$FILES - WITH X.RDB$FILE_SEQUENCE EQ section - AND X.RDB$SHADOW_NUMBER EQ shadow_number - { - MODIFY X USING - X.RDB$FILE_LENGTH = start - X.RDB$FILE_START; - END_MODIFY - } - END_FOR - } - - CCH_release_exclusive(tdbb); - break; - } - - return false; -} - - - static bool add_shadow(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra* transaction) { /************************************** @@ -2053,11 +1924,11 @@ static bool add_shadow(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tr finished = false; handle.reset(); FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) - F IN RDB$FILES - WITH F.RDB$FILE_NAME EQ work->dfw_name.c_str() - + F IN RDB$FILES WITH F.RDB$FILE_NAME EQ work->dfw_name.c_str() + { expanded_fname = F.RDB$FILE_NAME; ISC_expand_filename(expanded_fname, false); + MODIFY F USING expanded_fname.copyTo(F.RDB$FILE_NAME, sizeof(F.RDB$FILE_NAME)); END_MODIFY @@ -2066,94 +1937,34 @@ static bool add_shadow(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tr { if ((F.RDB$SHADOW_NUMBER == shadow->sdw_number) && !(shadow->sdw_flags & SDW_IGNORE)) { - if (F.RDB$FILE_FLAGS & FILE_shadow) - { - // This is the case of a bogus duplicate posted - // work when we added a multi-file shadow - finished = true; - } - else if (shadow->sdw_flags & (SDW_dumped)) - { - /* Case of adding a file to a currently active - * shadow set. - * Note: as of 1995-January-31 there is - * no SQL syntax that supports this, but there - * may be GDML - */ - add_file(tdbb, 3, work, transaction); - add_file(tdbb, 4, work, transaction); - finished = true; - } - else + if (!(F.RDB$FILE_FLAGS & FILE_shadow)) { // We cannot add a file to a shadow that is still // in the process of being created. raiseDatabaseInUseError(false); } + + // This is the case of a bogus duplicate posted + // work when we added a multi-file shadow + finished = true; break; } } - + } END_FOR if (finished) return false; - // this file is part of a new shadow, so get all files for the shadow - // in order of the starting page for the file - - // Note that for a multi-file shadow, we have several pieces of - // work posted (one dfw_add_shadow for each file). Rather than - // trying to cancel the other pieces of work we ignore them - // when they arrive in this routine. - - sequence = 0; - min_page = 0; - shadow = NULL; handle.reset(); FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction) - X IN RDB$FILES CROSS - Y IN RDB$FILES - OVER RDB$SHADOW_NUMBER - WITH X.RDB$FILE_NAME EQ expanded_fname.c_str() - SORTED BY Y.RDB$FILE_START + F IN RDB$FILES WITH F.RDB$FILE_NAME EQ expanded_fname.c_str() { - // for the first file, create a brand new shadow; for secondary - // files that have a starting page specified, add a file - if (!sequence) - SDW_add(tdbb, Y.RDB$FILE_NAME, Y.RDB$SHADOW_NUMBER, Y.RDB$FILE_FLAGS); - else if (Y.RDB$FILE_START) - { - if (!shadow) - { - for (shadow = dbb->dbb_shadow; shadow; shadow = shadow->sdw_next) - { - if ((Y.RDB$SHADOW_NUMBER == shadow->sdw_number) && - !(shadow->sdw_flags & SDW_IGNORE)) - { - break; - } - } - } + SDW_add(tdbb, F.RDB$FILE_NAME, F.RDB$SHADOW_NUMBER, F.RDB$FILE_FLAGS); - if (!shadow) - BUGCHECK(203); // msg 203 shadow block not found for extend file - - min_page = MAX((min_page + 1), (ULONG) Y.RDB$FILE_START); - add_sequence = SDW_add_file(tdbb, Y.RDB$FILE_NAME, min_page, Y.RDB$SHADOW_NUMBER); - } - - // update the sequence number and bless the file entry as being good - - if (!sequence || (Y.RDB$FILE_START && add_sequence)) - { - MODIFY Y - Y.RDB$FILE_FLAGS |= FILE_shadow; - Y.RDB$FILE_SEQUENCE = sequence; - Y.RDB$FILE_START = min_page; - END_MODIFY - sequence++; - } + MODIFY F + F.RDB$FILE_FLAGS |= FILE_shadow; + END_MODIFY } END_FOR diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 0706bbeeb6..2d0fea9563 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -1301,7 +1301,7 @@ private: static void check_database(thread_db* tdbb, bool async = false); static void commit(thread_db*, jrd_tra*, const bool); -static bool drop_files(const jrd_file*); +static bool drop_file(Database*, const jrd_file*); static void find_intl_charset(thread_db*, Jrd::Attachment*, const DatabaseOptions*); static void init_database_lock(thread_db*); static void run_commit_triggers(thread_db* tdbb, jrd_tra* transaction); @@ -1831,7 +1831,7 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_permanent) CryptoManager(tdbb); dbb->dbb_monitoring_data = FB_NEW_POOL(*dbb->dbb_permanent) MonitoringData(dbb); - PAG_init2(tdbb, 0); + PAG_init2(tdbb); PAG_header(tdbb, false, newForceWrite); dbb->dbb_page_manager.initTempPageSpace(tdbb); dbb->dbb_crypto_manager->attach(tdbb, attachment); @@ -3552,11 +3552,9 @@ void JAttachment::internalDropDatabase(CheckStatusWrapper* user_status) // This point on database is useless // drop the files here - bool err = drop_files(file); + bool err = drop_file(dbb, file); for (; shadow; shadow = shadow->sdw_next) - { - err = drop_files(shadow->sdw_file) || err; - } + err = drop_file(dbb, shadow->sdw_file) || err; tdbb->setDatabase(NULL); Database::destroy(dbb); @@ -6797,31 +6795,28 @@ static void commit(thread_db* tdbb, jrd_tra* transaction, const bool retaining_f } -static bool drop_files(const jrd_file* file) +static bool drop_file(Database* dbb, const jrd_file* file) { /************************************** * - * d r o p _ f i l e s + * d r o p _ f i l e * ************************************** * * Functional description - * drop a linked list of files + * Drop a file. * **************************************/ FbLocalStatus status; - for (; file; file = file->fil_next) + if (unlink(file->fil_string)) { - if (unlink(file->fil_string)) - { - ERR_build_status(&status, Arg::Gds(isc_io_error) << Arg::Str("unlink") << - Arg::Str(file->fil_string) << - Arg::Gds(isc_io_delete_err) << SYS_ERR(errno)); - Database* dbb = GET_DBB(); - PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); - iscDbLogStatus(pageSpace->file->fil_string, &status); - } + ERR_build_status(&status, Arg::Gds(isc_io_error) << Arg::Str("unlink") << + Arg::Str(file->fil_string) << + Arg::Gds(isc_io_delete_err) << SYS_ERR(errno)); + + PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); + iscDbLogStatus(pageSpace->file->fil_string, &status); } return status->getState() & IStatus::STATE_ERRORS ? true : false; diff --git a/src/jrd/met.epp b/src/jrd/met.epp index f16f2190f4..8d5efc9f1b 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -1782,7 +1782,6 @@ void MET_get_shadow_files(thread_db* tdbb, bool delete_files) FOR(REQUEST_HANDLE handle) X IN RDB$FILES WITH X.RDB$SHADOW_NUMBER NOT MISSING AND X.RDB$SHADOW_NUMBER NE 0 - AND X.RDB$FILE_SEQUENCE EQ 0 { if ((X.RDB$FILE_FLAGS & FILE_shadow) && !(X.RDB$FILE_FLAGS & FILE_inactive)) { diff --git a/src/jrd/ods.h b/src/jrd/ods.h index 12d4071710..18ad4824e6 100644 --- a/src/jrd/ods.h +++ b/src/jrd/ods.h @@ -531,8 +531,8 @@ static_assert(offsetof(struct header_page, hdr_data) == 128, "hdr_data offset mi inline constexpr UCHAR HDR_end = 0; inline constexpr UCHAR HDR_root_file_name = 1; // Original name of root file -inline constexpr UCHAR HDR_file = 2; // Secondary file -inline constexpr UCHAR HDR_last_page = 3; // Last logical page number of file +//inline constexpr UCHAR HDR_file = 2; // Secondary file +//inline constexpr UCHAR HDR_last_page = 3; // Last logical page number of file inline constexpr UCHAR HDR_sweep_interval = 4; // Transactions between sweeps inline constexpr UCHAR HDR_crypt_checksum = 5; // Checksum of critical crypt parameters inline constexpr UCHAR HDR_difference_file = 6; // Delta file that is used during backup lock diff --git a/src/jrd/os/pio.h b/src/jrd/os/pio.h index f5ff6f4a17..fa594f7864 100644 --- a/src/jrd/os/pio.h +++ b/src/jrd/os/pio.h @@ -41,11 +41,6 @@ namespace Jrd { class jrd_file : public pool_alloc_rpt { public: - jrd_file* fil_next; // Next file in database - ULONG fil_min_page; // Minimum page number in file - ULONG fil_max_page; // Maximum page number in file - USHORT fil_sequence; // Sequence number of file - USHORT fil_fudge; // Fudge factor for page relocation int fil_desc; Firebird::Mutex fil_mutex; USHORT fil_flags; @@ -69,11 +64,6 @@ public: delete fil_ext_lock; } - jrd_file* fil_next; // Next file in database - ULONG fil_min_page; // Minimum page number in file - ULONG fil_max_page; // Maximum page number in file - USHORT fil_sequence; // Sequence number of file - USHORT fil_fudge; // Fudge factor for page relocation HANDLE fil_desc; // File descriptor Firebird::RWLock* fil_ext_lock; // file extend lock USHORT fil_flags; diff --git a/src/jrd/os/pio_proto.h b/src/jrd/os/pio_proto.h index d936c8aea2..8ec0ec3cde 100644 --- a/src/jrd/os/pio_proto.h +++ b/src/jrd/os/pio_proto.h @@ -36,7 +36,6 @@ namespace Ods { struct pag; } -int PIO_add_file(Jrd::thread_db*, Jrd::jrd_file*, const Firebird::PathName&, SLONG); void PIO_close(Jrd::jrd_file*); Jrd::jrd_file* PIO_create(Jrd::thread_db*, const Firebird::PathName&, const bool, const bool); diff --git a/src/jrd/os/posix/unix.cpp b/src/jrd/os/posix/unix.cpp index ba1a3220dc..76071238de 100644 --- a/src/jrd/os/posix/unix.cpp +++ b/src/jrd/os/posix/unix.cpp @@ -132,7 +132,7 @@ using namespace Firebird; static const mode_t MASK = 0660; -static jrd_file* seek_file(jrd_file*, BufferDesc*, FB_UINT64*, FbStatusVector*); +static bool seek_file(jrd_file*, BufferDesc*, FB_UINT64*, FbStatusVector*); static jrd_file* setup_file(Database*, const PathName&, int, USHORT); static void lockDatabaseFile(int& desc, const bool shareMode, const bool temporary, const char* fileName, ISC_STATUS operation); @@ -149,42 +149,8 @@ static int raw_devices_unlink_database (const PathName&); static int openFile(const Firebird::PathName&, const bool, const bool, const bool); static void maybeCloseFile(int&); -int PIO_add_file(thread_db* tdbb, jrd_file* main_file, const PathName& file_name, SLONG start) -{ -/************************************** - * - * P I O _ a d d _ f i l e - * - ************************************** - * - * Functional description - * Add a file to an existing database. Return the sequence - * number of the new file. If anything goes wrong, return a - * sequence of 0. - * NOTE: This routine does not lock any mutexes on - * its own behalf. It is assumed that mutexes will - * have been locked before entry. - * - **************************************/ - jrd_file* new_file = PIO_create(tdbb, file_name, false, false); - if (!new_file) - return 0; - new_file->fil_min_page = start; - USHORT sequence = 1; - - jrd_file* file; - for (file = main_file; file->fil_next; file = file->fil_next) - ++sequence; - - file->fil_max_page = start - 1; - file->fil_next = new_file; - - return sequence; -} - - -void PIO_close(jrd_file* main_file) +void PIO_close(jrd_file* file) { /************************************** * @@ -199,13 +165,10 @@ void PIO_close(jrd_file* main_file) * **************************************/ - for (jrd_file* file = main_file; file; file = file->fil_next) + if (file->fil_desc && file->fil_desc != -1) { - if (file->fil_desc && file->fil_desc != -1) - { - close(file->fil_desc); - file->fil_desc = -1; - } + close(file->fil_desc); + file->fil_desc = -1; } } @@ -336,7 +299,7 @@ bool PIO_expand(const TEXT* file_name, USHORT file_length, TEXT* expanded_name, } -void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, const USHORT pageSize) +void PIO_extend(thread_db* tdbb, jrd_file* file, const ULONG extPages, const USHORT pageSize) { /************************************** * @@ -348,56 +311,46 @@ void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, cons * Extend file by extPages pages of pageSize size. * **************************************/ + fb_assert(extPages); #if defined(HAVE_LINUX_FALLOC_H) && defined(HAVE_FALLOCATE) EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); - ULONG leftPages = extPages; - for (jrd_file* file = main_file; file && leftPages; file = file->fil_next) + if (file->fil_flags & FIL_no_fast_extend) + return; + + const ULONG filePages = PIO_get_number_of_pages(file, pageSize); + const ULONG extendBy = MIN(MAX_ULONG - filePages, extPages); + + int r; + for (r = 0; r < IO_RETRY; r++) { - const ULONG filePages = PIO_get_number_of_pages(file, pageSize); - const ULONG fileMaxPages = (file->fil_max_page == MAX_ULONG) ? - MAX_ULONG : file->fil_max_page - file->fil_min_page + 1; - if (filePages < fileMaxPages) - { - if (file->fil_flags & FIL_no_fast_extend) - return; + int err = fallocate(file->fil_desc, 0, filePages * pageSize, extendBy * pageSize); + if (err == 0) + break; - const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages); + err = errno; + if (SYSCALL_INTERRUPTED(err)) + continue; - int r; - for (r = 0; r < IO_RETRY; r++) - { - int err = fallocate(file->fil_desc, 0, filePages * pageSize, extendBy * pageSize); - if (err == 0) - break; + if (err != EOPNOTSUPP && err != ENOSYS) + unix_error("fallocate", file, isc_io_write_err); - err = errno; - if (SYSCALL_INTERRUPTED(err)) - continue; + file->fil_flags |= FIL_no_fast_extend; + return; + } - if (err != EOPNOTSUPP && err != ENOSYS) - unix_error("fallocate", file, isc_io_write_err); - - file->fil_flags |= FIL_no_fast_extend; - return; - } - - if (r == IO_RETRY) - { + if (r == IO_RETRY) + { #ifdef DEV_BUILD - fprintf(stderr, "PIO_extend: retry count exceeded\n"); - fflush(stderr); + fprintf(stderr, "PIO_extend: retry count exceeded\n"); + fflush(stderr); #endif - unix_error("fallocate_retry", file, isc_io_write_err); - } - - leftPages -= extendBy; - } + unix_error("fallocate_retry", file, isc_io_write_err); } #else - main_file->fil_flags |= FIL_no_fast_extend; + file->fil_flags |= FIL_no_fast_extend; #endif // fallocate present // not implemented @@ -405,7 +358,7 @@ void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, cons } -void PIO_flush(thread_db* tdbb, jrd_file* main_file) +void PIO_flush(thread_db* tdbb, jrd_file* file) { /************************************** * @@ -422,15 +375,12 @@ void PIO_flush(thread_db* tdbb, jrd_file* main_file) #ifndef SUPERSERVER_V2 EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); - MutexLockGuard guard(main_file->fil_mutex, FB_FUNCTION); + MutexLockGuard guard(file->fil_mutex, FB_FUNCTION); - for (jrd_file* file = main_file; file; file = file->fil_next) + if (file->fil_desc != -1) { - if (file->fil_desc != -1) - { - // This really should be an error - fsync(file->fil_desc); - } + // This really should be an error + fsync(file->fil_desc); } #endif } @@ -615,7 +565,7 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length) static Firebird::InitInstance zeros; -USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* status_vector, +USHORT PIO_init_data(thread_db* tdbb, jrd_file* file, FbStatusVector* status_vector, ULONG startPage, USHORT initPages) { /************************************** @@ -642,16 +592,14 @@ USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* statu EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); - jrd_file* file = seek_file(main_file, &bdb, &offset, status_vector); - - if (!file) + if (!seek_file(file, &bdb, &offset, status_vector)) return 0; - if (file->fil_min_page + 8 > startPage) + if (startPage < 8) return 0; USHORT leftPages = initPages; - const ULONG initBy = MIN(file->fil_max_page - startPage, leftPages); + const ULONG initBy = MIN(MAX_ULONG - startPage, leftPages); if (initBy < leftPages) leftPages = initBy; @@ -667,15 +615,16 @@ USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* statu for (int r = 0; r < IO_RETRY; r++) { - if (!(file = seek_file(file, &bdb, &offset, status_vector))) - return false; + if (!seek_file(file, &bdb, &offset, status_vector)) + return 0; + if ((written = os_utils::pwrite(file->fil_desc, zero_buff, to_write, LSEEK_OFFSET_CAST offset)) == to_write) break; + if (written < 0 && !SYSCALL_INTERRUPTED(errno)) return unix_error("write", file, isc_io_write_err, status_vector); } - leftPages -= write_pages; i += write_pages; } @@ -812,7 +761,7 @@ bool PIO_read(thread_db* tdbb, jrd_file* file, BufferDesc* bdb, Ods::pag* page, for (i = 0; i < IO_RETRY; i++) { - if (!(file = seek_file(file, bdb, &offset, status_vector))) + if (!seek_file(file, bdb, &offset, status_vector)) return false; if ((bytes = os_utils::pread(file->fil_desc, page, size, LSEEK_OFFSET_CAST offset)) == size) @@ -864,7 +813,7 @@ bool PIO_write(thread_db* tdbb, jrd_file* file, BufferDesc* bdb, Ods::pag* page, for (i = 0; i < IO_RETRY; i++) { - if (!(file = seek_file(file, bdb, &offset, status_vector))) + if (!seek_file(file, bdb, &offset, status_vector)) return false; if ((bytes = os_utils::pwrite(file->fil_desc, page, size, LSEEK_OFFSET_CAST offset)) == size) @@ -881,8 +830,8 @@ bool PIO_write(thread_db* tdbb, jrd_file* file, BufferDesc* bdb, Ods::pag* page, } -static jrd_file* seek_file(jrd_file* file, BufferDesc* bdb, FB_UINT64* offset, - FbStatusVector* status_vector) +static bool seek_file(jrd_file* file, BufferDesc* bdb, FB_UINT64* offset, + FbStatusVector* status_vector) { /************************************** * @@ -891,43 +840,29 @@ static jrd_file* seek_file(jrd_file* file, BufferDesc* bdb, FB_UINT64* offset, ************************************** * * Functional description - * Given a buffer descriptor block, find the appropriate - * file block and seek to the proper page in that file. + * Given a buffer descriptor block, seek to the proper page in that file. * **************************************/ - BufferControl* bcb = bdb->bdb_bcb; - Database* dbb = bcb->bcb_database; - ULONG page = bdb->bdb_page.getPageNum(); - - for (;; file = file->fil_next) - { - if (!file) { - CORRUPT(158); // msg 158 database file not available - } - else if (page >= file->fil_min_page && page <= file->fil_max_page) - break; - } + BufferControl* const bcb = bdb->bdb_bcb; + const ULONG page = bdb->bdb_page.getPageNum(); if (file->fil_desc == -1) { unix_error("lseek", file, isc_io_access_err, status_vector); - return 0; + return false; } - page -= file->fil_min_page - file->fil_fudge; - FB_UINT64 lseek_offset = page; - lseek_offset *= dbb->dbb_page_size; + lseek_offset *= bcb->bcb_page_size; if (lseek_offset != (FB_UINT64) LSEEK_OFFSET_CAST lseek_offset) { unix_error("lseek", file, isc_io_32bit_exceeded_err, status_vector); - return 0; + return false; } *offset = lseek_offset; - - return file; + return true; } @@ -999,7 +934,6 @@ static jrd_file* setup_file(Database* dbb, const PathName& file_name, int desc, { 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_flags = flags; strcpy(file->fil_string, file_name.c_str()); } diff --git a/src/jrd/os/win32/winnt.cpp b/src/jrd/os/win32/winnt.cpp index 71b0a3b50b..fa9ea5bb1e 100644 --- a/src/jrd/os/win32/winnt.cpp +++ b/src/jrd/os/win32/winnt.cpp @@ -106,7 +106,7 @@ using namespace Firebird; #define TEXT SCHAR static bool maybeCloseFile(HANDLE&); -static jrd_file* seek_file(jrd_file*, BufferDesc*, OVERLAPPED*); +static bool seek_file(jrd_file*, BufferDesc*, OVERLAPPED*); static jrd_file* setup_file(Database*, const Firebird::PathName&, HANDLE, USHORT); static bool nt_error(const TEXT*, const jrd_file*, ISC_STATUS, FbStatusVector* const); @@ -121,39 +121,7 @@ static const DWORD g_dwExtraTempFlags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; -int PIO_add_file(thread_db* tdbb, jrd_file* main_file, const Firebird::PathName& file_name, SLONG start) -{ -/************************************** - * - * P I O _ a d d _ f i l e - * - ************************************** - * - * Functional description - * Add a file to an existing database. Return the sequence - * number of the new file. If anything goes wrong, return a - * sequence of 0. - * - **************************************/ - jrd_file* const new_file = PIO_create(tdbb, file_name, false, false); - if (!new_file) - return 0; - - new_file->fil_min_page = start; - USHORT sequence = 1; - - jrd_file* file; - for (file = main_file; file->fil_next; file = file->fil_next) - ++sequence; - - file->fil_max_page = start - 1; - file->fil_next = new_file; - - return sequence; -} - - -void PIO_close(jrd_file* main_file) +void PIO_close(jrd_file* file) { /************************************** * @@ -164,10 +132,7 @@ void PIO_close(jrd_file* main_file) * Functional description * **************************************/ - for (jrd_file* file = main_file; file; file = file->fil_next) - { - maybeCloseFile(file->fil_desc); - } + maybeCloseFile(file->fil_desc); } @@ -251,7 +216,7 @@ bool PIO_expand(const TEXT* file_name, USHORT file_length, TEXT* expanded_name, } -void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, const USHORT pageSize) +void PIO_extend(thread_db* tdbb, jrd_file* file, const ULONG extPages, const USHORT pageSize) { /************************************** * @@ -263,6 +228,8 @@ void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, cons * Extend file by extPages pages of pageSize size. * **************************************/ + fb_assert(extPages); + // hvlad: prevent other reading\writing threads from changing file pointer. // As we open file without FILE_FLAG_OVERLAPPED, ReadFile\WriteFile calls // will change file pointer we set here and file truncation instead of file @@ -271,42 +238,30 @@ void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, cons // and read\write activity performed simultaneously) // if file have no extend lock it is better to not extend file than corrupt it - if (!main_file->fil_ext_lock) + if (!file->fil_ext_lock) return; EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); - FileExtendLockGuard extLock(main_file->fil_ext_lock, true); + FileExtendLockGuard extLock(file->fil_ext_lock, true); - ULONG leftPages = extPages; - for (jrd_file* file = main_file; file && leftPages; file = file->fil_next) - { - const ULONG filePages = PIO_get_number_of_pages(file, pageSize); - const ULONG fileMaxPages = (file->fil_max_page == MAX_ULONG) ? - MAX_ULONG : file->fil_max_page - file->fil_min_page + 1; - if (filePages < fileMaxPages) - { - const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages); + const ULONG filePages = PIO_get_number_of_pages(file, pageSize); + const ULONG extendBy = MIN(MAX_ULONG - filePages, extPages); - HANDLE hFile = file->fil_desc; + const HANDLE hFile = file->fil_desc; - LARGE_INTEGER newSize; - newSize.QuadPart = ((ULONGLONG) filePages + extendBy) * pageSize; + LARGE_INTEGER newSize; + newSize.QuadPart = ((ULONGLONG) filePages + extendBy) * pageSize; - const DWORD ret = SetFilePointer(hFile, newSize.LowPart, &newSize.HighPart, FILE_BEGIN); - if (ret == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { - nt_error("SetFilePointer", file, isc_io_write_err, NULL); - } - if (!SetEndOfFile(hFile)) { - nt_error("SetEndOfFile", file, isc_io_write_err, NULL); - } + const DWORD ret = SetFilePointer(hFile, newSize.LowPart, &newSize.HighPart, FILE_BEGIN); + if (ret == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) + nt_error("SetFilePointer", file, isc_io_write_err, NULL); - leftPages -= extendBy; - } - } + if (!SetEndOfFile(hFile)) + nt_error("SetEndOfFile", file, isc_io_write_err, NULL); } -void PIO_flush(thread_db* tdbb, jrd_file* main_file) +void PIO_flush(thread_db* tdbb, jrd_file* file) { /************************************** * @@ -320,7 +275,7 @@ void PIO_flush(thread_db* tdbb, jrd_file* main_file) **************************************/ EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); - for (jrd_file* file = main_file; file; file = file->fil_next) + if (file->fil_desc != INVALID_HANDLE_VALUE) FlushFileBuffers(file->fil_desc); } @@ -417,7 +372,7 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length) static Firebird::InitInstance zeros; -USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* status_vector, +USHORT PIO_init_data(thread_db* tdbb, jrd_file* file, FbStatusVector* status_vector, ULONG startPage, USHORT initPages) { /************************************** @@ -436,7 +391,7 @@ USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* statu Database* const dbb = tdbb->getDatabase(); EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); - FileExtendLockGuard extLock(main_file->fil_ext_lock, false); + FileExtendLockGuard extLock(file->fil_ext_lock, false); // Fake buffer, used in seek_file. Page space ID doesn't matter there // as we already know file to work with @@ -444,16 +399,14 @@ USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* statu bdb.bdb_page = PageNumber(0, startPage); OVERLAPPED overlapped; - jrd_file* file = seek_file(main_file, &bdb, &overlapped); - - if (!file) + if (!seek_file(file, &bdb, &overlapped)) return 0; - if (file->fil_min_page + 8 > startPage) + if (startPage < 8) return 0; USHORT leftPages = initPages; - const ULONG initBy = MIN(file->fil_max_page - startPage, leftPages); + const ULONG initBy = MIN(MAX_ULONG - startPage, leftPages); if (initBy < leftPages) leftPages = initBy; @@ -464,8 +417,8 @@ USHORT PIO_init_data(thread_db* tdbb, jrd_file* main_file, FbStatusVector* statu if (write_pages > leftPages) write_pages = leftPages; - jrd_file* file1 = seek_file(main_file, &bdb, &overlapped); - fb_assert(file1 == file); + if (!seek_file(file, &bdb, &overlapped)) + return 0; const DWORD to_write = (DWORD) write_pages * dbb->dbb_page_size; DWORD written; @@ -590,7 +543,7 @@ bool PIO_read(thread_db* tdbb, jrd_file* file, BufferDesc* bdb, Ods::pag* page, FileExtendLockGuard extLock(file->fil_ext_lock, false); OVERLAPPED overlapped; - if (!(file = seek_file(file, bdb, &overlapped))) + if (!seek_file(file, bdb, &overlapped)) return false; HANDLE desc = file->fil_desc; @@ -625,14 +578,12 @@ bool PIO_read_ahead(thread_db* tdbb, ************************************** * * Functional description - * Read a contiguous set of pages. The only - * tricky part is to segment the I/O when crossing - * file boundaries. + * Read a contiguous set of pages. * **************************************/ OVERLAPPED overlapped, *overlapped_ptr; - Database* const dbb = tdbb->getDatabase(); + const auto dbb = tdbb->getDatabase(); EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); @@ -647,60 +598,45 @@ bool PIO_read_ahead(thread_db* tdbb, piob->piob_flags = 0; } + // Setup up a dummy buffer descriptor block for seeking file BufferDesc bdb; - while (pages) + bdb.bdb_dbb = dbb; + bdb.bdb_page = start_page; + + const jrd_file* const file = dbb->dbb_file; + + if (!seek_file(file, &bdb, status_vector, overlapped_ptr, &overlapped_ptr)) + return false; + + const HANDLE desc = file->fil_desc; + const DWORD length = pages * dbb->dbb_page_size; + + DWORD actual_length; + if (ReadFile(desc, buffer, length, &actual_length, overlapped_ptr) && + actual_length == length) { - // Setup up a dummy buffer descriptor block for seeking file. - - bdb.bdb_dbb = dbb; - bdb.bdb_page = start_page; - - jrd_file* file = seek_file(dbb->dbb_file, &bdb, status_vector, overlapped_ptr, &overlapped_ptr); - if (!file) - return false; - - // Check that every page within the set resides in the same database - // file. If not read what you can and loop back for the rest. - - DWORD segmented_length = 0; - while (pages && start_page >= file->fil_min_page && start_page <= file->fil_max_page) - { - segmented_length += dbb->dbb_page_size; - ++start_page; - --pages; - } - - HANDLE desc = file->fil_desc; - - DWORD actual_length; - if (ReadFile(desc, buffer, segmented_length, &actual_length, overlapped_ptr) && - actual_length == segmented_length) - { - if (piob && !pages) - piob->piob_flags = PIOB_success; - } - else if (piob && !pages) - { - piob->piob_flags = PIOB_pending; - piob->piob_desc = reinterpret_cast(desc); - piob->piob_file = file; - piob->piob_io_length = segmented_length; - } - else if (!GetOverlappedResult(desc, overlapped_ptr, &actual_length, TRUE) || - actual_length != segmented_length) - { - if (piob) - piob->piob_flags = PIOB_error; - - release_io_event(file, overlapped_ptr); - return nt_error("GetOverlappedResult", file, isc_io_read_err, status_vector); - } - - if (!piob || (piob->piob_flags & (PIOB_success | PIOB_error))) - release_io_event(file, overlapped_ptr); - - buffer += segmented_length; + if (piob) + piob->piob_flags = PIOB_success; } + else if (piob) + { + piob->piob_flags = PIOB_pending; + piob->piob_desc = reinterpret_cast(desc); + piob->piob_file = file; + piob->piob_io_length = segmented_length; + } + else if (!GetOverlappedResult(desc, overlapped_ptr, &actual_length, TRUE) || + actual_length != length) + { + if (piob) + piob->piob_flags = PIOB_error; + + release_io_event(file, overlapped_ptr); + return nt_error("GetOverlappedResult", file, isc_io_read_err, status_vector); + } + + if (!piob || (piob->piob_flags & (PIOB_success | PIOB_error))) + release_io_event(file, overlapped_ptr); return true; } @@ -767,8 +703,7 @@ bool PIO_write(thread_db* tdbb, jrd_file* file, BufferDesc* bdb, Ods::pag* page, FileExtendLockGuard extLock(file->fil_ext_lock, false); OVERLAPPED overlapped; - file = seek_file(file, bdb, &overlapped); - if (!file) + if (!seek_file(file, bdb, &overlapped)) return false; HANDLE desc = file->fil_desc; @@ -813,9 +748,7 @@ ULONG PIO_get_number_of_pages(const jrd_file* file, const USHORT pagesize) } -static jrd_file* seek_file(jrd_file* file, - BufferDesc* bdb, - OVERLAPPED* overlapped) +static bool seek_file(jrd_file* file, BufferDesc* bdb, OVERLAPPED* overlapped) { /************************************** * @@ -824,24 +757,11 @@ static jrd_file* seek_file(jrd_file* file, ************************************** * * Functional description - * Given a buffer descriptor block, find the appropriate - * file block and seek to the proper page in that file. + * Given a buffer descriptor block, seek to the proper page in that file. * **************************************/ - BufferControl *bcb = bdb->bdb_bcb; - ULONG page = bdb->bdb_page.getPageNum(); - - for (;; file = file->fil_next) - { - if (!file) { - CORRUPT(158); // msg 158 database file not available - } - else if (page >= file->fil_min_page && page <= file->fil_max_page) { - break; - } - } - - page -= file->fil_min_page - file->fil_fudge; + BufferControl* const bcb = bdb->bdb_bcb; + const ULONG page = bdb->bdb_page.getPageNum(); LARGE_INTEGER liOffset; liOffset.QuadPart = UInt32x32To64((DWORD) page, (DWORD) bcb->bcb_page_size); @@ -854,7 +774,7 @@ static jrd_file* seek_file(jrd_file* file, ThreadSync* thd = ThreadSync::getThread(FB_FUNCTION); overlapped->hEvent = thd->getIOEvent(); - return file; + return true; } @@ -876,7 +796,6 @@ static jrd_file* setup_file(Database* dbb, const Firebird::PathName& file_name, { 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_flags = flags; strcpy(file->fil_string, file_name.c_str()); diff --git a/src/jrd/pag.cpp b/src/jrd/pag.cpp index 73df5a3826..3c7c683517 100644 --- a/src/jrd/pag.cpp +++ b/src/jrd/pag.cpp @@ -364,115 +364,6 @@ namespace } // namespace -USHORT PAG_add_file(thread_db* tdbb, const TEXT* file_name, SLONG start) -{ -/************************************** - * - * P A G _ a d d _ f i l e - * - ************************************** - * - * Functional description - * Add a file to the current database. Return the sequence number for the new file. - * - **************************************/ - SET_TDBB(tdbb); - ensureDbWritable(tdbb); - - const auto dbb = tdbb->getDatabase(); - - // Find current last file - - PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); - jrd_file* file = pageSpace->file; - while (file->fil_next) { - file = file->fil_next; - } - - // Verify database file path against DatabaseAccess entry of firebird.conf - if (!JRD_verify_database_access(file_name)) - { - string fileName(file_name); - ISC_systemToUtf8(fileName); - ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("additional database file") << - Arg::Str(fileName)); - } - - // Create the file. If the sequence number comes back zero, it didn't work, so punt - - const USHORT sequence = PIO_add_file(tdbb, pageSpace->file, file_name, start); - if (!sequence) - return 0; - - // Create header page for new file - - jrd_file* next = file->fil_next; - - WIN window(DB_PAGE_SPACE, next->fil_min_page); - header_page* header = (header_page*) CCH_fake(tdbb, &window, 1); - header->hdr_header.pag_type = pag_header; - header->hdr_sequence = sequence; - header->hdr_page_size = dbb->dbb_page_size; - header->hdr_data[0] = HDR_end; - header->hdr_end = HDR_SIZE; - next->fil_sequence = sequence; - -#ifdef SUPPORT_RAW_DEVICES - // The following lines (taken from PAG_format_header) are needed to identify - // this file in raw_devices_validate_database as a valid database attachment. - *(ISC_TIMESTAMP*) header->hdr_creation_date = TimeZoneUtil::getCurrentGmtTimeStamp().utc_timestamp; - // should we include milliseconds or not? - //TimeStamp::round_time(header->hdr_creation_date->timestamp_time, 0); - - header->hdr_ods_version = ODS_VERSION | ODS_FIREBIRD_FLAG; - DbImplementation::current.store(header); - header->hdr_ods_minor = ODS_CURRENT; - if (dbb->dbb_flags & DBB_DB_SQL_dialect_3) - header->hdr_flags |= hdr_SQL_dialect_3; -#endif - - header->hdr_header.pag_pageno = window.win_page.getPageNum(); - // It's header, never encrypted - PIO_write(tdbb, pageSpace->file, window.win_bdb, window.win_buffer, tdbb->tdbb_status_vector); - CCH_RELEASE(tdbb, &window); - next->fil_fudge = 1; - - // Update the previous header page to point to new file - - file->fil_fudge = 0; - window.win_page = file->fil_min_page; - header = (header_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_header); - if (!file->fil_min_page) - CCH_MARK_MUST_WRITE(tdbb, &window); - else - CCH_MARK(tdbb, &window); - - --start; - - if (file->fil_min_page) - { - PAG_add_header_entry(tdbb, header, HDR_file, static_cast(strlen(file_name)), - reinterpret_cast(file_name)); - PAG_add_header_entry(tdbb, header, HDR_last_page, sizeof(SLONG), (UCHAR*) &start); - } - else - { - storeClump(tdbb, HDR_file, static_cast(strlen(file_name)), - reinterpret_cast(file_name)); - storeClump(tdbb, HDR_last_page, sizeof(SLONG), (UCHAR*) &start); - } - - header->hdr_header.pag_pageno = window.win_page.getPageNum(); - // It's header, never encrypted - PIO_write(tdbb, pageSpace->file, window.win_bdb, window.win_buffer, tdbb->tdbb_status_vector); - CCH_RELEASE(tdbb, &window); - if (file->fil_min_page) - file->fil_fudge = 1; - - return sequence; -} - - void PAG_add_header_entry(thread_db* tdbb, header_page* header, USHORT type, USHORT len, const UCHAR* entry) { @@ -1136,8 +1027,7 @@ void PAG_header(thread_db* tdbb, bool info, const TriState newForceWrite) // Ensure the file-level FW mode matches the actual FW mode in the database const auto pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); - for (jrd_file* file = pageSpace->file; file; file = file->fil_next) - PIO_force_write(file, forceWrite && !readOnly); + PIO_force_write(pageSpace->file, forceWrite && !readOnly); if (dbb->dbb_backup_manager->getState() != Ods::hdr_nbak_normal) dbb->dbb_backup_manager->setForcedWrites(forceWrite); @@ -1327,7 +1217,7 @@ void PAG_init(thread_db* tdbb) } -void PAG_init2(thread_db* tdbb, USHORT shadow_number) +void PAG_init2(thread_db* tdbb) { /************************************** * @@ -1336,128 +1226,40 @@ void PAG_init2(thread_db* tdbb, USHORT shadow_number) ************************************** * * Functional description - * Perform second phase of page initialization -- the eternal - * search for additional files. + * Read and apply the database header options. * **************************************/ SET_TDBB(tdbb); const auto dbb = tdbb->getDatabase(); - FbStatusVector* status = tdbb->tdbb_status_vector; + WIN window(HEADER_PAGE_NUMBER); + const auto header = (header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header); - // allocate a spare buffer which is large enough, - // and set up to release it in case of error. Align - // the temporary page buffer for raw disk access. - - Array temp; - UCHAR* const temp_page = temp.getAlignedBuffer(dbb->dbb_page_size, dbb->getIOBlockSize()); - - PageSpace* const pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); - jrd_file* file = pageSpace->file; - if (shadow_number) + for (const UCHAR* p = header->hdr_data; *p != HDR_end; p += 2 + p[1]) { - Shadow* shadow = dbb->dbb_shadow; - for (; shadow; shadow = shadow->sdw_next) + switch (*p) { - if (shadow->sdw_number == shadow_number) - { - file = shadow->sdw_file; - break; - } - } - if (!shadow) - BUGCHECK(161); // msg 161 shadow block not found - } - - USHORT sequence = 1; - WIN window(DB_PAGE_SPACE, -1); - - // Loop thru files and header pages until everything is open - - while (true) - { - window.win_page = file->fil_min_page; - ULONG last_page = 0; - BufferDesc temp_bdb(dbb->dbb_bcb); - - // note that we do not have to get a read lock on - // the header page (except for header page 0) because - // the only time it will be modified is when adding a file, - // which must be done with an exclusive lock on the database -- - // if this changes, this policy will have to be reevaluated; - // at any rate there is a problem with getting a read lock - // because the corresponding page in the main database file may not exist - - if (!file->fil_min_page) - CCH_FETCH(tdbb, &window, LCK_read, pag_header); - - header_page* header = (header_page*) temp_page; - temp_bdb.bdb_buffer = (pag*) header; - temp_bdb.bdb_page = window.win_page; - - // Read the required page into the local buffer - // It's header, never encrypted - PIO_read(tdbb, file, &temp_bdb, (PAG) header, status); - - if (shadow_number && !file->fil_min_page) - CCH_RELEASE(tdbb, &window); - - PathName nextFileName; - - for (const UCHAR* p = header->hdr_data; *p != HDR_end; p += 2 + p[1]) - { - switch (*p) - { - case HDR_file: - nextFileName.assign(p + 2, p[1]); - break; - - case HDR_last_page: - fb_assert(p[1] == sizeof(last_page)); - memcpy(&last_page, p + 2, sizeof(last_page)); - break; - - case HDR_sweep_interval: - fb_assert(p[1] == sizeof(SLONG)); - memcpy(&dbb->dbb_sweep_interval, p + 2, sizeof(SLONG)); - break; - - case HDR_db_guid: - fb_assert(p[1] == Guid::SIZE); - dbb->dbb_guid = Guid(p + 2); - break; - - case HDR_repl_seq: - fb_assert(p[1] == sizeof(FB_UINT64)); - memcpy(&dbb->dbb_repl_sequence, p + 2, sizeof(FB_UINT64)); - break; - } - } - - if (!shadow_number && !file->fil_min_page) - CCH_RELEASE(tdbb, &window); - - if (file->fil_min_page) - file->fil_fudge = 1; - - if (nextFileName.isEmpty()) + case HDR_sweep_interval: + fb_assert(p[1] == sizeof(SLONG)); + memcpy(&dbb->dbb_sweep_interval, p + 2, sizeof(SLONG)); break; - // Verify database file path against DatabaseAccess entry of firebird.conf - if (!JRD_verify_database_access(nextFileName)) - { - ISC_systemToUtf8(nextFileName); - ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("additional database file") << - Arg::Str(nextFileName)); + case HDR_db_guid: + fb_assert(p[1] == Guid::SIZE); + dbb->dbb_guid = Guid(p + 2); + break; + + case HDR_repl_seq: + fb_assert(p[1] == sizeof(FB_UINT64)); + memcpy(&dbb->dbb_repl_sequence, p + 2, sizeof(FB_UINT64)); + break; + + default: + break; } - - file->fil_next = PIO_open(tdbb, nextFileName, nextFileName); - file->fil_max_page = last_page; - file = file->fil_next; - - file->fil_min_page = last_page + 1; - file->fil_sequence = sequence++; } + + CCH_RELEASE(tdbb, &window); } @@ -1644,14 +1446,10 @@ void PAG_set_force_write(thread_db* tdbb, bool flag) CCH_RELEASE(tdbb, &window); PageSpace* const pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); - for (jrd_file* file = pageSpace->file; file; file = file->fil_next) - PIO_force_write(file, flag); + PIO_force_write(pageSpace->file, flag); for (Shadow* shadow = dbb->dbb_shadow; shadow; shadow = shadow->sdw_next) - { - for (jrd_file* file = shadow->sdw_file; file; file = file->fil_next) - PIO_force_write(file, flag); - } + PIO_force_write(shadow->sdw_file, flag); if (dbb->dbb_backup_manager->getState() != Ods::hdr_nbak_normal) dbb->dbb_backup_manager->setForcedWrites(flag); @@ -1917,13 +1715,7 @@ PageSpace::~PageSpace() if (file) { PIO_close(file); - - while (file) - { - jrd_file* next = file->fil_next; - delete file; - file = next; - } + delete file; } } @@ -1936,15 +1728,7 @@ ULONG PageSpace::actAlloc() * **************************************/ - // Traverse the linked list of files and add up the - // number of pages in each file - const USHORT pageSize = dbb->dbb_page_size; - ULONG tot_pages = 0; - for (const jrd_file* f = file; f != NULL; f = f->fil_next) { - tot_pages += PIO_get_number_of_pages(f, pageSize); - } - - return tot_pages; + return PIO_get_number_of_pages(file, dbb->dbb_page_size); } ULONG PageSpace::actAlloc(const Database* dbb) @@ -1961,17 +1745,7 @@ ULONG PageSpace::maxAlloc() * Compute last physically allocated page of database. * **************************************/ - const USHORT pageSize = dbb->dbb_page_size; - const jrd_file* f = file; - ULONG nPages = PIO_get_number_of_pages(f, pageSize); - - while (f->fil_next && nPages == f->fil_max_page - f->fil_min_page + 1 + f->fil_fudge) - { - f = f->fil_next; - nPages = PIO_get_number_of_pages(f, pageSize); - } - - nPages += f->fil_min_page - f->fil_fudge; + const ULONG nPages = PIO_get_number_of_pages(file, dbb->dbb_page_size); if (maxPageNumber < nPages) maxPageNumber = nPages; @@ -1987,15 +1761,7 @@ ULONG PageSpace::maxAlloc(const Database* dbb) bool PageSpace::onRawDevice() const { -#ifdef SUPPORT_RAW_DEVICES - for (const jrd_file* f = file; f != NULL; f = f->fil_next) - { - if (f->fil_flags & FIL_raw_device) - return true; - } -#endif - - return false; + return (file->fil_flags & FIL_raw_device) != 0; } ULONG PageSpace::lastUsedPage() diff --git a/src/jrd/pag_proto.h b/src/jrd/pag_proto.h index dc9a4ae20d..084b55a2a3 100644 --- a/src/jrd/pag_proto.h +++ b/src/jrd/pag_proto.h @@ -37,7 +37,6 @@ namespace Ods { struct header_page; } -USHORT PAG_add_file(Jrd::thread_db* tdbb, const TEXT*, SLONG); void PAG_add_header_entry(Jrd::thread_db* tdbb, Ods::header_page*, USHORT, USHORT, const UCHAR*); bool PAG_replace_entry_first(Jrd::thread_db* tdbb, Ods::header_page*, USHORT, USHORT, const UCHAR*); Ods::pag* PAG_allocate_pages(Jrd::thread_db* tdbb, Jrd::win* window, unsigned cntAlloc, bool aligned); @@ -49,7 +48,7 @@ bool PAG_get_clump(Jrd::thread_db*, USHORT, USHORT*, UCHAR*); void PAG_header(Jrd::thread_db*, bool, const Firebird::TriState newForceWrite = Firebird::TriState()); void PAG_header_init(Jrd::thread_db*); void PAG_init(Jrd::thread_db*); -void PAG_init2(Jrd::thread_db*, USHORT); +void PAG_init2(Jrd::thread_db*); SLONG PAG_last_page(Jrd::thread_db* tdbb); void PAG_release_page(Jrd::thread_db* tdbb, const Jrd::PageNumber&, const Jrd::PageNumber&); void PAG_release_pages(Jrd::thread_db* tdbb, USHORT pageSpaceID, int cntRelease, diff --git a/src/jrd/sdw.cpp b/src/jrd/sdw.cpp index c7a14f7a39..4e78682f33 100644 --- a/src/jrd/sdw.cpp +++ b/src/jrd/sdw.cpp @@ -64,7 +64,6 @@ static bool check_for_file(thread_db* tdbb, const SCHAR*, USHORT); #ifdef NOT_USED_OR_REPLACED static void check_if_got_ast(thread_db* tdbb, jrd_file*); #endif -static void copy_header(thread_db* tdbb); static void update_dbb_to_sdw(Database*); @@ -112,147 +111,6 @@ void SDW_add(thread_db* tdbb, const TEXT* file_name, USHORT shadow_number, USHOR } -int SDW_add_file(thread_db* tdbb, const TEXT* file_name, SLONG start, USHORT shadow_number) -{ -/************************************** - * - * S D W _ a d d _ f i l e - * - ************************************** - * - * Functional description - * Add a file to a shadow set. - * Return the sequence number for the new file. - * - **************************************/ - SET_TDBB(tdbb); - Database* dbb = tdbb->getDatabase(); - - SyncLockGuard guard(&dbb->dbb_shadow_sync, SYNC_EXCLUSIVE, "SDW_add_file"); - - // Find the file to be extended - - jrd_file* shadow_file = 0; - Shadow* shadow; - for (shadow = dbb->dbb_shadow; shadow; shadow = shadow->sdw_next) - { - if ((shadow->sdw_number == shadow_number) && - !(shadow->sdw_flags & (SDW_IGNORE | SDW_rollover))) - { - shadow_file = shadow->sdw_file; - break; - } - } - - if (!shadow) { - return 0; - } - - // find the last file in the list, open the new file - - jrd_file* file = shadow_file; - while (file->fil_next) { - file = file->fil_next; - } - - // Verify shadow file path against DatabaseAccess entry of firebird.conf - if (!JRD_verify_database_access(file_name)) - { - ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("database shadow") << - Arg::Str(file_name)); - } - - const SLONG sequence = PIO_add_file(tdbb, shadow_file, file_name, start); - if (!sequence) - return 0; - - jrd_file* next = file->fil_next; - - // Always write the header page, even for a conditional - // shadow that hasn't been activated. - - // allocate a spare buffer which is large enough, - // and set up to release it in case of error. Align - // the spare page buffer for raw disk access. - - Array temp; - UCHAR* const spare_page = temp.getAlignedBuffer(dbb->dbb_page_size, dbb->getIOBlockSize()); - - // create the header using the spare_buffer - - header_page* header = (header_page*) spare_page; - header->hdr_header.pag_type = pag_header; - header->hdr_sequence = sequence; - header->hdr_page_size = dbb->dbb_page_size; - header->hdr_data[0] = HDR_end; - header->hdr_end = HDR_SIZE; - - // fool PIO_write into writing the scratch page into the correct place - BufferDesc temp_bdb(dbb->dbb_bcb); - temp_bdb.bdb_page = next->fil_min_page; - temp_bdb.bdb_buffer = (PAG) header; - header->hdr_header.pag_pageno = temp_bdb.bdb_page.getPageNum(); - // It's header, never encrypted - if (!PIO_write(tdbb, shadow_file, &temp_bdb, reinterpret_cast(header), 0)) - return 0; - - next->fil_fudge = 1; - - // Update the previous header page to point to new file -- - // we can use the same header page, suitably modified, - // because they all look pretty much the same at this point - - /******************* - Fix for bug 7925. drop_gdb wan not dropping secondary file in - multi-shadow files. The structure was not being filled with the - info. Commented some code so that the structure will always be filled. - - -Sudesh 07/06/95 - - The original code : - === - if (shadow_file == file) - copy_header(tdbb); - else - === - ************************/ - - // Temporarly reverting the change ------- Sudesh 07/07/95 ******* - - if (shadow_file == file) - { - copy_header(tdbb); - } - else - { - --start; - header->hdr_data[0] = HDR_end; - header->hdr_end = HDR_SIZE; - - PAG_add_header_entry(tdbb, header, HDR_file, static_cast(strlen(file_name)), - reinterpret_cast(file_name)); - PAG_add_header_entry(tdbb, header, HDR_last_page, sizeof(start), - reinterpret_cast(&start)); - file->fil_fudge = 0; - temp_bdb.bdb_page = file->fil_min_page; - header->hdr_header.pag_pageno = temp_bdb.bdb_page.getPageNum(); - // It's header, never encrypted - if (!PIO_write(tdbb, shadow_file, &temp_bdb, reinterpret_cast(header), 0)) - return 0; - - if (file->fil_min_page) { - file->fil_fudge = 1; - } - } - - if (file->fil_min_page) { - file->fil_fudge = 1; - } - - return sequence; -} - - void SDW_check(thread_db* tdbb) { /************************************** @@ -814,12 +672,7 @@ bool SDW_rollover_to_shadow(thread_db* tdbb, jrd_file* file, const bool inAst) // close the main database file if possible and release all file blocks PIO_close(pageSpace->file); - - while ( (file = pageSpace->file) ) - { - pageSpace->file = file->fil_next; - delete file; - } + delete pageSpace->file; /* point the main database file at the file of the first shadow in the list and mark that shadow as rolled over to @@ -894,13 +747,7 @@ static void shutdown_shadow(Shadow* shadow) // close the shadow files and free up the associated memory PIO_close(shadow->sdw_file); - jrd_file* file; - jrd_file* free = shadow->sdw_file; - - for (; (file = free->fil_next); free = file) - delete free; - - delete free; + delete shadow->sdw_file; delete shadow; } @@ -1003,12 +850,6 @@ void SDW_start(thread_db* tdbb, const TEXT* file_name, const header_page* shadow_header = (header_page*) spare_page; - // NOTE ! NOTE! NOTE! - // Starting V4.0, header pages can have overflow pages. For the shadow, - // we are making an assumption that the shadow header page will not - // overflow, as the only things written on a shadow header is the - // HDR_root_file_name, HDR_file, and HDR_last_page - const UCHAR* p = shadow_header->hdr_data; while (*p != HDR_end && *p != HDR_root_file_name) { p += 2 + p[1]; @@ -1046,10 +887,6 @@ void SDW_start(thread_db* tdbb, const TEXT* file_name, shadow->sdw_flags |= SDW_dumped; } - // get the ancillary files and reset the error environment - - PAG_init2(tdbb, shadow_number); - } // try catch (const Firebird::Exception& ex) { @@ -1257,35 +1094,6 @@ static void check_if_got_ast(thread_db* tdbb, jrd_file* file) } #endif -static void copy_header(thread_db* tdbb) -{ -/************************************** - * - * c o p y _ h e a d e r - * - ************************************** - * - * Functional description - * Fetch the header page from the database - * and write it to the shadow file. This is - * done so that if this shadow is extended, - * the header page will be there for writing - * the name of the extend file. - * - **************************************/ - SET_TDBB(tdbb); - Database* dbb = tdbb->getDatabase(); - CHECK_DBB(dbb); - - // get the database header page and write it out -- - // CCH will take care of modifying it - - WIN window(HEADER_PAGE_NUMBER); - CCH_FETCH(tdbb, &window, LCK_write, pag_header); - CCH_MARK_MUST_WRITE(tdbb, &window); - CCH_RELEASE(tdbb, &window); -} - static void update_dbb_to_sdw(Database* dbb) { @@ -1319,13 +1127,7 @@ static void update_dbb_to_sdw(Database* dbb) // hvlad: need sync for this code PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE); PIO_close(pageSpace->file); - - jrd_file* file; - while ( (file = pageSpace->file) ) - { - pageSpace->file = file->fil_next; - delete file; - } + delete pageSpace->file; pageSpace->file = shadow->sdw_file; shadow->sdw_flags |= SDW_rollover; diff --git a/src/jrd/sdw_proto.h b/src/jrd/sdw_proto.h index db9f8cf23f..325bdfef7d 100644 --- a/src/jrd/sdw_proto.h +++ b/src/jrd/sdw_proto.h @@ -29,7 +29,6 @@ namespace Jrd { } void SDW_add(Jrd::thread_db* tdbb, const TEXT*, USHORT, USHORT); -int SDW_add_file(Jrd::thread_db* tdbb, const TEXT*, SLONG, USHORT); void SDW_check(Jrd::thread_db* tdbb); bool SDW_check_conditional(Jrd::thread_db* tdbb); void SDW_close(); diff --git a/src/jrd/tra.h b/src/jrd/tra.h index 35a1797b27..d42711bcca 100644 --- a/src/jrd/tra.h +++ b/src/jrd/tra.h @@ -478,7 +478,6 @@ enum dfw_t { dfw_create_index, dfw_delete_index, dfw_compute_security, - dfw_add_file, dfw_add_shadow, dfw_delete_shadow, dfw_delete_shadow_nodelete, diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index cdb851df85..3d23566bbc 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -2240,27 +2240,32 @@ bool VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction) case rel_files: protect_system_table_delupd(tdbb, relation, "DELETE"); { - const bool name_defined = EVL_field(0, rpb->rpb_record, f_file_name, &desc); - const USHORT file_flags = EVL_field(0, rpb->rpb_record, f_file_flags, &desc2) ? + const bool nameDefined = EVL_field(0, rpb->rpb_record, f_file_name, &desc); + + const auto shadowNumber = EVL_field(0, rpb->rpb_record, f_file_shad_num, &desc2) ? MOV_get_long(tdbb, &desc2, 0) : 0; - if (file_flags & FILE_difference) + + const auto fileFlags = EVL_field(0, rpb->rpb_record, f_file_flags, &desc2) ? + MOV_get_long(tdbb, &desc2, 0) : 0; + + if (shadowNumber) { - if (file_flags & FILE_backing_up) - DFW_post_work(transaction, dfw_end_backup, &desc, 0); - if (name_defined) - DFW_post_work(transaction, dfw_delete_difference, &desc, 0); - } - else if (EVL_field(0, rpb->rpb_record, f_file_shad_num, &desc2) && - (id = MOV_get_long(tdbb, &desc2, 0))) - { - if (!(file_flags & FILE_inactive)) + if (!(fileFlags & FILE_inactive)) { - if (file_flags & FILE_nodelete) - DFW_post_work(transaction, dfw_delete_shadow_nodelete, &desc, id); - else - DFW_post_work(transaction, dfw_delete_shadow, &desc, id); + const auto work = (fileFlags & FILE_nodelete) ? + dfw_delete_shadow_nodelete : dfw_delete_shadow; + + DFW_post_work(transaction, work, &desc, shadowNumber); } } + else if (fileFlags & FILE_difference) + { + if (fileFlags & FILE_backing_up) + DFW_post_work(transaction, dfw_end_backup, &desc, 0); + + if (nameDefined) + DFW_post_work(transaction, dfw_delete_difference, &desc, 0); + } } break; @@ -3617,18 +3622,24 @@ bool VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j case rel_files: protect_system_table_delupd(tdbb, relation, "UPDATE"); { - SSHORT new_rel_flags, old_rel_flags; EVL_field(0, new_rpb->rpb_record, f_file_name, &desc1); - if (EVL_field(0, new_rpb->rpb_record, f_file_flags, &desc2) && - ((new_rel_flags = MOV_get_long(tdbb, &desc2, 0)) & FILE_difference) && - EVL_field(0, org_rpb->rpb_record, f_file_flags, &desc2) && - ((old_rel_flags = MOV_get_long(tdbb, &desc2, 0)) != new_rel_flags)) + + const auto orgFileFlags = EVL_field(0, org_rpb->rpb_record, f_file_flags, &desc2) ? + MOV_get_long(tdbb, &desc2, 0) : 0; + const auto newFileFlags = EVL_field(0, new_rpb->rpb_record, f_file_flags, &desc2) ? + MOV_get_long(tdbb, &desc2, 0) : 0; + + if ((newFileFlags & FILE_difference) && orgFileFlags != newFileFlags) { DFW_post_work(transaction, - (new_rel_flags & FILE_backing_up ? dfw_begin_backup : dfw_end_backup), + (newFileFlags & FILE_backing_up) ? dfw_begin_backup : dfw_end_backup, &desc1, 0); } } + // Nullify the unsupported fields + new_rpb->rpb_record->setNull(f_file_seq); + new_rpb->rpb_record->setNull(f_file_start); + new_rpb->rpb_record->setNull(f_file_length); break; case rel_charsets: @@ -4175,34 +4186,32 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction) case rel_files: protect_system_table_insert(tdbb, request, relation); { - const bool name_defined = EVL_field(0, rpb->rpb_record, f_file_name, &desc); - if (EVL_field(0, rpb->rpb_record, f_file_shad_num, &desc2) && - MOV_get_long(tdbb, &desc2, 0)) + const bool nameDefined = EVL_field(0, rpb->rpb_record, f_file_name, &desc); + + const auto shadowNumber = EVL_field(0, rpb->rpb_record, f_file_shad_num, &desc2) ? + MOV_get_long(tdbb, &desc2, 0) : 0; + + const auto fileFlags = EVL_field(0, rpb->rpb_record, f_file_flags, &desc2) ? + MOV_get_long(tdbb, &desc2, 0) : 0; + + if (shadowNumber) { - EVL_field(0, rpb->rpb_record, f_file_flags, &desc2); - if (!(MOV_get_long(tdbb, &desc2, 0) & FILE_inactive)) { + if (!(fileFlags & FILE_inactive)) DFW_post_work(transaction, dfw_add_shadow, &desc, 0); - } } - else + else if (fileFlags & FILE_difference) { - USHORT rel_flags; - if (EVL_field(0, rpb->rpb_record, f_file_flags, &desc2) && - ((rel_flags = MOV_get_long(tdbb, &desc2, 0)) & FILE_difference)) - { - if (name_defined) { - DFW_post_work(transaction, dfw_add_difference, &desc, 0); - } - if (rel_flags & FILE_backing_up) - { - DFW_post_work(transaction, dfw_begin_backup, &desc, 0); - } - } - else { - DFW_post_work(transaction, dfw_add_file, &desc, 0); - } + if (nameDefined) + DFW_post_work(transaction, dfw_add_difference, &desc, 0); + + if (fileFlags & FILE_backing_up) + DFW_post_work(transaction, dfw_begin_backup, &desc, 0); } } + // Nullify the unsupported fields + rpb->rpb_record->setNull(f_file_seq); + rpb->rpb_record->setNull(f_file_start); + rpb->rpb_record->setNull(f_file_length); break; case rel_triggers: diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp index 44c0ac4277..5bf89a5d4b 100644 --- a/src/utilities/gstat/dba.epp +++ b/src/utilities/gstat/dba.epp @@ -164,10 +164,6 @@ struct dba_rel struct dba_fil { - dba_fil* fil_next; // Next file in database - ULONG fil_min_page; // Minimum page number in file - ULONG fil_max_page; // Maximum page number in file - USHORT fil_fudge; // Fudge factor for page relocation #ifdef WIN_NT void *fil_desc; #else @@ -216,16 +212,6 @@ static void print_help(); #include "../utilities/gstat/dba_proto.h" -struct open_files -{ -#ifdef WIN_NT - void* desc; -#else - int desc; -#endif - open_files* open_files_next; -}; - struct dba_mem { char* memory; @@ -241,7 +227,7 @@ public: : ThreadData(tddDBA), uSvc(us) { //dba_throw = false; - files = 0; + file = 0; relations = 0; page_size = 0; dp_per_pp = 0; @@ -252,14 +238,13 @@ public: global_buffer = 0; exit_code = 0; head_of_mem_list = 0; - head_of_files_list = 0; memset(dba_status_vector, 0, sizeof (dba_status_vector)); dba_status = dba_status_vector; } //bool dba_throw; Firebird::UtilSvc* uSvc; - dba_fil* files; + dba_fil* file; dba_rel* relations; USHORT page_size; USHORT dp_per_pp; @@ -270,7 +255,6 @@ public: pag* global_buffer; int exit_code; dba_mem *head_of_mem_list; - open_files *head_of_files_list; ISC_STATUS *dba_status; ISC_STATUS_ARRAY dba_status_vector; @@ -613,7 +597,7 @@ int gstat(Firebird::UtilSvc* uSvc) expandDatabaseName(fileName, tempStr, NULL); fileName = tempStr; - dba_fil* current = db_open(fileName.c_str(), fileName.length()); + dba_fil* file = db_open(fileName.c_str(), fileName.length()); alignas(DIRECT_IO_BLOCK_SIZE) SCHAR temp[MAX(RAW_HEADER_SIZE, DIRECT_IO_BLOCK_SIZE)]; tddba->page_size = MAX(RAW_HEADER_SIZE, DIRECT_IO_BLOCK_SIZE); @@ -661,38 +645,6 @@ int gstat(Firebird::UtilSvc* uSvc) if (sw_header) dba_exit(FINI_OK, tddba); - // gather continuation files - - while (true) - { - if (page != HEADER_PAGE) - { - current = db_open(file_name, static_cast(strlen(file_name))); - header = (const header_page*) db_read(page); - } - - if (current != tddba->files) - current->fil_fudge = 1; // ignore header page once read it - - PathName nextFileName; - - const UCHAR* vp = header->hdr_data; - for (const auto vend = reinterpret_cast(header) + header->hdr_page_size; - vp < vend && *vp != HDR_end; vp += 2 + vp[1]) - { - if (*vp == HDR_file) - nextFileName.assign(vp + 2, vp[1]); - - if (*vp == HDR_last_page) - memcpy(¤t->fil_max_page, vp + 2, sizeof(current->fil_max_page)); - } - - if (nextFileName.isEmpty()) - break; - - page = current->fil_max_page + 1; // first page of next file - } - if (sw_enc) { class Statist @@ -724,6 +676,7 @@ int gstat(Firebird::UtilSvc* uSvc) private: ULONG enc, non; }; + Statist data, index, blob, generator, other; ULONG last = lastUsedPage(header->hdr_page_size); @@ -766,18 +719,6 @@ int gstat(Firebird::UtilSvc* uSvc) dba_exit(FINI_OK, tddba); } - // print continuation file sequence - - dba_print(false, 7); - // msg 7: \n\nDatabase file sequence: - for (current = tddba->files; current->fil_next; current = current->fil_next) - { - dba_print(false, 8, SafeArg() << current->fil_string << current->fil_next->fil_string); - // msg 8: File %s continues as file %s - } - dba_print(false, 9, SafeArg() << current->fil_string << ((current == tddba->files) ? "only" : "last")); - // msg 9: File %s is the %s file\n - // Check to make sure that the user accessing the database is either // SYSDBA or owner of the database @@ -1192,22 +1133,11 @@ int gstat(Firebird::UtilSvc* uSvc) alloced = alloced->mem_next; } - // close files - open_files* open_file = tddba->head_of_files_list; - while (open_file) - { - db_close(open_file->desc); - open_file = open_file->open_files_next; - } + // close file + if (tddba->file) + db_close(tddba->file->fil_desc); // free linked lists - while (tddba->head_of_files_list != 0) - { - open_files* tmp1 = tddba->head_of_files_list; - tddba->head_of_files_list = tddba->head_of_files_list->open_files_next; - delete tmp1; - } - while (tddba->head_of_mem_list != 0) { dba_mem* tmp2 = tddba->head_of_mem_list; @@ -1865,29 +1795,12 @@ static dba_fil* db_open(const char* file_name, USHORT file_length) **************************************/ tdba* tddba = tdba::getSpecific(); - dba_fil* fil; + const auto file = (dba_fil*) alloc(sizeof(dba_fil) + file_length + 1); - if (tddba->files) - { - for (fil = tddba->files; fil->fil_next; fil = fil->fil_next); - fil->fil_next = (dba_fil*) alloc(sizeof(dba_fil) + file_length + 1); - fil->fil_next->fil_min_page = fil->fil_max_page + 1; - fil = fil->fil_next; - } - else - { - // empty list - fil = tddba->files = (dba_fil*) alloc(sizeof(dba_fil) + file_length + 1); - fil->fil_min_page = 0L; - } + strcpy(file->fil_string, file_name); + file->fil_length = file_length; - fil->fil_next = NULL; - strcpy(fil->fil_string, file_name); - fil->fil_length = file_length; - fil->fil_fudge = 0; - fil->fil_max_page = 0L; - - fil->fil_desc = CreateFile( file_name, + file->fil_desc = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, @@ -1895,31 +1808,15 @@ static dba_fil* db_open(const char* file_name, USHORT file_length) FILE_ATTRIBUTE_NORMAL, 0); - if (fil->fil_desc == INVALID_HANDLE_VALUE) + if (file->fil_desc == INVALID_HANDLE_VALUE) { tddba->uSvc->getStatusAccessor().setServiceStatus(GSTAT_MSG_FAC, 29, SafeArg() << file_name); // msg 29: Can't open database file %s db_error(GetLastError()); } - open_files* file_list = FB_NEW_POOL(*getDefaultMemoryPool()) open_files; - if (!file_list) - { - // NOMEM: return error - dba_error(31); - } - file_list->desc = fil->fil_desc; - file_list->open_files_next = 0; - - if (tddba->head_of_files_list == 0) - tddba->head_of_files_list = file_list; - else - { - file_list->open_files_next = tddba->head_of_files_list; - tddba->head_of_files_list = file_list; - } - - return fil; + tddba->file = file; + return file; } @@ -1945,17 +1842,9 @@ static const pag* db_read( SLONG page_number, bool ok_enc) tddba->page_number = page_number; - dba_fil* fil; - for (fil = tddba->files; page_number > (SLONG) fil->fil_max_page && fil->fil_next;) - { - fil = fil->fil_next; - } - - page_number -= fil->fil_min_page - fil->fil_fudge; - LARGE_INTEGER liOffset; liOffset.QuadPart = UInt32x32To64((DWORD) page_number, (DWORD) tddba->page_size); - if (SetFilePointer(fil->fil_desc, (LONG) liOffset.LowPart, &liOffset.HighPart, FILE_BEGIN) == + if (SetFilePointer(tddba->file->fil_desc, (LONG) liOffset.LowPart, &liOffset.HighPart, FILE_BEGIN) == (DWORD) -1) { int lastError = GetLastError(); @@ -1968,7 +1857,7 @@ static const pag* db_read( SLONG page_number, bool ok_enc) } SLONG actual_length; - if (!ReadFile( fil->fil_desc, + if (!ReadFile( tddba->file->fil_desc, tddba->global_buffer, tddba->page_size, reinterpret_cast(&actual_length), @@ -2057,54 +1946,20 @@ static dba_fil* db_open(const char* file_name, USHORT file_length) **************************************/ tdba* tddba = tdba::getSpecific(); - dba_fil* fil; - if (tddba->files) - { - for (fil = tddba->files; fil->fil_next; fil = fil->fil_next) - ; - fil->fil_next = (dba_fil*) alloc(sizeof(dba_fil) + file_length + 1); - fil->fil_next->fil_min_page = fil->fil_max_page + 1; - fil = fil->fil_next; - } - else - { - // empty list + const auto file = (dba_fil*) alloc(sizeof(dba_fil) + file_length + 1); - fil = tddba->files = (dba_fil*) alloc(sizeof(dba_fil) + file_length + 1); - fil->fil_min_page = 0L; - } + strcpy(file->fil_string, file_name); + file->fil_length = file_length; - fil->fil_next = NULL; - strcpy(fil->fil_string, file_name); - fil->fil_length = file_length; - fil->fil_fudge = 0; - fil->fil_max_page = 0L; - - if ((fil->fil_desc = os_utils::open(file_name, O_RDONLY)) == -1) + if ((file->fil_desc = os_utils::open(file_name, O_RDONLY)) == -1) { tddba->uSvc->getStatusAccessor().setServiceStatus(GSTAT_MSG_FAC, 29, SafeArg() << file_name); // msg 29: Can't open database file %s db_error(errno); } - open_files* file_list = FB_NEW_POOL(*getDefaultMemoryPool()) open_files; - if (!file_list) - { - // NOMEM: return error - dba_error(31); - } - file_list->desc = fil->fil_desc; - file_list->open_files_next = 0; - - if (tddba->head_of_files_list == 0) - tddba->head_of_files_list = file_list; - else - { - file_list->open_files_next = tddba->head_of_files_list; - tddba->head_of_files_list = file_list; - } - - return fil; + tddba->file = file; + return file; } @@ -2127,15 +1982,8 @@ static const pag* db_read( SLONG page_number, bool ok_enc) tddba->page_number = page_number; - dba_fil* fil; - for (fil = tddba->files; page_number > (SLONG) fil->fil_max_page && fil->fil_next;) - { - fil = fil->fil_next; - } - - page_number -= fil->fil_min_page - fil->fil_fudge; const FB_UINT64 offset = ((FB_UINT64) page_number) * ((FB_UINT64) tddba->page_size); - if (os_utils::lseek (fil->fil_desc, offset, 0) == -1) + if (os_utils::lseek (tddba->file->fil_desc, offset, 0) == -1) { tddba->uSvc->getStatusAccessor().setServiceStatus(GSTAT_MSG_FAC, 30, SafeArg()); // msg 30: Can't read a database page @@ -2145,7 +1993,7 @@ static const pag* db_read( SLONG page_number, bool ok_enc) USHORT length = tddba->page_size; for (SCHAR* p = (SCHAR *) tddba->global_buffer; length > 0;) { - const int l = read(fil->fil_desc, p, length); + const int l = read(tddba->file->fil_desc, p, length); if (l < 0) { tddba->uSvc->getStatusAccessor().setServiceStatus(GSTAT_MSG_FAC, 30, SafeArg()); diff --git a/src/utilities/gstat/ppg.cpp b/src/utilities/gstat/ppg.cpp index 88380c898b..40b773e03e 100644 --- a/src/utilities/gstat/ppg.cpp +++ b/src/utilities/gstat/ppg.cpp @@ -231,17 +231,6 @@ void PPG_print_header(const header_page* header, bool nocreation, Firebird::Util uSvc->printf(false, "\tRoot file name:\t\t%s\n", temp); break; - case HDR_file: - memcpy(temp, p + 2, p[1]); - temp[p[1]] = '\0'; - uSvc->printf(false, "\tContinuation file:\t\t%s\n", temp); - break; - - case HDR_last_page: - memcpy(&number, p + 2, sizeof(number)); - uSvc->printf(false, "\tLast logical page:\t\t%ld\n", number); - break; - case HDR_sweep_interval: memcpy(&number, p + 2, sizeof(number)); uSvc->printf(false, "\tSweep interval:\t\t%ld\n", number); diff --git a/src/utilities/rebuild/rebuild.cpp b/src/utilities/rebuild/rebuild.cpp index d15caa95d7..8d8d1cadb2 100644 --- a/src/utilities/rebuild/rebuild.cpp +++ b/src/utilities/rebuild/rebuild.cpp @@ -63,7 +63,6 @@ static void format_index_root(index_root_page*, int, SSHORT, SSHORT); static void format_pointer(pointer_page*, int, SSHORT, SSHORT, bool, SSHORT, const SLONG*); static void format_pip(page_inv_page*, int, int); static void format_tip(tx_inv_page*, int, SLONG); -static void get_next_file(rbdb*, header_page*); static void get_range(TEXT***, const TEXT* const* const, ULONG*, ULONG*); static void get_switch(TEXT**, swc*); static header_page* open_database(rbdb*, ULONG); @@ -197,8 +196,7 @@ int main( int argc, char *argv[]) rbdb = (rbdb*) RBDB_alloc((SLONG) (sizeof(struct rbdb) + strlen(db_in))); strcpy(rbdb->rbdb_file.fil_name, db_in); rbdb->rbdb_file.fil_length = strlen(db_in); - if (header = open_database(rbdb, pg_size)) - get_next_file(rbdb, header); + header = open_database(rbdb, pg_size); // some systems don't care for this write sharing stuff... if (rbdb && (sw_dump_tips || sw_dump_pages)) @@ -210,7 +208,6 @@ int main( int argc, char *argv[]) } } - gdbb = &tdbb_struct; gdbb->tdbb_database = &dbb_struct; gdbb->tdbb_transaction = &dull; @@ -252,17 +249,15 @@ int main( int argc, char *argv[]) fclose(dbg_file); if (rbdb) + { RBDB_close(rbdb); - while (rbdb) - { - rbdb* const next_db = rbdb->rbdb_next; if (rbdb->rbdb_buffer1) gds__free(rbdb->rbdb_buffer1); if (rbdb->rbdb_buffer2) gds__free(rbdb->rbdb_buffer2); + gds__free(rbdb); - rbdb = next_db; } return 0; @@ -332,8 +327,7 @@ void RBDB_close( rbdb* rbdb) * Functional description * **************************************/ - for (; rbdb; rbdb = rbdb->rbdb_next) - close(rbdb->rbdb_file.fil_file); + close(rbdb->rbdb_file.fil_file); } @@ -732,36 +726,6 @@ static void format_tip( tx_inv_page* page, int page_size, SLONG next_page) } -static void get_next_file( rbdb* rbdb, header_page* header) -{ -/************************************** - * - * g e t _ n e x t _ f i l e - * - ************************************** - * - * Functional description - * If there's another file as part of - * this database, get it now. - * - **************************************/ - rbdb** next = &rbdb->rbdb_next; - const UCHAR* p = header->hdr_data; - for (const UCHAR* const end = p + header->hdr_page_size; p < end && *p != HDR_end; p += 2 + p[1]) - { - if (*p == HDR_file) - { - rbdb* next_rbdb = (rbdb*) RBDB_alloc(sizeof(struct rbdb) + (SSHORT) p[1]); - next_rbdb->rbdb_file.fil_length = (SSHORT) p[1]; - strncpy(next_rbdb->rbdb_file.fil_name, p + 2, (SSHORT) p[1]); - *next = next_rbdb; - next = &next_rbdb->rbdb_next; - break; - } - } -} - - static void get_range(TEXT*** argv, const TEXT* const* const end, ULONG* lower, ULONG* upper) { /**************************************