8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 13:23:02 +01:00

Backported fix for CORE-5264: To unlock a raw device DB is not working.

This commit is contained in:
Alexander Peshkov 2016-07-15 18:06:05 +03:00
parent 8a67ae05c3
commit 8709dab13b
2 changed files with 63 additions and 35 deletions

View File

@ -60,6 +60,11 @@ bool PIO_status(Jrd::thread_db*, struct Jrd::phys_io_blk*, Jrd::FbStatusVector*)
#ifdef SUPPORT_RAW_DEVICES #ifdef SUPPORT_RAW_DEVICES
bool PIO_on_raw_device(const Firebird::PathName&); bool PIO_on_raw_device(const Firebird::PathName&);
int PIO_unlink(const Firebird::PathName&); int PIO_unlink(const Firebird::PathName&);
#else
inline bool PIO_on_raw_device(const Firebird::PathName&)
{
return false;
}
#endif #endif
bool PIO_write(Jrd::thread_db*, Jrd::jrd_file*, Jrd::BufferDesc*, Ods::pag*, Jrd::FbStatusVector*); bool PIO_write(Jrd::thread_db*, Jrd::jrd_file*, Jrd::BufferDesc*, Ods::pag*, Jrd::FbStatusVector*);

View File

@ -1501,41 +1501,12 @@ SLONG PAG_last_page(thread_db* tdbb)
* shadow stuff to dump a database. * shadow stuff to dump a database.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
PageManager& pageMgr = dbb->dbb_page_manager; return PageSpace::lastUsedPage(dbb);
PageSpace* pageSpace = pageMgr.findPageSpace(DB_PAGE_SPACE);
fb_assert(pageSpace);
const ULONG pages_per_pip = pageMgr.pagesPerPIP;
WIN window(DB_PAGE_SPACE, -1);
// Find the last page allocated
ULONG relative_bit = 0;
USHORT sequence;
for (sequence = 0; true; ++sequence)
{
window.win_page = (!sequence) ? pageSpace->pipFirst : sequence * pages_per_pip - 1;
const page_inv_page* page = (page_inv_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_pages);
const UCHAR* bits = page->pip_bits + (pages_per_pip >> 3) - 1;
while (*bits == (UCHAR) - 1)
--bits;
SSHORT bit;
for (bit = 7; bit >= 0; --bit)
{
if (!(*bits & (1 << bit)))
break;
}
relative_bit = (bits - page->pip_bits) * 8 + bit;
CCH_RELEASE(tdbb, &window);
if (relative_bit != pages_per_pip - 1)
break;
}
return sequence * pages_per_pip + relative_bit;
} }
@ -2064,14 +2035,66 @@ ULONG PageSpace::maxAlloc()
**************************************/ **************************************/
const USHORT pageSize = dbb->dbb_page_size; const USHORT pageSize = dbb->dbb_page_size;
const jrd_file* f = file; const jrd_file* f = file;
ULONG nPages = PIO_get_number_of_pages(f, pageSize); ULONG nPages = 0;
if (maxPageNumber == 0 && !PIO_on_raw_device(f->fil_string))
{
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) while (f->fil_next && nPages == f->fil_max_page - f->fil_min_page + 1 + f->fil_fudge)
{ {
f = f->fil_next; f = f->fil_next;
if (PIO_on_raw_device(f->fil_string))
{
nPages = 0;
break;
}
nPages = PIO_get_number_of_pages(f, pageSize); nPages = PIO_get_number_of_pages(f, pageSize);
} }
if (nPages)
nPages += f->fil_min_page - f->fil_fudge; nPages += f->fil_min_page - f->fil_fudge;
}
if (!nPages)
{
thread_db* tdbb = JRD_get_thread_data();
const ULONG pagesPerPip = dbb->dbb_page_manager.pagesPerPIP;
WIN window(pageSpaceID, -1);
// Find the last page allocated
for (USHORT sequence = maxPageNumber / pagesPerPip; true; ++sequence)
{
window.win_page = (!sequence) ? pipFirst : sequence * pagesPerPip - 1;
ULONG pipUsed = 0;
const page_inv_page* page = NULL;
for (FB_SIZE_T n = 0; n < tdbb->tdbb_bdbs.getCount(); ++n)
{
BufferDesc *bdb = tdbb->tdbb_bdbs[n];
if (bdb && bdb->isLocked() && bdb->bdb_page == window.win_page && bdb->bdb_buffer)
{
page = (page_inv_page*)(bdb->bdb_buffer);
pipUsed = page->pip_used;
break;
}
}
if (!page)
{
page = (page_inv_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_pages);
pipUsed = page->pip_used;
CCH_RELEASE(tdbb, &window);
}
if (pipUsed != pagesPerPip)
{
nPages = sequence * pagesPerPip + pipUsed;
break;
}
}
}
if (maxPageNumber < nPages) if (maxPageNumber < nPages)
maxPageNumber = nPages; maxPageNumber = nPages;