Пример #1
0
/*
  This function will recover the disk and then attempt to put any recovered data on that
  recovered disk
  @param int disk - disk to recover 
  @return void 
*/
void recoverDisk(int disk){
    // If RAID 0 do nothing besides calling the recover function
    disk_array_recover_disk(diskArray, disk);
    //Level 10
    if (level == 10){
     int diskToCopyFrom;
     
     // To determine if recovered disk is first or second in a pair of mirrored disks
     if (disk % 2){
      diskToCopyFrom = disk - 1; 
     } else{
      diskToCopyFrom = disk + 1; 
     }
     int i;
     for (i = 0; i < blockSize; i++){
      char buffer[BLOCK_SIZE];
      disk_array_read(diskArray, diskToCopyFrom, i, buffer);
      disk_array_write(diskArray, disk, i, buffer);
     }
  }
  
  //Level 4 or 5 do the same attempts at recovery
  else if (level == 4  || level == 5){
    int i;
    char missingData [BLOCK_SIZE];
    for (i = 0; i < blockSize; i++){
      if(calculateXOR(disk,i, missingData) == -1){
	return;
      }
      disk_array_write(diskArray, disk, i, missingData);
    }
  }
}
Пример #2
0
/**
 * This function handles striping across the disks
 */
static int stripper(int size, int lba, char* value, short isWrite) {
  int rc = 0;
  short startFound = 0;
  int diskIndex  = 0;
  int blockIndex = 0; //index of block within disk
  int i;
  short write_error = 0;
  //loop until address reached
  for(i = 0; i < size + lba; i++){
    if(i == lba){
      startFound = 1;
    }
    //if address reached perform read or write
    if(startFound == 1){
      if(isWrite == 1){
        //has the disk failed?
        if(disk_active[diskIndex] == 0) {
          write_error = 1;
        }
		    disk_array_write(_da, diskIndex, blockIndex, value);
      }
      //Read operation
      else {
		    disk_array_read(_da, diskIndex, blockIndex, buffer);
		    //if bad disk print error message
        if(!disk_active[diskIndex]) {
          printf("ERROR ");
        }
        else {
	        printf("%d ", *((int*)buffer)); //print output from read
        }
      }
    } //end if start found
    
    //if reached end of strip change disk
	  if(++blockIndex % _strip == 0) {
	    diskIndex += 1;
	    if(diskIndex % _disk == 0) {
		    diskIndex = 0;
	    }
	    else {
		    blockIndex -= _strip;
	    }
	  }
	
  } //end size+lba for loop
  diskIndex = diskIndex % _disk;
  //inform user of write error
  if(write_error){
    printf("ERROR ");
    write_error = 0;
  }
  
  return rc;
}
Пример #3
0
/*
  This function will write to the disk array starting at lba, for size, and will write 
  the pattern in the buff passed into the block
  @param int lba - logical block address
  @param int size - size of the write
  @param char *buff - buffer to write to each block of the disk array
  @return void 
*/ 
void writeToArray(int lba, int size, char * buff){
  //Level 0 
  if (level == 0) {
    int currentDisk, currentBlock;
    getPhysicalBlock(disks, lba, &currentDisk, &currentBlock);
    
    //successfulWrite should be 0 after all writing is complete, otherwise print error
    //Only want to print error once
    int successfulWrite = 0;
    while (size > 0) {
      successfulWrite += disk_array_write(diskArray, currentDisk, currentBlock, buff);
      lba ++;
      getPhysicalBlock(disks, lba, &currentDisk, &currentBlock);
      size --;
    }
    if (successfulWrite != 0) {
      fprintf(stdout, "ERROR "); 
    }
  }
  
  //Level 10
  else if(level == 10){
    int currentDisk, currentBlock;
    getPhysicalBlock(disks, lba, &currentDisk, &currentBlock);
    currentDisk *= 2;
    
    //successfulWrite should be 0 after all writing is complete 
    // Only want to print error once
    int successfulWrite = 0;
    
    while (size > 0) {
      // Status keeps track of if write to disk succeded
      // If we fail both, status will equal -2
      int status = disk_array_write(diskArray, currentDisk, currentBlock, buff);
      status += disk_array_write(diskArray, currentDisk + 1, currentBlock, buff);
      if (status == -2){
	successfulWrite = -1;
      }
      lba ++;
      getPhysicalBlock(disks, lba, &currentDisk, &currentBlock);
      currentDisk *= 2;
      size--;
    }
    if (successfulWrite != 0) {
      fprintf(stdout, "ERROR "); 
    }
  }
  
  //Level 4
  else if(level == 4){
    	// successfulWrite should be 0 after all writing is complete
    	// Only want to print error once
    	int successfulWrite = 0;
    	int currentDisk, currentBlock;
    	int stripeLength =(disks - 1)*strip;
    	int i, j, k;

	char temp[BLOCK_SIZE];
	char parityChange[BLOCK_SIZE];

	while (size > 0) {
		int whereInStripe = lba % stripeLength;
		int startOfThisStripe = lba - whereInStripe;
		int blockOffsetOfThisStripe = (startOfThisStripe)/(disks-1);
		int coverTo = whereInStripe + size;
		int tempNum;

		for(i = 0; i < strip; i ++){
			for (j = 0; j < BLOCK_SIZE; j++) {
     				parityChange[j] = 0;
			}
			tempNum = i;
			//printf("i: %i\n", i);
			currentBlock = i + blockOffsetOfThisStripe;
			while(tempNum < stripeLength){
			//printf("temp: %i\n", tempNum);
				currentDisk = tempNum / strip;
				if(tempNum >= whereInStripe && tempNum < coverTo){					
					if (disk_array_write(diskArray, currentDisk, currentBlock, buff)){
						successfulWrite --; //write failed
					}
					for (k = 0; k < BLOCK_SIZE; k++) {
						parityChange[k] = parityChange[k] ^ buff[k];
					}
				}
				else{
					if (disk_array_read(diskArray, currentDisk, currentBlock, temp) != 0) {
					//error reading old data, which means we cannot update parity for this block
					}
					else{
						for (k = 0; k < BLOCK_SIZE; k++) {
							parityChange[k] = parityChange[k] ^ temp[k];
						}
					}
				}
				tempNum += strip;
			}
			disk_array_write(diskArray, disks-1, currentBlock, parityChange);
			//printf("parity %i is %i\n", i, *((int*)parityChange));
		}
		int next = startOfThisStripe + stripeLength;
		size -= next - lba;
		lba = next;
	}
    	if (successfulWrite != 0) {
      		fprintf(stdout, "ERROR "); 
    	}
  }
  
  //Level 5
  else if(level == 5){
    // successfulWrite should be 0 after all writing is complete
    	// Only want to print error once
    	int successfulWrite = 0;
    	int currentDisk, currentBlock;
    	int stripeLength =(disks - 1)*strip;
    	int i, j, k;
	int currentParityDisk;

	char temp[BLOCK_SIZE];
	char parityChange[BLOCK_SIZE];

	while (size > 0) {
		int whereInStripe = lba % stripeLength;
		int startOfThisStripe = lba - whereInStripe;
		int blockOffsetOfThisStripe = (startOfThisStripe)/(disks-1);
		int coverTo = whereInStripe + size;
		int tempNum;

		for(i = 0; i < strip; i ++){
			for (j = 0; j < BLOCK_SIZE; j++) {
     				parityChange[j] = 0;
			}
			tempNum = i;
			//printf("i: %i\n", i);
			currentBlock = i + blockOffsetOfThisStripe;
			currentParityDisk = (currentBlock/strip) % disks;
			while(tempNum < stripeLength){
			//printf("temp: %i\n", tempNum);
				currentDisk = tempNum / strip;
				if (currentDisk >= currentParityDisk) {
				  currentDisk ++;
				}
				
				if(tempNum >= whereInStripe && tempNum < coverTo){					
					if (disk_array_write(diskArray, currentDisk, currentBlock, buff)){
						successfulWrite --; //write failed
					}
					for (k = 0; k < BLOCK_SIZE; k++) {
						parityChange[k] = parityChange[k] ^ buff[k];
					}
				}
				else{
					if (disk_array_read(diskArray, currentDisk, currentBlock, temp) != 0) {
					//error reading old data, which means we cannot update parity for this block
					}
					else{
						for (k = 0; k < BLOCK_SIZE; k++) {
							parityChange[k] = parityChange[k] ^ temp[k];
						}
					}
				}
				tempNum += strip;
			}
			disk_array_write(diskArray, currentParityDisk, currentBlock, parityChange);
			//printf("parity %i is %i\n", i, *((int*)parityChange));
		}
		int next = startOfThisStripe + stripeLength;
		size -= next - lba;
		lba = next;
	}
    	if (successfulWrite != 0) {
      		fprintf(stdout, "ERROR "); 
    	}
  }
  
  //Error
  else{
    errorMsgParse();
  }
}