Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions src/jrd/jrd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,33 @@ namespace
}
}

USHORT validatePageSize(SLONG pageSize)
{
USHORT actualPageSize = DEFAULT_PAGE_SIZE;

if (pageSize > 0)
{
for (SLONG size = MIN_PAGE_SIZE; size <= MAX_PAGE_SIZE; size <<= 1)
{
if (pageSize <= size)
{
pageSize = size;
break;
}
}

if (pageSize > MAX_PAGE_SIZE)
pageSize = MAX_PAGE_SIZE;

fb_assert(pageSize <= MAX_USHORT);
actualPageSize = (USHORT) pageSize;
}

fb_assert(actualPageSize % PAGE_SIZE_BASE == 0);
fb_assert(actualPageSize >= MIN_PAGE_SIZE && actualPageSize <= MAX_PAGE_SIZE);

return actualPageSize;
}

class DefaultCallback : public AutoIface<ICryptKeyCallbackImpl<DefaultCallback, CheckStatusWrapper> >
{
Expand Down Expand Up @@ -3005,18 +3032,7 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch

attachment->att_client_charset = attachment->att_charset = options.dpb_interp;

if (options.dpb_page_size <= 0) {
options.dpb_page_size = DEFAULT_PAGE_SIZE;
}

SLONG page_size = MIN_PAGE_SIZE;
for (; page_size < MAX_PAGE_SIZE; page_size <<= 1)
{
if (options.dpb_page_size < page_size << 1)
break;
}

dbb->dbb_page_size = (page_size > MAX_PAGE_SIZE) ? MAX_PAGE_SIZE : page_size;
dbb->dbb_page_size = validatePageSize(options.dpb_page_size);

TRA_init(attachment);

Expand Down Expand Up @@ -7634,20 +7650,22 @@ static JAttachment* create_attachment(const PathName& alias_name,

static void check_single_maintenance(thread_db* tdbb)
{
Database* const dbb = tdbb->getDatabase();
const auto dbb = tdbb->getDatabase();
const auto attachment = tdbb->getAttachment();

const ULONG ioBlockSize = dbb->getIOBlockSize();
const ULONG headerSize = MAX(RAW_HEADER_SIZE, ioBlockSize);

HalfStaticArray<UCHAR, RAW_HEADER_SIZE + PAGE_ALIGNMENT> temp;
UCHAR* header_page_buffer = temp.getAlignedBuffer(headerSize, ioBlockSize);
UCHAR* const header_page_buffer = temp.getAlignedBuffer(headerSize, ioBlockSize);

Ods::header_page* const header_page = reinterpret_cast<Ods::header_page*>(header_page_buffer);
if (!PIO_header(tdbb, header_page_buffer, headerSize))
ERR_post(Arg::Gds(isc_bad_db_format) << Arg::Str(attachment->att_filename));

PIO_header(tdbb, header_page_buffer, headerSize);
const auto header_page = reinterpret_cast<Ods::header_page*>(header_page_buffer);

if (header_page->hdr_shutdown_mode == Ods::hdr_shutdown_single)
ERR_post(Arg::Gds(isc_shutdown) << Arg::Str(tdbb->getAttachment()->att_filename));
ERR_post(Arg::Gds(isc_shutdown) << Arg::Str(attachment->att_filename));
}


Expand Down
3 changes: 3 additions & 0 deletions src/jrd/ods.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ inline constexpr ULONG FIRST_SCN_PAGE = 2;

// Page size limits

inline constexpr USHORT PAGE_SIZE_BASE = 1024; // Minimal page size ever supported,
// common divisor for valid page sizes

inline constexpr USHORT MIN_PAGE_SIZE = 4096;
inline constexpr USHORT MAX_PAGE_SIZE = 32768;

Expand Down
2 changes: 1 addition & 1 deletion src/jrd/os/pio_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void PIO_extend(Jrd::thread_db*, Jrd::jrd_file*, const ULONG, const USHORT);
void PIO_flush(Jrd::thread_db*, Jrd::jrd_file*);
void PIO_force_write(Jrd::jrd_file*, const bool);
ULONG PIO_get_number_of_pages(const Jrd::jrd_file*, const USHORT);
void PIO_header(Jrd::thread_db*, UCHAR*, int);
bool PIO_header(Jrd::thread_db*, UCHAR*, unsigned);
USHORT PIO_init_data(Jrd::thread_db*, Jrd::jrd_file*, Jrd::FbStatusVector*, ULONG, USHORT);
Jrd::jrd_file* PIO_open(Jrd::thread_db*, const Firebird::PathName&,
const Firebird::PathName&);
Expand Down
18 changes: 12 additions & 6 deletions src/jrd/os/posix/unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ error: Raw device support for your OS is missing. Fix it or turn off raw device
}


void PIO_header(thread_db* tdbb, UCHAR* address, int length)
bool PIO_header(thread_db* tdbb, UCHAR* address, unsigned length)
{
/**************************************
*
Expand All @@ -519,13 +519,13 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length)
* Read the page header.
*
**************************************/
Database* const dbb = tdbb->getDatabase();
const auto dbb = tdbb->getDatabase();

int i;
unsigned i;
SINT64 bytes;

PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
jrd_file* file = pageSpace->file;
PageSpace* const pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
jrd_file* const file = pageSpace->file;

if (file->fil_desc == -1)
unix_error("PIO_header", file, isc_io_read_err);
Expand All @@ -537,7 +537,11 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length)
if (bytes < 0 && !SYSCALL_INTERRUPTED(errno))
unix_error("read", file, isc_io_read_err);
if (bytes >= 0)
block_size_error(file, bytes);
{
FbLocalStatus tempStatus;
if (!block_size_error(file, bytes, &tempStatus))
return false;
}
}

