⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 volume.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 3 页
字号:
  ::close(target_fd);  if (target_fd != working_fd)    close(working_fd);    target_fd = -1;  working_fd = -1;#if defined(__linux__) && 0  sync();  sleep(5);			/* linux sync is busted - schedules */				/* the writes but doesn't do them. */  sync();  sleep(5);			/* linux sync is busted - schedules */				/* the writes but doesn't do them. */#endif}uint32_tVolume::GetLogFrameVolOffset(int ndx, const OID& loc){  const Division& d = divTable[ndx];  assert(div_contains(&d, loc));  uint32_t relPage = (uint32_t) (loc - d.startOid);  relPage /= EROS_OBJECTS_PER_FRAME;  uint32_t divStart = d.start * EROS_SECTOR_SIZE;  uint32_t pageOffset = relPage * EROS_PAGE_SIZE;  return divStart + pageOffset;}    uint32_tVolume::GetOidFrameVolOffset(int ndx, const OID& oid){  const Division& d = divTable[ndx];  assert(div_contains(&d, oid));  assert ((d.startOid % EROS_OBJECTS_PER_FRAME) == 0);  uint32_t relPage = (uint32_t) ((oid - d.startOid) / EROS_OBJECTS_PER_FRAME);  relPage += (relPage / DATA_PAGES_PER_PAGE_CLUSTER);  relPage += 1;			/* clusters precede data */  relPage += 1;			/* skip ckpt sequence pg */    uint32_t divStart = d.start * EROS_SECTOR_SIZE;  uint32_t pageOffset = relPage * EROS_PAGE_SIZE;  return divStart + pageOffset;}    /* Return true/false according to whether this is a valid object OID * given the frame type: */boolVolume::ValidOid(int ndx, const OID& oid){  const Division& d = divTable[ndx];  assert(div_contains(&d, oid));  assert (d.type != dt_Log);  uint32_t obOffset = (uint32_t) (oid % EROS_OBJECTS_PER_FRAME);  VolPagePot frameInfo;  GetPagePotInfo(oid, frameInfo);    switch (frameInfo.type) {  case FRM_TYPE_ZDPAGE:  case FRM_TYPE_DPAGE:    return (obOffset == 0) ? true : false;  case FRM_TYPE_NODE:    return (obOffset < DISK_NODES_PER_PAGE) ? true : false;  default:    return false;  }}/* given a division index and a OID, return the volume-relative * offset of the object in that division. */uint32_tVolume::GetOidVolOffset(int ndx, const OID& oid){  const Division& d = divTable[ndx];  assert(div_contains(&d, oid));  assert (d.type != dt_Log);    uint32_t frameStart = GetOidFrameVolOffset(ndx, oid);  uint32_t obOffset = (uint32_t) (oid % EROS_OBJECTS_PER_FRAME);  if (obOffset) {    VolPagePot frameInfo;    GetPagePotInfo(oid, frameInfo);      switch (frameInfo.type) {    case FRM_TYPE_ZDPAGE:    case FRM_TYPE_DPAGE:      obOffset *= EROS_PAGE_SIZE;      break;    case FRM_TYPE_NODE:      obOffset *= sizeof(DiskNode);      break;    default:      Diag::fatal(1, "Unknown object type tag!\n");    }  }  if (obOffset >= EROS_PAGE_SIZE)    Diag::fatal(1, "Bad OID (gives improper offset)\n");      return frameStart + obOffset;}boolVolume::GetPagePotInfo(const OID& oid, VolPagePot& pot){  CkptDirent* cpd = LookupObject(oid);      if (cpd) {    pot.count = cpd->count;    pot.type = cpd->type;    return true;  }    return ReadPagePotEntry(oid, pot);}/* Object I/O support: */boolVolume::ReadDataPage(const OID& oid, uint8_t *buf){  VolPagePot pp;  if (oid % EROS_OBJECTS_PER_FRAME) {    Diag::printf("Page OID must be multiple of %d (0x%x)\n",		 EROS_OBJECTS_PER_FRAME,		 EROS_OBJECTS_PER_FRAME);    return false;  }    if ( GetPagePotInfo(oid, pp) == false ) {    Diag::printf("Requested OID invalid\n");    return false;  }  switch(pp.type) {  case FRM_TYPE_ZDPAGE:    memset(buf, 0, EROS_PAGE_SIZE);    return true;  case FRM_TYPE_DPAGE:    break;  default:    Diag::printf("Requested OID not a page frame\n");    return false;  }    CkptDirent* cpd = LookupObject(oid);      if (cpd) {    assert (CONTENT_LID(cpd->lid));    assert (cpd->type != FRM_TYPE_ZDPAGE);        if (ReadLogPage(cpd->lid, buf) == false)      return false;    return true;  }  for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];        if (((d.type == dt_Object) || (d.type == dt_Kernel)) &&	div_contains(&d, oid)) {      if (ValidOid(div, oid) == false) {	Diag::printf("Requested OID invalid\n");	return false;      }            VolPagePot frameInfo;      ReadPagePotEntry(oid, frameInfo);      if ((frameInfo.type != FRM_TYPE_DPAGE) &&	  (frameInfo.type != FRM_TYPE_ZDPAGE)) {	Diag::printf("Non-page frame\n");	return false;      }            uint32_t offset = GetOidVolOffset(div, oid);      return Read(offset, buf, EROS_PAGE_SIZE);    }  }  return false;}boolVolume::WriteDataPage(const OID& oid, const uint8_t *buf){  bool isZeroPage = true;  for (uint32_t i = 0; i < EROS_PAGE_SIZE; i++)    if (buf[i]) {      isZeroPage = false;      break;    }      CkptDirent* cpd = LookupObject(oid);      if (cpd && cpd->type != FRM_TYPE_DPAGE && cpd->type != FRM_TYPE_ZDPAGE)    return false;    /* If a location has already been fabricated, write it there even if   * it is a zero page.   */  if ( cpd && CONTENT_LID(cpd->lid) ) {    if (WriteLogPage(cpd->lid, buf) == false)      return false;    return true;  }    for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];        if (((d.type == dt_Object) || (d.type == dt_Kernel)) &&	div_contains(&d, oid)) {      VolPagePot frameInfo;      ReadPagePotEntry(oid, frameInfo);      assert ((oid % EROS_OBJECTS_PER_FRAME) == 0);      uint8_t wantTag = isZeroPage ? FRM_TYPE_ZDPAGE : FRM_TYPE_DPAGE;      if (frameInfo.type != wantTag) {	Diag::debug(1, "Re-tagging frame for OID 0x%08x%08x to %d\n",		    (uint32_t) (oid >> 32),		    (uint32_t) (oid),		    wantTag);	frameInfo.type = wantTag;	WritePagePotEntry(oid, frameInfo);      }      uint32_t offset = GetOidVolOffset(div, oid);      if ( !Write(offset, buf, EROS_PAGE_SIZE) )	Diag::fatal(5, "Volume write failed at offset %d.\n", offset);      return true;    }  }    if (rewriting == false)    return false;    /* If we get here, we didn't find what we wanted.  Allocate space   * for this page in the checkpoint log.   */  Diag::fatal(1, "Cannot write page with OID 0x%08x%08x -- no home location\n",	      (uint32_t)(oid>>32), (uint32_t)oid);    lid_t lid = ZERO_LID;  uint8_t type = FRM_TYPE_ZDPAGE;  if (isZeroPage == false) {    lid = AllocLogPage();    type = FRM_TYPE_DPAGE;      if (WriteLogPage(lid, buf) == false)      return false;  }    AddDirent(oid, 0, lid, type);  return true;}/* Log I/O support: */boolVolume::ReadLogPage(const lid_t lid, uint8_t *buf){  for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];        if (d.type == dt_Log && div_contains(&d, lid)) {      uint32_t offset = GetLogFrameVolOffset(div, lid);      return Read(offset, buf, EROS_PAGE_SIZE);    }  }  return false;}boolVolume::WriteLogPage(const lid_t lid, const uint8_t *buf){  for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];        if (d.type == dt_Log && div_contains(&d, lid)) {      uint32_t offset = GetLogFrameVolOffset(div, lid);      if ( !Write(offset, buf, EROS_PAGE_SIZE) )	Diag::fatal(5, "Volume write failed at offset %d.\n", offset);    }  }  return true;}/* given a division index and a OID, return the volume-relative * offset of the page pot for that OID */uint32_tVolume::GetOidPagePotVolOffset(int ndx, const OID& oid){  const Division& d = divTable[ndx];  assert(d.type == dt_Object);  assert(div_contains(&d, oid));    assert ((d.startOid % EROS_OBJECTS_PER_FRAME) == 0);    uint32_t relPage = (uint32_t) ((oid - d.startOid) / EROS_OBJECTS_PER_FRAME);  uint32_t whichCluster = (uint32_t) (relPage / DATA_PAGES_PER_PAGE_CLUSTER);  uint32_t pagePotFrame = whichCluster * PAGES_PER_PAGE_CLUSTER;  pagePotFrame ++;		/* for ckpt sequence number pg */  uint32_t pageOffset = pagePotFrame * EROS_PAGE_SIZE;  uint32_t divStart = d.start * EROS_SECTOR_SIZE;    return divStart + pageOffset;}boolVolume::ReadPagePotEntry(const OID& oid, VolPagePot& pagePot){  for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];    uint8_t data[EROS_PAGE_SIZE];        if ( d.type == dt_Object && div_contains(&d, oid) ) {      bool result;      assert ((d.startOid % EROS_OBJECTS_PER_FRAME) == 0);      uint32_t offset = GetOidPagePotVolOffset(div, oid);      result = Read(offset, data, EROS_PAGE_SIZE);      if (result == false)	return result;      uint32_t relPage = (uint32_t) ((oid - d.startOid) / EROS_OBJECTS_PER_FRAME);            PagePot* pp = (PagePot *) data;      uint32_t potEntry = relPage % DATA_PAGES_PER_PAGE_CLUSTER;      pagePot.type = pp->type[potEntry];      pagePot.count = pp->count[potEntry];      return true;    }  }  return false;}boolVolume::WritePagePotEntry(const OID& oid, const VolPagePot& pagePot){  for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];    uint8_t data[EROS_PAGE_SIZE];        if ( d.type == dt_Object && div_contains(&d, oid) ) {      bool result;      assert ((d.startOid % EROS_OBJECTS_PER_FRAME) == 0);      uint32_t offset = GetOidPagePotVolOffset(div, oid);      result = Read(offset, data, EROS_PAGE_SIZE);      if (result == false)	return result;      uint32_t relPage = (uint32_t) ((oid - d.startOid) / EROS_OBJECTS_PER_FRAME);            PagePot* pp = (PagePot *) data;      uint32_t potEntry = relPage % DATA_PAGES_PER_PAGE_CLUSTER;      pp->type[potEntry] = pagePot.type;      pp->count[potEntry] = pagePot.count;      if ( !Write(offset, data, EROS_PAGE_SIZE) )	Diag::fatal(5, "Volume write failed at offset %d.\n", offset);      return true;    }  }  return false;}boolVolume::ReadNode(const OID& oid, DiskNode& node){  CkptDirent* ccd = LookupObject(oid);      if (ccd && ccd->type == FRM_TYPE_NODE && ccd->lid != UNDEF_LID) {    uint8_t logPage[EROS_PAGE_SIZE];    DiskNode* logPot = (DiskNode *) logPage;    assert (CONTENT_LID(ccd->lid));        if (ReadLogPage(ccd->lid, logPage) == false)      return false;    for (uint32_t i = 0; i < DISK_NODES_PER_PAGE; i++) {      if (logPot[i].oid == oid) {	memcpy(&node, &logPot[i], sizeof(DiskNode));	return true;      }    }    return false;  }    for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];        if (d.type == dt_Object && div_contains(&d, oid)) {      if (ValidOid(div, oid) == false) {	Diag::printf("Requested OID invalid\n");	return false;      }            VolPagePot frameInfo;      ReadPagePotEntry(oid, frameInfo);      if (frameInfo.type != FRM_TYPE_NODE) {	Diag::printf("Non-node frame\n");	return false;      }            uint32_t offset = GetOidVolOffset(div, oid);      return Read(offset, &node, sizeof(DiskNode));    }  }  return false;}boolVolume::WriteNodeToLog(const OID& oid, const DiskNode& node){  assert (oid == node.oid);    if (curLogPotLid == UNDEF_LID) {    curLogPotLid = AllocLogPage();  }  uint8_t logPage[EROS_PAGE_SIZE];  DiskNode* logPot = (DiskNode *) logPage;  if (ReadLogPage(curLogPotLid, logPage) == false)    return false;  uint8_t ndx = curLogPotLid % EROS_OBJECTS_PER_FRAME;    memcpy(&logPot[ndx], &node, sizeof(DiskNode));  if (WriteLogPage(curLogPotLid, logPage) == false)    return false;  AddDirent(oid, 0, curLogPotLid, FRM_TYPE_NODE);  curLogPotLid++;    if (curLogPotLid % EROS_OBJECTS_PER_FRAME == DISK_NODES_PER_PAGE)    curLogPotLid = UNDEF_LID;  return true;}boolVolume::WriteNode(const OID& oid, const DiskNode& node){  CkptDirent* ccd = LookupObject(oid);      if (ccd && ccd->type != FRM_TYPE_NODE)    return false;    if (ccd && CONTENT_LID(ccd->lid)) {    uint8_t logPage[EROS_PAGE_SIZE];    DiskNode* logPot = (DiskNode *) logPage;    if (ReadLogPage(ccd->lid, logPage) == false)      return false;    for (uint32_t i = 0; i < DISK_NODES_PER_PAGE; i++) {      if (logPot[i].oid == oid) {	memcpy(&logPot[i], &node, sizeof(DiskNode));	if (WriteLogPage(ccd->lid, logPage) == false)	  return false;	return true;      }    }    return false;  }    for (int div = 0; div < topDiv; div++) {    Division& d = divTable[div];        if (d.type == dt_Object && div_contains(&d, oid)) {      VolPagePot frameInfo;      ReadPagePotEntry(oid, frameInfo);      if (frameInfo.type != FRM_TYPE_NODE) {	Diag::debug(1, "Re-tagging frame for OID 0x%08x%08x to %d\n",		    (uint32_t) (oid >> 32),		    (uint32_t) (oid),		    FRM_TYPE_NODE);	OID frameOID = oid & ~(EROS_OBJECTS_PER_FRAME - 1u);	if ( ! FormatNodeFrame(div, frameOID) )	  Diag::fatal(5, "Unable to format node frame 0x%08x%08x\n",		      (uint32_t) (frameOID >> 32),		      (uint32_t) frameOID);	frameInfo.type = FRM_TYPE_NODE;	WritePagePotEntry(oid, frameInfo);      }      uint32_t offset = GetOidVolOffset(div, oid);      if ( !Write(offset, &node, sizeof(DiskNode)) )	Diag::fatal(5, "Volume write failed at offset %d.\n", offset);      return true;    }  }  if (rewriting == false)    return false;    /* If we get here, we didn't find what we wanted.  Allocate space   * for this node in the checkpoint log.   */  Diag::fatal(1, "Cannot write node with OID 0x%08x%08x -- no home location\n",	      (uint32_t)(oid>>32), (uint32_t)oid);  if ( !WriteNodeToLog(oid, node) )    Diag::fatal(5, "Volume write to log failed\n");  return true;}	boolVolume::FormatNodeFrame(int div, OID frameOID){  char buf[EROS_PAGE_SIZE];  bzero (buf, EROS_PAGE_SIZE);	  DiskNode *pdn = (DiskNode *) buf;	  for (int nd = 0; nd < EROS_NODES_PER_FRAME; nd++) {    pdn[nd].oid = frameOID + nd;    for (uint32_t slot = 0; slot < EROS_NODE_SIZE; slot++)      pdn[nd][slot] = VoidDiskKey();  }  uint32_t offset = GetOidVolOffset(div, frameOID);  return Write(offset, buf, EROS_PAGE_SIZE);}boolVolume::ContainsNode(const OID& oid){  CkptDirent* ccd = LookupObject(oid);  if (ccd && ccd->type == FRM_TYPE_NODE)    return true;    VolPagePot frameInfo;  if (ReadPagePotEntry(oid, frameInfo) == false)    return false;    if (frameInfo.type != FRM_TYPE_NODE)    return false;    return true;}boolVolume::ContainsPage(const OID& oid){  CkptDirent* ccd = LookupObject(oid);  if (ccd && (ccd->type == FRM_TYPE_DPAGE || ccd->type == FRM_TYPE_ZDPAGE))    return true;    VolPagePot frameInfo;  if (ReadPagePotEntry(oid, frameInfo) == false)    return false;    if (frameInfo.type != FRM_TYPE_DPAGE && frameInfo.type != FRM_TYPE_ZDPAGE)    return false;    return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -