| 193 | { |
| 194 | public: |
| 195 | explicit PhysHdr(Jrd::thread_db* tdbb) |
| 196 | { |
| 197 | // Can't use CCH_fetch_page() here cause it will cause infinite recursion |
| 198 | |
| 199 | Jrd::Database* dbb = tdbb->getDatabase(); |
| 200 | Jrd::BufferControl* bcb = dbb->dbb_bcb; |
| 201 | Jrd::BufferDesc bdb(bcb); |
| 202 | bdb.bdb_page = Jrd::HEADER_PAGE_NUMBER; |
| 203 | |
| 204 | UCHAR* h = FB_NEW_POOL(*MemoryPool::getContextPool()) UCHAR[dbb->dbb_page_size + dbb->getIOBlockSize()]; |
| 205 | buffer.reset(h); |
| 206 | h = FB_ALIGN(h, dbb->getIOBlockSize()); |
| 207 | bdb.bdb_buffer = (Ods::pag*) h; |
| 208 | |
| 209 | Jrd::FbStatusVector* const status = tdbb->tdbb_status_vector; |
| 210 | |
| 211 | Ods::pag* page = bdb.bdb_buffer; |
| 212 | |
| 213 | Jrd::PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(Jrd::DB_PAGE_SPACE); |
| 214 | fb_assert(pageSpace); |
| 215 | |
| 216 | Jrd::jrd_file* file = pageSpace->file; |
| 217 | |
| 218 | Jrd::BackupManager::StateReadGuard stateGuard(tdbb); |
| 219 | Jrd::BackupManager* bm = dbb->dbb_backup_manager; |
| 220 | int bak_state = bm->getState(); |
| 221 | |
| 222 | fb_assert(bak_state != Ods::hdr_nbak_unknown); |
| 223 | |
| 224 | ULONG diff_page = 0; |
| 225 | if (bak_state != Ods::hdr_nbak_normal) |
| 226 | diff_page = bm->getPageIndex(tdbb, bdb.bdb_page.getPageNum()); |
| 227 | |
| 228 | bool readPageAsNormal = false; |
| 229 | if (bak_state == Ods::hdr_nbak_normal || !diff_page) |
| 230 | readPageAsNormal = true; |
| 231 | else |
| 232 | { |
| 233 | if (!bm->readDifference(tdbb, diff_page, page)) |
| 234 | { |
| 235 | if (page->pag_type == 0 && page->pag_generation == 0 && page->pag_scn == 0) |
| 236 | { |
| 237 | // We encountered a page which was allocated, but never written to the |
| 238 | // difference file. In this case we try to read the page from database. With |
| 239 | // this approach if the page was old we get it from DISK, and if the page |
| 240 | // was new IO error (EOF) or BUGCHECK (checksum error) will be the result. |
| 241 | // Engine is not supposed to read a page which was never written unless |
| 242 | // this is a merge process. |
| 243 | readPageAsNormal = true; |
| 244 | } |
| 245 | else |
| 246 | ERR_punt(); |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | if (readPageAsNormal) |
| 251 | { |
| 252 | // Read page from disk as normal |
nothing calls this directly
no test coverage detected