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

📄 hd.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    DKS(node,ctrl,unit).errnoVal = 0;    DKS(node,ctrl,unit).done     = 1;  }#endif /* SIM_ALPHA || IRIX6_4 */    return;   case CMD_TST_UNIT_RDY:    /*     * XXX When does this return an error?     * XXX What errors does it return?     */    DKS(node,ctrl,unit).errnoVal = 0;    DKS(node,ctrl,unit).done     = 1;    return;      case CMD_MODE_SENSE:    /*     * Return that disk is not write protected and block size is 512 bytes     * WARNING: Watch this. I omitted the last section of the     * mode_sense_data data structure so that we could easily use     * this structure when running on other platforms. SAH     */    bzero((char *)&msd, sizeof(msd));    msd.wprot            = 0;    msd.bd_len = 8;    msd.block_descrip[5] = 0;    msd.block_descrip[6] = SectorSize >> 8;    msd.block_descrip[7] = 0;    /* this information needs to be DMA'ed to memory. Set up correct     * transfer size and place info in buffer.     */    DKS(node,ctrl,unit).isRead           = 1;    DKS(node,ctrl,unit).bytesTransferred = sizeof(struct mode_sense_data);    DKS(node,ctrl,unit).errnoVal         = 0;    DKS(node,ctrl,unit).sectorNum        = -1; /* signal this is sense */    bcopy((char *)&msd, DKS(node,ctrl,unit).c.dataBuffer,	  sizeof(struct mode_sense_data));    return;      case CMD_INQUIRY:    /*     * XXX When does this return an error?     * XXX What errors does it return?     */    DKS(node,ctrl,unit).errnoVal = 0;    if (DKS(node,ctrl,unit).pAddr[0]) {       /*	* XXX  This MIGHT now work on a cross-endian	* XXX simualtion	*/       ALL_INQ_DATA inq;       DKS(node,ctrl,unit).isRead           = 1;       DKS(node,ctrl,unit).bytesTransferred = sizeof(inq);       DKS(node,ctrl,unit).sectorNum        = -1; /* signal this is sense */       bzero((char*)&inq,sizeof(inq));       inq.dtype = 0; /* ALL_DTYPE_DIRECT */       if (rmtdiskfd) {           if (!strncmp(DKS_filename(node,ctrl,unit),"NOTDEF",strlen("NOTDEF"))) {             inq.pqual = 3;  /* ALL_PQUAL_NO_PHYS */          } else {             inq.pqual = 0; /* ALL_PQUAL_CONN */          }             } else {           if (access(DKS_filename(node,ctrl,unit),R_OK) !=0) {#if 0             CPUWarning("simos::hd,c: CMD_INQUIRY fails for %s\n",DKS_filename(node,ctrl,unit));#endif             inq.pqual = 3;  /* ALL_PQUAL_NO_PHYS */          } else {#if 0             CPUWarning("simos::hd,c: CMD_INQUIRY succeeds for %s\n",DKS_filename(node,ctrl,unit));#endif             inq.pqual = 0; /* ALL_PQUAL_CONN */          }       }       inq.dmodify = 0;       inq.rmb = 0;       inq.ansi = 0x2; /* ALL_SCSI2 */       inq.ecma = 0;       inq.iso = 0;       inq.rdf =0;       inq.trmiop = 0;       strcpy((char *)inq.vid,"simosVID");       strcpy((char *)inq.pid,"simosPID");              bcopy((char *)&inq, DKS(node,ctrl,unit).c.dataBuffer,	     sizeof(ALL_INQ_DATA));            /*	* actually need to transfer data	*/    } else {        DKS(node,ctrl,unit).done     = 1;    }    return;  default:     CPUError("hd.c: scsi command not supported (0x%x)\n",	      DKS(node,ctrl,unit).cmd[0]);    return;  }error:  DKS(node,ctrl,unit).errnoVal         = -1;  DKS(node,ctrl,unit).done             = 1;  DKS(node,ctrl,unit).bytesTransferred = 0;#undef UNSUPPORTED}/*************************************************************************** * * Modify map utilities * ***************************************************************************/intSimhdSetupModifyMap(int node, int ctrl, int unit){  SimhdSaveInfo *hd = &(DKS(node,ctrl,unit).hdcpt.simhdStats);  char nameBuf[256];  unsigned long size;    /* First time we are writing to the disk */  /* allocate bitmap of modified sectors, shadow file, etc. */  sprintf(nameBuf, "%s/.%s_XXXXXX",	  MemFileDir,	  DKS_diskname(node,ctrl,unit));  mktemp(nameBuf);  if((hd->sfd =  open(nameBuf, O_RDWR|O_CREAT|O_TRUNC , 0)) == -1) {    Sim_Warning("Could not open shadow file %s\n", nameBuf);    return -1;  }    unlink(nameBuf);    size = (unsigned long)     (hd->fileSize + (SIM_DISK_SHADOW_BLKSIZE-1)) & ~(SIM_DISK_SHADOW_BLKSIZE-1);  size = size/SectorSize/(8) + 1; /* 8 extra */  sprintf(nameBuf, "SHADOWMAP%d.%d.%d", node, ctrl, unit);  hd->modifyMap = (char *) ZMALLOC(hd->modifyMapSize, nameBuf);  size = (unsigned long)     (hd->fileSize/SIM_DISK_SHADOW_BLKSIZE + 1)*sizeof(int);   sprintf(nameBuf, "shadowOffset%d.%d.%d", node, ctrl, unit);  hd->shadowOffset = (int *) MALLOC(size, nameBuf);  if((hd->modifyMap == NULL) || (hd->shadowOffset == NULL)) {    Sim_Warning("Can't alloc. bitmap for shadow file\n");    return -1;  }    return 0;}/* * Given a disk number and a sector number, return a file * descriptor and an offset */intSimhdFindSector(int node, int ctrl, int unit,		int64 sectorNum, int *fd, unsigned long *offset, int isRead) {  SimhdSaveInfo *hd = &(DKS(node,ctrl,unit).hdcpt.simhdStats);  int remote = (rmtdiskfd >= 0);    ASSERT( sectorNum/8 < hd->modifyMapSize);  if (!isRead) {    if (hd->modifyMap == NULL) {      if (SimhdSetupModifyMap(node, ctrl, unit)) {	/* this is a fatal error */	ASSERT(0);	exit(-1);      }    }        /* Check if this sector has been previously modified */    if (!(hd->modifyMap[sectorNum/8] & (1 << (sectorNum % 8)))) {      /*        * check if the block is allocated on the shadow disk        * This code explicitly assumes that the block size is 8 times       * the sector size. If this is changed, we need a more complicated       * computation here.       */      if (!(hd->modifyMap[sectorNum/8])) {	/* 	 * Every 100 extend the file by a chunk	 * Reduces the number of times metadata has to be written 	 */	if (!(hd->nextWriteOffset%100)){	  int k;	  if ((k = lseek (hd->sfd, (hd->nextWriteOffset+100) *			                SIM_DISK_SHADOW_BLKSIZE, SEEK_SET)) 	      != (hd->nextWriteOffset+100)*SIM_DISK_SHADOW_BLKSIZE) {	    perror("lseek");	    Sim_Warning("Can't seek to offset %#x in shadow file (%d) "			"for %s return %d\n", 			(hd->nextWriteOffset+1000)*SIM_DISK_SHADOW_BLKSIZE,			hd->sfd, DKS_diskname(node,ctrl,unit), k);	    exit( -1);	  }	}	hd->shadowOffset[sectorNum*SectorSize/SIM_DISK_SHADOW_BLKSIZE] =           (int)(hd->nextWriteOffset++);#ifdef DEBUG_HD	Sim_Warning("Block %#x allocated offset %#x\n", 		    sectorNum*SectorSize/SIM_DISK_SHADOW_BLKSIZE,		    hd->nextWriteOffset-1);#endif      }      hd->modifyMap[sectorNum/8] |= (char) (1 << (sectorNum % 8));    }  }     if ((hd->modifyMap == NULL) ||      (!(hd->modifyMap[sectorNum/8] & (1 << (sectorNum % 8))))) {    *fd = hd->dfd;    *offset = sectorNum*SectorSize;  } else {    remote = 0;    *fd = hd->sfd;    *offset = hd->shadowOffset[sectorNum*SectorSize/SIM_DISK_SHADOW_BLKSIZE]*                SIM_DISK_SHADOW_BLKSIZE + (sectorNum % 8)*SectorSize;#ifdef DEBUG_HD    Sim_Warning("%s of %#x at offset %#x\n",		isRead?"Read":"Write", sectorNum, *offset);#endif  }  return remote;}/***************************************************************** * Given an encoded controller and unit, return the disk number. *****************************************************************/intSimhdGetDiskNum(int encoded_ctrl_unit){   int node = DECODE_NODE(encoded_ctrl_unit);   int ctrl = DECODE_CTRL(encoded_ctrl_unit);   int unit = DECODE_UNIT(encoded_ctrl_unit);   return DKS(node,ctrl,unit).dmodel_no;}/*************************************************************************** * * Ckeckpoint support * ***************************************************************************//* XXX Note: * XXX * The former hd.c only supported one controller / node. To maintain * backward compatibility with the old checkpoints, we now use the * following encoding when writing the *.diskdev file: * *   Accessed[<node>,<disk>] ... * * becomes * *   Accessed[<node>,<ctrldisk>] ... * * where <ctrldisk> has the disk number in the ls 16 bits and the * controller number in the following 16 bits. */#define ENCODE_CD(_CTRL,_DISK) ((((_CTRL) & 0xffff)<<16) | ((_DISK) & 0xffff))#define DECODE_C(_CD) (((_CD)>>16) & 0xffff)#define DECODE_D(_CD) (((_CD)>>0) & 0xffff)intDiskCheckpointCB(CptDescriptor *cptd){  int node, c, u;  int j;  bool modified;  uint diskAccessed = 0;  char *fnptr;  long val;  if (cptd->mode == CPT_SAVE) {    /*     * Check ownership     */    for (node = 0; node < nnode; node++) {      if (!dks[node]) continue;      for (c = 0; c < nctrl[node]; c++) {	if (!dks[node][c]) continue;       /* controller never used */	for (u = 0; u < nunit[node][c]; u++) {          if (!dks[node][c][u]) continue;  /* unit never used */          if( DKS(node,c,u).done != 0)	    CPUError("DiskCheckpointCB: disk I/O in progress, can't ckpt.\n");          diskAccessed |= DKS(node,c,u).hdcpt.accessed;	  /* DT: I think this check could be removed */          if (!DKS(node,c,u).isReady) { ASSERT(0); return -1; }	}      }    }  }  if (cptd->mode == CPT_RESTORE) {     DevFileDir = 0;  }  Simcpt_CptString(cptd, "DiskPath", NO_INDEX, NO_INDEX, &DevFileDir);     for (node = 0; node < nnode; node++) {    for (c = 0; c < nctrl[node]; c++) {      for (u = 0; u < nunit[node][c]; u++) {	/* Note: have to be careful to ensure backward compatibility */	int            cu = ENCODE_CD(c,u);	SimhdSaveInfo *hd;	if (dks[node] && dks[node][c] && dks[node][c][u]) {	  diskAccessed = DKS(node,c,u).hdcpt.accessed;	} else {	  diskAccessed = 0;	}                if (diskAccessed && (DKS(node,c,u).hdcpt.simhdStats.fileSize == 0)) {           diskAccessed = 0;        }	Simcpt_OptionalUint(cptd, "Accessed", node, cu, 0);	Simcpt_CptUint(cptd,      "Accessed", node, cu, &diskAccessed);	if (!diskAccessed) {	  /* This disk was never accessed OR	   * this is a compatibility case and we're restoring from	   * an old checkpoint.	   */  	  continue;	}		if (!(dks[node] && dks[node][c] && dks[node][c][u])) {	  ASSERT(cptd->mode == CPT_RESTORE);	  sim_disk_touch(node,c,u); /* alloc mem for disk data structures */	}		DKS(node,c,u).hdcpt.accessed = 1;	hd = &(DKS(node,c,u).hdcpt.simhdStats);	if( hd->writeable ) {	  Sim_Warning("Cannot take checkpoint with writable %s\n",		      DKS_diskname(node,c,u));	  return -1;	}		fnptr = hd->filename;	Simcpt_CptString(cptd, "Filename", node, cu, &fnptr);	ASSERT (strlen(hd->filename) < sizeof(hd->filename)-1);	val = (long)hd->fileSize;	Simcpt_CptLong(cptd,   "Filesize", node, cu, &val);	hd->fileSize = val;	Simcpt_CptLong(cptd,   "LastModified", node, cu, &(hd->modifyTime));	Simcpt_CptUint(cptd,   "ChecksumDone", node, cu, &(hd->doCheckSum));	if (hd->doCheckSum)	  Simcpt_CptInt(cptd,  "Checksum", node, cu, &(hd->checkSum));	else	  hd->checkSum = 0;		if (cptd->mode == CPT_RESTORE) {	  int ret = SimhdOpenCOWDisk(node,c,u,hd);	  if (ret != 0) return ret;	}		Simcpt_CptUint(cptd,   "Writeable", node, cu, &(hd->writeable));	Simcpt_CptInt(cptd,    "ModifyMapSize", node,cu, &(hd->modifyMapSize));	modified = (hd->modifyMap != NULL);	Simcpt_CptUint(cptd,   "Modified", node, cu, &(modified));		if (modified) {	  char *modMap, *origModMap;	  	  if (cptd->mode == CPT_RESTORE) {             long pageSize=getpagesize();	    modMap = (char *) ZMALLOC(hd->modifyMapSize+pageSize, "DiskCheckpointTemp");	    if(modMap == NULL) {	      Sim_Warning("Can't alloc. bitmap for shadow file\n");	      return -1;	    }	    origModMap = modMap;            modMap = (char *) (((VA)modMap +(PAGE_SIZE-1))&~(PAGE_SIZE-1));	  } else {	    modMap = hd->modifyMap;	  }	  	  Simcpt_CptBlock(cptd,"ModifyMap", node, cu,			  modMap, hd->modifyMapSize, -1);	  	  for (j = 0; j < hd->modifyMapSize; j++) {	    if (modMap[j] == 0) {	      continue;	    } else {	      int k;	      for (k = 0; k < 8; k++) {		if ((modMap[j] >> k) & 1) {		  int fd;		  unsigned long offset;		  char buf[SectorSize];		  int sectorNum = j * 8 + k;		  if (cptd->mode == CPT_RESTORE) {		    Simcpt_CptBlock(cptd, "ModifiedSector",				    /* DT this was: c*1000+u */				    c*1000000+node*1000+u,				    sectorNum, buf, SectorSize,-1);		    SimhdFindSector(node, c, u, sectorNum, &fd, &offset, 0);		    lseek (fd, offset, SEEK_SET);		    write (fd, buf, SectorSize);		  } else {		    SimhdFindSector(node, c, u, sectorNum, &fd, &offset, 1);		    lseek (fd, offset, SEEK_SET);		    read (fd, buf, SectorSize);		    Simcpt_CptBlock(cptd, "ModifiedSector",				    /* DT this was: c*1000+u */				    c*1000000+node*1000+u,				    sectorNum, buf, SectorSize,-1);		  }                		}	      }	    }	  }	  if (cptd->mode == CPT_RESTORE) {	    free(origModMap);	  }	}      }    }  }  return 0;}static long DetermineDeviceSize(int fd){   long    delta =  1024 * 1024 * 1024,size = 0;   char    buf[1];   if ( (size = (off_t)lseek(fd, 0 ,SEEK_END)) < 0 ) {	perror("Lseeking disk in simhd");	ASSERT(0);   }  if (size) return size;  size = 0;   while(delta) {      lseek(fd,(off_t)size + delta - sizeof(buf),SEEK_SET);      if (read(fd,buf,sizeof(buf)) > 0) {         size = lseek(fd,0,SEEK_CUR);      } else {          delta /= 2;      }   }   CPUWarning("SimHD: Use binsearch to determine size of disk to %lld MB \n",              size / 1024 / 1024);   return size;}

⌨️ 快捷键说明

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