[eros-cvs] cvs commit: eros/src/base/sys/ckpt ck_Retag.cxx

shap@eros.cs.jhu.edu shap@eros.cs.jhu.edu
Tue, 24 Apr 2001 11:14:12 -0400


shap        01/04/24 11:14:12

  Modified:    src/base/sys/ckpt ck_Retag.cxx
  Log:
  This change fixes (or at least *appears* to fix) the panic in
  RetagFrame, which was the result of zapping PTEs after a commit. I'm
  not entirely happy with the whole strategy at this point, but a more
  serious repair is going to have to wait for greater leisure.

Revision  Changes    Path
1.16      +68 -9     eros/src/base/sys/ckpt/ck_Retag.cxx

Index: ck_Retag.cxx
===================================================================
RCS file: /cvs/eros/src/base/sys/ckpt/ck_Retag.cxx,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ck_Retag.cxx	2001/01/08 20:57:51	1.15
+++ ck_Retag.cxx	2001/04/24 15:14:12	1.16
@@ -226,6 +226,10 @@
 
   assert (curType != newType);
   
+  assert(curType == FRM_TYPE_ZNODE ||
+	 curType == FRM_TYPE_ZDPAGE ||
+	 curType == FRM_TYPE_ZCPAGE);
+  
   /* We now know everything we need to know about the current frame.
    * Reserve space for the new objects:
    */
@@ -234,6 +238,60 @@
 
   CleanCkptFrames(curType, fi);
   
+  /* Since we will be commited to making progress after we reserve the
+     log directories, ensure that any cached state associated with the
+     OLD object is killed before we reserve them. */
+  
+  switch(curType) {
+  case FRM_TYPE_ZDPAGE:
+  case FRM_TYPE_DPAGE:
+  case FRM_TYPE_ZCPAGE:
+  case FRM_TYPE_CPAGE:
+    {
+      ObjectHeader *pObj;
+      
+      if (curType == FRM_TYPE_ZDPAGE || curType == FRM_TYPE_DPAGE)
+	pObj = ObjectHeader::Lookup(ObType::PtDataPage, fi.oid);
+      else
+	pObj = ObjectHeader::Lookup(ObType::PtCapPage, fi.oid);
+
+      if (pObj) {
+	if (pObj->GetFlags(OFLG_CKPT))
+	  assert(pObj->IsDirty() == false);
+      
+	pObj->kr.UnprepareAll(); /* This zaps any PTE's as a side effect. */
+	pObj->InvalidateProducts();
+
+	assert ( PTE::ObIsNotWritable(pObj) );
+      }
+
+      break;
+    }
+  case FRM_TYPE_ZNODE:
+  case FRM_TYPE_NODE:
+    {
+      for (uint32_t n = 0; n < DISK_NODES_PER_PAGE; n++) {
+	OID oid = fi.obFrameOid + n;
+
+	Node * pNode = ObjectHeader::LookupNode(oid);
+	assert(pNode);		/* we pinned them previously! */
+
+	if (pNode->GetFlags(OFLG_CKPT))
+	  assert(pNode->IsDirty() == false);
+
+	pNode->Unprepare(false);
+	pNode->kr.UnprepareAll();
+
+	for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) {
+	  assert ( (*pNode)[i].IsHazard() == false );
+	  (*pNode)[i].NH_Unprepare();
+	  assert ( (*pNode)[i].IsUnprepared() );
+	}
+      }
+      break;
+    }
+  }
+
   /* Make sure we have sufficient core and disk directory entries: */
   if (CoreDirent::Require(nObjects) == false)
     TakeCheckpoint();
@@ -297,8 +355,8 @@
 	if (pObj->GetFlags(OFLG_CKPT))
 	  assert(pObj->IsDirty() == false);
       
-	pObj->kr.UnprepareAll(); /* This zaps any PTE's as a side effect. */
-	pObj->InvalidateProducts();
+	assert ( pObj->kr.IsEmpty() );
+	assert ( pObj->products == 0 );
 
 	assert ( PTE::ObIsNotWritable(pObj) );
 
@@ -332,8 +390,8 @@
 	if (pObj->GetFlags(OFLG_DISKCAPS))
 	  needBump = true;
 
-	pObj->kr.UnprepareAll(); /* This zaps any PTE's as a side effect. */
-	pObj->InvalidateProducts();
+	assert ( pObj->kr.IsEmpty() );
+	assert ( pObj->products == 0 );
 
 	assert ( PTE::ObIsNotWritable(pObj) );
 
@@ -372,14 +430,15 @@
 	if (pNode->GetFlags(OFLG_DISKCAPS))
 	  needBump = true;
 
-	pNode->Unprepare(false);
-	pNode->kr.UnprepareAll();
+	assert (pNode->obType == ObType::NtUnprepared);
+	assert (pNode->kr.IsEmpty());
 
+#ifndef NDEBUG
 	for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) {
-	  if ( (*pNode)[i].IsHazard() )
-	    pNode->ClearHazard(i);
-	  (*pNode)[i].NH_Unprepare();
+	  assert ( (*pNode)[i].IsHazard() == false );
+	  assert ( (*pNode)[i].IsUnprepared() );
 	}
+#endif
 
 #ifdef OFLG_PIN
 	pNode->ClearFlags(OFLG_PIN);