if (i == IO_RETRY)
Expand All @@ -558,6 +562,8 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length)
unix_error("read_retry", file, isc_io_read_err);
}
}

return true;
}

// we need a class here only to return memory on shutdown and avoid
Expand Down
16 changes: 9 additions & 7 deletions src/jrd/os/win32/winnt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ void PIO_force_write(jrd_file* file, const bool forceWrite)
}


void PIO_header(thread_db* tdbb, UCHAR* address, int length)
bool PIO_header(thread_db* tdbb, UCHAR* address, unsigned length)
{
/**************************************
*
Expand All @@ -345,11 +345,11 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length)
* callers should not rely on this behavior
*
**************************************/
Database* const dbb = tdbb->getDatabase();
const auto dbb = tdbb->getDatabase();

PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
jrd_file* file = pageSpace->file;
HANDLE desc = file->fil_desc;
PageSpace* const pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
jrd_file* const file = pageSpace->file;
const HANDLE desc = file->fil_desc;

OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(OVERLAPPED));
Expand All @@ -361,10 +361,12 @@ void PIO_header(thread_db* tdbb, UCHAR* address, int length)
{
if (GetLastError() == ERROR_IO_PENDING)
ret = GetOverlappedResult(desc, &overlapped, &actual_length, TRUE);

if (!ret)
nt_error("ReadFile", file, isc_io_read_err, NULL);
}

if (!ret || (length != actual_length))
nt_error("ReadFile", file, isc_io_read_err, NULL);
return (length == actual_length);
}

// we need a class here only to return memory on shutdown and avoid
Expand Down
11 changes: 8 additions & 3 deletions src/jrd/pag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,10 +1115,15 @@ void PAG_header_init(thread_db* tdbb)
HalfStaticArray<UCHAR, RAW_HEADER_SIZE + PAGE_ALIGNMENT> temp;
UCHAR* const temp_page = temp.getAlignedBuffer(headerSize, ioBlockSize);

PIO_header(tdbb, temp_page, headerSize);
const header_page* header = (header_page*) temp_page;
if (!PIO_header(tdbb, temp_page, headerSize))
ERR_post(Arg::Gds(isc_bad_db_format) << Arg::Str(attachment->att_filename));

const auto header = (header_page*) temp_page;

if (header->hdr_header.pag_type != pag_header || header->hdr_header.pag_pageno != HEADER_PAGE)
ERR_post(Arg::Gds(isc_bad_db_format) << Arg::Str(attachment->att_filename));

if (header->hdr_header.pag_type != pag_header)
if (header->hdr_page_size < PAGE_SIZE_BASE || header->hdr_page_size % PAGE_SIZE_BASE != 0)
ERR_post(Arg::Gds(isc_bad_db_format) << Arg::Str(attachment->att_filename));

const USHORT ods_version = header->hdr_ods_version & ~ODS_FIREBIRD_FLAG;
Expand Down
Loading