📄 ck_readwrite.cxx
字号:
} else { if (! coreGeneration[current].ReserveDataPage() ) { MsgLog::dprintf(true, "Could not reserve log space for page\n"); goto release_dirent; } coreGeneration[current].Release(cde); cde->lid = UNDEF_LID; cde->type = FRM_TYPE_DPAGE; } /* This must be deferred until we are past the possibility of a * checkpoint. */ if (neededDirent) coreGeneration[current].AddToOidMap(cde);#ifdef DBG_WILD_PTR Checkpoint::CheckConsistency(false); if (dbg_wild_ptr) { Check::Consistency("Bottom RegisterDirtyObject()"); Check::Nodes(); }#endif pObj->SetDirtyFlag(); pObj->ClearFlags(OFLG_CKPT); return;release_dirent: if (!neededDirent) goto take_checkpoint; DEBUG(dirent) MsgLog::dprintf(false, "Releasing disk dirent.\n"); coreGeneration[current].UnreserveDirent(); coreGeneration[current].alloc.nCoreDirent--;release_core_dirent: assert (neededDirent && cde != 0 && cde != CkNIL); DEBUG(dirent) MsgLog::dprintf(false, "Releasing core dirent.\n"); delete cde;take_checkpoint:#ifdef DBG_WILD_PTR Checkpoint::CheckConsistency(false);#endif DEBUG(dirent) MsgLog::dprintf(false, "Taking checkpoint.\n");#ifdef DBG_WILD_PTR if (dbg_wild_ptr) Check::Consistency("RegisterDirtyObject() before TakeCheckpoint()");#endif TakeCheckpoint();}lid_tCheckpoint::GetLidForPage(ObjectHeader *pObj){ assert(pObj->obType == ObType::PtDataPage);#ifdef DBG_WILD_PTR Checkpoint::CheckConsistency(false);#endif uint32_t gen = pObj->GetFlags(OFLG_CKPT) ? last_ckpt : current; DEBUG(reservation) MsgLog::dprintf(false, "Assigning log loc for 0x%08x%08x, generation %d\n", (uint32_t) (pObj->ob.oid >> 32), (uint32_t) pObj->ob.oid, gen); CoreGeneration *pGen = &coreGeneration[gen]; CoreDirent *cde = FindObject(pObj->ob.oid, (ObType::Type) pObj->obType, gen); assert (cde); /* type should be valid */ #ifndef NDEBUG if (cde == CkNIL) { MsgLog::fatal("GetLDEforPage(): Looking for pg 0x%08x%08x gen=%d, not found\n", (uint32_t) (pObj->ob.oid >> 32), (uint32_t) pObj->ob.oid, gen); }#endif assert(cde != CkNIL); assert ( (EROS_PAGE_SIZE % sizeof(uint32_t)) == 0 ); /* GetLogDirentForPage is only called when writing a dirty page to * the checkpoint area. If page is dirty, it will not have a * directory entry indicating a zero page. */ assert (cde->type != FRM_TYPE_ZDPAGE); bool isZero = true; uint32_t *pData = (uint32_t *) ObjectCache::ObHdrToPage(pObj); for (uint32_t i = 0; i < (EROS_PAGE_SIZE/sizeof(uint32_t)); i++) { if (pData[i]) { isZero = false; break; } } /* It would be nice if we could assume that /cde->lid == UNDEF_LID/. * Regrettably, we can allocate a lid here in the call to * pGen->Allocate() and then yield trying to obtain an IoRequest * structure with which to actually write the frame. When we * subsequently try to rewrite the page, we will discover the * previously allocated lid. Note that we do not try to decommit * the previously assigned location -- in all likelihood it was * assigned very recently, and we do not want the effort to bring in * the frame to be wasted. * * Just to make life interesting, however, it is possible that some * other operation has zeroed the page in the interim. In that * case, we need to release the allocated storage. */ cde->count = pObj->ob.allocCount; if (isZero) { pGen->Release(cde); cde->lid = ZERO_LID; cde->type = FRM_TYPE_ZDPAGE; } else { pGen->Allocate(cde); assert ( cde->type == FRM_TYPE_DPAGE ); }#ifdef DBG_WILD_PTR Checkpoint::CheckConsistency(false);#endif return cde->lid;}Node *Checkpoint::LoadCurrentNode(CoreDirent *cde){ assert (cde); assert (cde != CkNIL); assert (cde->type == FRM_TYPE_NODE || cde->type == FRM_TYPE_ZNODE); Node *pNode; if (cde->type == FRM_TYPE_ZNODE) { assert (cde->lid == ZERO_LID); DEBUG(ndload) MsgLog::printf("Loading zero node 0x%08x%08x\n", (uint32_t) (cde->oid>>32), (uint32_t) (cde->oid)); pNode = ObjectCache::GrabNodeFrame(); assert (pNode); assert(ObjectCache::ValidNodePtr(pNode)); assert (pNode->kr.IsEmpty()); assert (pNode->obType == ObType::NtUnprepared); pNode->ob.allocCount = cde->count; pNode->callCount = cde->count; pNode->ob.oid = cde->oid; for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) { assert (pNode->slot[i].IsUnprepared()); /* not hazarded because newly loaded node */ pNode->slot[i].NH_VoidKey(); } } else { assert (cde->type == FRM_TYPE_NODE); assert (cde->lid != ZERO_LID); DEBUG(ndload) MsgLog::printf("Loading non-zero node 0x%08x%08x lid=0x%08x\n", (uint32_t) (cde->oid>>32), (uint32_t) (cde->oid), cde->lid); ObjectHeader *pObj = Persist::GetCkFrame(cde->lid); assert(pObj); if (pObj->IsDirty()) Persist::WritePage(pObj, true); pObj->TransLock(); DiskNode *which = (DiskNode*) ObjectCache::ObHdrToPage(pObj); which += (cde->lid % EROS_OBJECTS_PER_FRAME); pNode = ObjectCache::GrabNodeFrame(); assert(pNode); assert(ObjectCache::ValidNodePtr(pNode)); assert (pNode->kr.IsEmpty()); assert (pNode->obType == ObType::NtUnprepared); (*pNode) = *which; pObj->TransUnlock(); }#ifdef OPTION_OB_MOD_CHECK pNode->ob.check = pNode->CalcCheck();#endif pNode->SetFlags(OFLG_CURRENT|OFLG_DISKCAPS); assert (pNode->GetFlags(OFLG_CKPT|OFLG_DIRTY|OFLG_REDIRTY|OFLG_IO) == 0);#if 0 MsgLog::printf("Interning node (hdr=0x%08x)...\n", pNode);#endif pNode->ResetKeyRing(); pNode->Intern(); assert (pNode->Validate()); return pNode;}ObjectHeader *Checkpoint::LoadCurrentPage(CoreDirent * cde){ assert (cde != CkNIL); assert (cde->type == FRM_TYPE_DPAGE || cde->type == FRM_TYPE_ZDPAGE); ObjectHeader *pPage;#if 1 if (cde->oid == 0x2f000) MsgLog::dprintf(true, "Loading pg 0x2f000 from ckpt\n");#endif if (cde->type == FRM_TYPE_ZDPAGE) { pPage = ObjectCache::GrabPageFrame(); uint8_t *pbuf = (uint8_t *) ObjectCache::ObHdrToPage(pPage); bzero( (void *) pbuf, EROS_PAGE_SIZE ); } else { pPage = Persist::GetCkFrame(cde->lid); if (pPage->IsDirty()) Persist::WritePage(pPage, true); pPage->Unintern(); } #if 0 MsgLog::printf("In-core log hdr 0x%08x\n", pPage);#endif pPage->age = Age::NewBorn; pPage->ob.oid = cde->oid; pPage->ob.allocCount = cde->count; pPage->SetFlags(OFLG_CURRENT|OFLG_DISKCAPS); assert (pPage->GetFlags(OFLG_CKPT|OFLG_DIRTY|OFLG_REDIRTY|OFLG_IO) == 0); pPage->ob.ioCount = 0; pPage->obType = ObType::PtDataPage;#ifdef OPTION_OB_MOD_CHECK pPage->ob.check = pPage->CalcCheck();#endif pPage->ResetKeyRing(); pPage->Intern(); return pPage;}/* Note on the FindXxx() family. We are looking for an object of * given type in each generation. If we don't find it, but we find * some other object *in the same frame* whose type is not the same as * the object type we are hunting for, then the frame has been * retagged and the object we are after does not exist. */CoreDirent*Checkpoint::FindObject(OID oid, ObType::Type oty, uint8_t generation){ /* If no ckpt range found, don't bother. */ if (totLogFrame == 0) return 0; for (uint8_t g = generation; g < nGeneration; g++) { CoreDirent* cde = coreGeneration[g].FindObject(oid); if (cde != CkNIL) { switch((unsigned)oty) { /* suppress incomplete switch warnings... */ case ObType::PtDataPage: if (cde->type == FRM_TYPE_DPAGE || cde->type == FRM_TYPE_ZDPAGE) return cde; break; case ObType::NtUnprepared: if (cde->type == FRM_TYPE_NODE || cde->type == FRM_TYPE_ZNODE) return cde; break; } return 0; } else { cde = coreGeneration[g].FindFrame(oid); if (cde == CkNIL) continue; switch((unsigned)oty) { /* suppress incomplete switch warnings */ case ObType::PtDataPage: if (cde->type != FRM_TYPE_DPAGE && cde->type != FRM_TYPE_ZDPAGE) return 0; break; case ObType::NtUnprepared: if (cde->type != FRM_TYPE_NODE && cde->type != FRM_TYPE_ZNODE) return 0; break; } } } return CkNIL;}#ifdef OPTION_DDBvoidCheckpoint::ddb_showhdrloc(){ extern void db_printf(const char *fmt, ...); db_printf("Checkpoint headers at %d and %d\n", 0, 1); db_printf("Next thread locs at"); for (int i = 0; i < nThreadDirPage; i++) db_printf(" 0x%08x", (uint32_t) nextThreadDirLid[i]); db_printf("\n"); db_printf("Last thread locs at"); for (int i = 0; i < nThreadDirPage; i++) db_printf(" 0x%08x", (uint32_t) lastThreadDirLid[i]); db_printf("\n"); db_printf("Next reserce locs at"); for (int i = 0; i < nReserveDirPage; i++) db_printf(" 0x%08x", (uint32_t) nextReserveDirLid[i]); db_printf("\n"); db_printf("Last reserce locs at"); for (int i = 0; i < nReserveDirPage; i++) db_printf(" 0x%08x", (uint32_t) lastReserveDirLid[i]); db_printf("\n"); db_printf("Next ckpt dir pgs at"); for (uint32_t i = 0; i < nextCkptHdr->nDirPage; i++) db_printf(" 0x%08x", (uint32_t) nextCkptHdr->dirPage[i]); db_printf("\n"); db_printf("Last ckpt dir pgs at"); for (uint32_t i = 0; i < lastCkptHdr->nDirPage; i++) db_printf(" 0x%08x", (uint32_t) lastCkptHdr->dirPage[i]); db_printf("\n");}voidCheckpoint::ddb_showalloc(){ extern void db_printf(const char *fmt, ...); db_printf("HDR: TotLog: %d Avail: %d Reserved: %d Allocated: %d\n", totLogFrame, nAvailLogFrame, nReservedLogFrame, nAllocatedLogFrame, allocMap.NumAllocated()); db_printf("HDR: masterLoc: %d TrueAlloc: %d Migrator: %s nChk %d\n", nMasterPage, allocMap.NumAllocated(), MigStateName(), nCheckpointsCompleted); CoreDirent::ddb_showalloc(); for (uint32_t gen = 0; gen < nGeneration; gen++) coreGeneration[gen].ddb_showalloc();}voidCheckpoint::ddb_dump_pgtree(uint32_t g){ extern void db_printf(const char *fmt, ...); if (g >= nGeneration) db_printf("Only %d generations\n", nGeneration); else coreGeneration[g].oidTree->DumpTree(0);}voidCheckpoint::ddb_dump_ndtree(uint32_t g){ extern void db_printf(const char *fmt, ...); if (g >= nGeneration) db_printf("Only %d generations\n", nGeneration); else coreGeneration[g].oidTree->DumpTree(0);}voidCheckpoint::ddb_dumpdir(uint32_t generation){ uint32_t count; extern void db_printf(const char *fmt, ...); if ( coreGeneration[generation].oidTree == CkNIL ) { db_printf("ckpt directory is empty\n"); return; } count = 0; if (coreGeneration[generation].oidTree != CkNIL) { CoreDirent *cde = coreGeneration[generation].oidTree->Minimum(); while (cde != CkNIL) { const char *cty = "??"; switch(cde->type) { case FRM_TYPE_ZDPAGE: cty = "zd"; break; case FRM_TYPE_DPAGE: cty = "dp"; break; case FRM_TYPE_NODE: cty = "nd"; break; case FRM_TYPE_ZNODE: cty = "zn"; break; } db_printf("[%3d] %s 0x%08x%08x ac=0x%08x lid=0x%08x gen: %d\n", count, cty, (uint32_t) (cde->oid>>32), (uint32_t) cde->oid, cde->count, cde->lid, generation); count++; cde = cde->Successor(); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -