// normalize the column by the pivot value void normalize_pivot_col(uint8_t *matrix, uint8_t *result, int col, int size) { int row; uint8_t pivotValue; pivotValue = matrix[ IDC2D(col, col, size) ]; for(row=0; row<size; row++) { matrix[ IDC2D(row, col, size)] = gf_div(matrix[ IDC2D(row, col, size) ], pivotValue); result[ IDC2D(row, col, size)] = gf_div(result[ IDC2D(row, col, size) ], pivotValue); } }
// normalize the row by the pivot value void normalize_pivot_row(uint8_t *matrix, uint8_t *result, int row, int size) { int col; uint8_t pivotValue; pivotValue = matrix[ IDC2D(row, row, size) ]; for(col=0; col<size; col++) { matrix[ IDC2D(row, col, size)] = gf_div(matrix[ IDC2D(row, col, size) ], pivotValue); result[ IDC2D(row, col, size)] = gf_div(result[ IDC2D(row, col, size) ], pivotValue); } }
int cgc_rs_decode(uint8_t *encoded, int n_parity) { poly_t tmp, synd, sigma, pos; cgc_memcpy(tmp.terms, encoded, 255); tmp.degree = 255; rs_calc_synd(&synd, &tmp, n_parity); // synd.degree must equal n_parity, e.g. don't eliminate zero terms rs_calc_sigma(&sigma, &synd); rs_calc_pos(&pos, &sigma); rs_calc_omega(&tmp, &synd, &sigma); rs_calc_sigma_deriv(&sigma); for (int i = 0; i < pos.degree; i++) { uint8_t x_inv = gf_inverse(gf_exp[(255 - 1 - pos.terms[i]) % 255]); uint8_t mag = gf_div(gf_poly_eval(&tmp, x_inv), gf_mul(x_inv, gf_poly_eval(&sigma, x_inv))); encoded[255 - 1 - pos.terms[i]] ^= mag; } // test result for errors cgc_memcpy(tmp.terms, encoded, 255); tmp.degree = 255; rs_calc_synd(&synd, &tmp, n_parity); gf_poly_reduce(&synd); // if no errors, then we succesfully decoded return synd.degree == 0; }
poly_t * poly_syndrome_init(poly_t generator, gf_t *support, int n) { int i,j,t; gf_t a; poly_t * F; F = malloc(n * sizeof (poly_t)); t = poly_deg(generator); //g(z)=g_t+g_(t-1).z^(t-1)+......+g_1.z+g_0 //f(z)=f_(t-1).z^(t-1)+......+f_1.z+f_0 for(j=0; j<n; j++) { F[j] = poly_alloc(t-1); poly_set_coeff(F[j],t-1,gf_unit()); for(i=t-2; i>=0; i--) { poly_set_coeff(F[j],i,gf_add(poly_coeff(generator,i+1), gf_mul(support[j],poly_coeff(F[j],i+1)))); } a = gf_add(poly_coeff(generator,0),gf_mul(support[j],poly_coeff(F[j],0))); for(i=0; i<t; i++) { poly_set_coeff(F[j],i, gf_div(poly_coeff(F[j],i),a)); } } return F; }
// p = p * x mod g // p de degré <= deg(g)-1 void poly_shiftmod(poly_t p, poly_t g) { int i, t; gf_t a; t = poly_deg(g); a = gf_div(p->coeff[t-1], g->coeff[t]); for (i = t - 1; i > 0; --i) p->coeff[i] = gf_add(p->coeff[i - 1], gf_mul(a, g->coeff[i])); p->coeff[0] = gf_mul(a, g->coeff[0]); }
void test_division_inverse() { suite("division has nonequal inverse"); ALL1( switch ( a ) { case 0: case 1: break; default: test(gf_div(1,a) != a); } ) }
// Main int main(int argc, char **argv) { // Variables int i; struct timeval start, end; // Change # of repeats according to the processing bits int repeat = REPEAT / 1; // 8bits //int repeat = REPEAT / 2; // 16bits //int repeat = REPEAT / 4; // 32bits //int repeat = REPEAT / 8; // 64bits uint8_t a, b; // Change type of these according to the processing bits //uint16_t a, b; // 16bits //uint32_t a, b; // 32bits //uint64_t a, b; // 64bits // Initialize GF //GFinit(); // Some libraries need initialization // Start measuring elapsed time gettimeofday(&start, NULL); // Get start time // Repeat mul and div in GF for (i = 0; i < repeat; i++) { // Note change these according to the bits, // random() must be 64bits a = (uint8_t)(random() & 0xff); b = (uint8_t)(random() & 0xff); // a = (uint16_t)(random() & 0xffff); // In case of 16bits // Calculate in GF gf_mul(a, b); // You may need to change this function according to the bits like GF8mul(), GF64mul() gf_div(a, b); } // Get end time gettimeofday(&end, NULL); // Print result printf("%ld\n", ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec))); }
//test raid6 algorithm int main(int argc, char *argv[]) { char disk_data[DISKNUM][BLOCKSIZE]; char read_data[DISKNUM-2][BLOCKSIZE]; int disk_id; char temp_char; int i, j; int code_disk_id, parity_disk_id; int data_disk_coeff; int disk_failed_no = DISK_FAILED_NUM; int disk_first_id = FIRST_FAIL_ID; int disk_second_id = SECOND_FAIL_ID; int disk_another_failed_id; int g1, g2, g12; char P_temp[BLOCKSIZE], Q_temp[BLOCKSIZE]; gen_tables(8); printf("\nPrint gflog(x)\n"); for (i=0; i<256; i++){ printf("%d(%d) ",i,gflog[i]); } printf("\n"); printf("\nPrint gfilog(x)\n"); for (i=0; i<256; i++){ printf("%d(%d) ",i,gfilog[i]); } printf("\n"); for (i=0; i<DISKNUM; i++){ if (i < DISKNUM-2){ temp_char = TEST_DATA_BEGIN + i; } else{ temp_char = 0; } for (j=0; j<BLOCKSIZE; j++){ disk_data[i][j] = temp_char; } } printf("\n****** PRINT DISK DATA ******\n"); for (i=0; i<DISKNUM; i++){ printf("Disk id: %d\n",i); for (j=0; j<BLOCKSIZE; j++){ printf("%c(%d) ",disk_data[i][j],disk_data[i][j]); } printf("\n"); } //write P and Q code_disk_id = DISKNUM -1; parity_disk_id = DISKNUM - 2; for (i=0; i<DISKNUM; i++){ if ( (i != parity_disk_id) && (i != code_disk_id) ){ for (j=0; j<BLOCKSIZE; j++){ //calculate P disk_data[parity_disk_id][j] = disk_data[parity_disk_id][j] ^ disk_data[i][j]; //calculate the coefficient of the data block data_disk_coeff = i; if (i > code_disk_id){ (data_disk_coeff)--; } if (i > parity_disk_id){ (data_disk_coeff)--; } data_disk_coeff = DISKNUM - 3 - data_disk_coeff; data_disk_coeff = get_coefficient(data_disk_coeff); printf("\ndata disk coefficient = %d\n",data_disk_coeff); //calculate Q temp_char = disk_data[code_disk_id][j]; disk_data[code_disk_id][j] = temp_char ^ (char)gf_mul((unsigned char)disk_data[i][j],data_disk_coeff,FIELDSIZE); printf(" newQ=%c(%d) \n",disk_data[code_disk_id][j], (unsigned int)disk_data[code_disk_id][j]); } } } printf("\n****** PRINT DISK DATA ******\n"); for (i=0; i<DISKNUM; i++){ printf("Disk id: %d\n",i); for (j=0; j<BLOCKSIZE; j++){ printf("%c(%d) ",disk_data[i][j],disk_data[i][j]); } printf("\n"); } //read data for (i=0; i<DISKNUM-2; i++){ for (j=0; j<BLOCKSIZE; j++){ read_data[i][j] = 0; } } for (disk_id=0; disk_id<DISKNUM-2; disk_id++){ disk_another_failed_id = disk_second_id; if (disk_id == disk_first_id){ disk_another_failed_id = disk_second_id; } else if (disk_id == disk_second_id){ disk_another_failed_id = disk_first_id; } printf("\nDisk ID: %d, another failed disk ID: %d\n",disk_id, disk_another_failed_id); //case of the disk is not failed if ( (disk_failed_no == 0) || ((disk_id != disk_first_id) && (disk_id != disk_second_id)) ){ printf("NO DISK FAIL\n"); for (j=0; j<BLOCKSIZE; j++){ read_data[disk_id][j] = disk_data[disk_id][j]; } } //cases of single disk fail else if ( (disk_failed_no == 1) || ((disk_failed_no == 2) && (disk_another_failed_id == code_disk_id)) ){ printf("One disk fail, or 1 data plus Q disk fail\n"); for (i = 0; i < DISKNUM; i++){ if ( (i != disk_id) && (i != code_disk_id) ){ for (j=0; j<BLOCKSIZE; j++){ read_data[disk_id][j] = read_data[disk_id][j] ^ disk_data[i][j]; } } } } else if (disk_failed_no == 2){ if (disk_another_failed_id == parity_disk_id){ printf("1 data plus P disk fail\n"); //calculate Q' for (i=0; i<DISKNUM; i++){ if ( ((i != disk_first_id) && (i != disk_second_id)) && (i != parity_disk_id) && (i != code_disk_id) ){ for (j=0; j < BLOCKSIZE; j++){ //calculate the coefficient of the data block data_disk_coeff = i; if (i > code_disk_id){ (data_disk_coeff)--; } if (i > parity_disk_id){ (data_disk_coeff)--; } data_disk_coeff = DISKNUM - 3 - data_disk_coeff; data_disk_coeff = get_coefficient(data_disk_coeff); printf("\ndata disk coefficient = %d\n",data_disk_coeff); temp_char = read_data[disk_id][j]; read_data[disk_id][j] = read_data[disk_id][j] ^ (char)gf_mul((unsigned char)disk_data[i][j],data_disk_coeff,FIELDSIZE); } } for (j=0; j<BLOCKSIZE; j++){ printf("Q'=%c(%d) ",read_data[disk_id][j],read_data[disk_id][j]); } } //calculate Q xor Q' for (j=0; j < BLOCKSIZE; j++){ read_data[disk_id][j] = read_data[disk_id][j] ^ disk_data[code_disk_id][j]; } for (j=0; j<BLOCKSIZE; j++){ printf("Q'+Q=%c(%d) ",read_data[disk_id][j],read_data[disk_id][j]); } //calculate the coefficient of the data block data_disk_coeff = disk_id; if (disk_id > code_disk_id){ (data_disk_coeff)--; } if (disk_id > parity_disk_id){ (data_disk_coeff)--; } data_disk_coeff = DISKNUM - 3 - data_disk_coeff; data_disk_coeff = get_coefficient(data_disk_coeff); printf("\ndata disk coefficient = %d\n",data_disk_coeff); //decode the origianl data block for (j=0; j < BLOCKSIZE; j++){ temp_char = read_data[disk_id][j]; read_data[disk_id][j] = (char)gf_div((unsigned char)temp_char,data_disk_coeff,FIELDSIZE); } } else{ //case of two data disk fail printf("2 data disk fail\n"); //calculate g1 g1 = disk_id; if (g1 > code_disk_id){ (g1)--; } if (g1 > parity_disk_id){ (g1)--; } g1 = DISKNUM - 3 - g1; g1 = get_coefficient(g1); printf("g1=%d \n",g1); //calculate g2 g2 = disk_another_failed_id; if (g2 > code_disk_id){ (g2)--; } if (g2 > parity_disk_id){ (g2)--; } g2 = DISKNUM - 3 - g2; g2 = get_coefficient(g2); printf("g2=%d \n",g2); //calculate g12 g12 = g1 ^ g2; //calculate P' for (j=0; j<BLOCKSIZE; j++){ P_temp[j] = 0; } for (i=0; i<DISKNUM; i++){ if ( (i != disk_first_id) && (i != disk_second_id) && (i != parity_disk_id) && (i != code_disk_id) ) { for (j=0; j<BLOCKSIZE; j++){ P_temp[j] = P_temp[j] ^ disk_data[i][j]; } } } for (j=0; j<BLOCKSIZE; j++){ P_temp[j] = P_temp[j] ^ disk_data[parity_disk_id][j]; //P_temp = P' xor P } //calculate Q' for (j=0; j<BLOCKSIZE; j++){ Q_temp[j] = 0; } for (i=0; i<DISKNUM; i++){ if ( ((i != disk_first_id) && (i != disk_second_id)) && (i != parity_disk_id) && (i != code_disk_id) ){ //calculate the coefficient of the data block data_disk_coeff = i; if (i > code_disk_id){ (data_disk_coeff)--; } if (i > parity_disk_id){ (data_disk_coeff)--; } data_disk_coeff = DISKNUM - 3 - data_disk_coeff; data_disk_coeff = get_coefficient(data_disk_coeff); printf("\ndata disk coefficient = %d\n",data_disk_coeff); for (j=0; j < BLOCKSIZE; j++){ temp_char = Q_temp[j]; Q_temp[j] = temp_char ^ (char)gf_mul((unsigned char)disk_data[i][j],data_disk_coeff,FIELDSIZE); } } for (j=0; j<BLOCKSIZE; j++){ printf("Q'=%c(%d) ",Q_temp[j],Q_temp[j]); } } //calculate D for (j=0; j<BLOCKSIZE; j++){ temp_char = (char)(gf_mul(g2,(unsigned char)P_temp[j],FIELDSIZE) ^ Q_temp[j] ^ disk_data[code_disk_id][j]); read_data[disk_id][j] = (char)gf_div((unsigned char)temp_char, g12, FIELDSIZE); } } } } //print data read printf("\n****** PRINT READ DATA ******\n"); for (i=0; i<DISKNUM-2; i++){ printf("Read disk id: %d\n",i); for (j=0; j<BLOCKSIZE; j++){ printf("%c(%d) ",read_data[i][j],read_data[i][j]); } printf("\n"); } return 0; }
// On suppose deg(g) >= deg(p) void poly_eeaux(poly_t * u, poly_t * v, poly_t p, poly_t g, int t) { int i, j, dr, du, delta; gf_t a; poly_t aux, r0, r1, u0, u1; // initialisation des variables locales // r0 <- g, r1 <- p, u0 <- 0, u1 <- 1 dr = poly_deg(g); r0 = poly_alloc(dr); r1 = poly_alloc(dr - 1); u0 = poly_alloc(dr - 1); u1 = poly_alloc(dr - 1); poly_set(r0, g); poly_set(r1, p); poly_set_to_zero(u0); poly_set_to_zero(u1); poly_set_coeff(u1, 0, gf_unit()); poly_set_deg(u1, 0); // invariants: // r1 = u1 * p + v1 * g // r0 = u0 * p + v0 * g // et deg(u1) = deg(g) - deg(r0) // on s'arrête lorsque deg(r1) < t (et deg(r0) >= t) // et donc deg(u1) = deg(g) - deg(r0) < deg(g) - t du = 0; dr = poly_deg(r1); delta = poly_deg(r0) - dr; while (dr >= t) { for (j = delta; j >= 0; --j) { a = gf_div(poly_coeff(r0, dr + j), poly_coeff(r1, dr)); if (a != gf_zero()) { // u0(z) <- u0(z) + a * u1(z) * z^j for (i = 0; i <= du; ++i) { poly_addto_coeff(u0, i + j, gf_mul_fast(a, poly_coeff(u1, i))); } // r0(z) <- r0(z) + a * r1(z) * z^j for (i = 0; i <= dr; ++i) poly_addto_coeff(r0, i + j, gf_mul_fast(a, poly_coeff(r1, i))); } } // échanges aux = r0; r0 = r1; r1 = aux; aux = u0; u0 = u1; u1 = aux; du = du + delta; delta = 1; while (poly_coeff(r1, dr - delta) == gf_zero()) delta++; dr -= delta; } poly_set_deg(u1, du); poly_set_deg(r1, dr); //return u1 and r1; *u=u1; *v=r1; poly_free(r0); poly_free(u0); }
//test msr algorithm int main(int argc, char *argv[]) { char write_data[MSR_M * MSR_SEGMENT_NUM][BLOCKSIZE]; char disk_data[DISKNUM][MSR_SEGMENT_SIZE * MSR_SEGMENT_NUM][BLOCKSIZE]; char read_data[MSR_M * MSR_SEGMENT_NUM][BLOCKSIZE]; char temp_buf[BLOCKSIZE]; int i, j, k, p; int temp; char temp_char; int msr_segment_id; int msr_block_id; int disk_id, block_no; int code_disk_id, code_block_no; int temp_msr_block_id, temp_disk_id, temp_block_no; char encoded_data; int coefficient; int decode_block_id, decode_disk_id, decode_block_no; int disk_failed_num = DISK_FAILED_NUM; int disk_first_id = FIRST_FAIL_ID; int disk_second_id = SECOND_FAIL_ID; int disk_another_failed_id; //Generate GF table gen_tables(8); //Generate coding matrix msr_gen_coding_matrix(MSR_N, MSR_K, MSR_M, MSR_C); //Print the coding matrix printf("\nCoding matrix\n"); for (i=0; i<MSR_C; i++){ printf("M'%d = ",i); for (j=0; j<MSR_M; j++){ temp = msr_coding_matrix[i][j]; if (temp != 0){ if (temp == 1){ printf("M%d + ",j); } else{ printf("%dM%d + ",temp,j); } } } printf("\n"); } printf("\n"); //Generate write buffer for (i=0; i<MSR_M * MSR_SEGMENT_NUM; i++){ temp_char = TEST_DATA_BEGIN + i; for (j=0; j<BLOCKSIZE; j++){ write_data[i][j] = temp_char; } } //PRINT Write Buffer printf("\n******PRINT Write Buffer******\n"); for (i=0; i <MSR_M * MSR_SEGMENT_NUM; i++){ printf("%d Data block: ",i); for (j=0; j<BLOCKSIZE; j++){ printf("%c(%d) ",write_data[i][j],write_data[i][j]); } printf("\n"); } //Nullify disk data for (i=0; i <DISKNUM; i++){ for (j=0; j<MSR_SEGMENT_SIZE * MSR_SEGMENT_NUM; j++){ for (k=0; k<BLOCKSIZE; k++){ disk_data[i][j][k] = 0; } } } //Write data to disk printf("\n******Writing data to disk******\n"); for (i=0; i<MSR_M * MSR_SEGMENT_NUM; i++){ //find data block location msr_segment_id = (int)(i / MSR_M); //find msr_segment_id; msr_block_id = i % MSR_M; disk_id = msr_get_disk_id(msr_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); block_no = msr_get_block_no(msr_block_id, MSR_SEGMENT_SIZE); block_no = block_no + msr_segment_id * MSR_SEGMENT_SIZE; printf("M%d disk_id=%d block_no=%d\n",msr_block_id,disk_id,block_no); //write data block for (k=0; k<BLOCKSIZE; k++){ disk_data[disk_id][block_no][k] = write_data[msr_block_id + msr_segment_id * MSR_M][k]; } //find coded block location for (p=0; p<MSR_C; p++){ if (msr_coding_matrix[p][msr_block_id] != 0){ code_disk_id = msr_get_code_disk_id(p, MSR_SEGMENT_SIZE, MSR_N, MSR_K); code_block_no = msr_get_code_block_no(p, MSR_SEGMENT_SIZE); code_block_no = code_block_no + msr_segment_id * MSR_SEGMENT_SIZE; //generate encoded data for (k=0; k<BLOCKSIZE; k++){ temp_buf[k] = 0; } for (j=0; j<MSR_M; j++){ coefficient = msr_coding_matrix[p][j]; if (coefficient != 0){ temp_msr_block_id = j; temp_disk_id = msr_get_disk_id(temp_msr_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); temp_block_no = msr_get_block_no(temp_msr_block_id, MSR_SEGMENT_SIZE); temp_block_no = temp_block_no + msr_segment_id * MSR_SEGMENT_SIZE; for (k=0; k<BLOCKSIZE; k++){ temp_char = disk_data[temp_disk_id][temp_block_no][k]; encoded_data = (char)gf_mul((unsigned char)coefficient, (unsigned char)temp_char, FIELDSIZE); temp_buf[k] = temp_buf[k] ^ encoded_data; } } } //write coded block for (k=0; k<BLOCKSIZE; k++){ disk_data[code_disk_id][code_block_no][k] = temp_buf[k]; } } } } //PRINT Disk Data printf("\n******PRINT Disk Data******\n"); for (i=0; i <DISKNUM; i++){ printf("###Disk id: %d\n",i); for (j=0; j<MSR_SEGMENT_SIZE * MSR_SEGMENT_NUM; j++){ msr_block_id = msr_find_block_id(i,j,MSR_SEGMENT_SIZE,MSR_N,MSR_K); if (msr_block_id == -1){ msr_block_id = msr_find_code_block_id(i,j,MSR_SEGMENT_SIZE,MSR_N,MSR_K); msr_block_id = msr_block_id + 100; } printf("##Relative block number: %d. MSR ID: {%d}, Data: ",j,msr_block_id); for (k=0; k<BLOCKSIZE; k++){ printf("%c(%d) ",disk_data[i][j][k],disk_data[i][j][k]); } printf("\n"); } printf("\n"); } //Read data from disk to read buffer for (i=0; i<MSR_M * MSR_SEGMENT_NUM; i++){ msr_block_id = i % MSR_M; msr_segment_id = i / MSR_M; disk_id = msr_get_disk_id(msr_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); block_no = msr_get_block_no(msr_block_id, MSR_SEGMENT_SIZE); block_no = block_no + msr_segment_id * MSR_SEGMENT_SIZE; disk_another_failed_id = disk_second_id; if (disk_id == disk_first_id){ disk_another_failed_id = disk_second_id; } else if (disk_id == disk_second_id){ disk_another_failed_id = disk_first_id; } disk_another_failed_id = disk_second_id; if (disk_id == disk_first_id){ disk_another_failed_id = disk_second_id; } else if (disk_id == disk_second_id){ disk_another_failed_id = disk_first_id; } if ((disk_id != FIRST_FAIL_ID) && (disk_id != SECOND_FAIL_ID)){ //Case of no disk failure printf("\nBlock is accessible\n"); for (k=0; k<BLOCKSIZE; k++){ read_data[i][k] = disk_data[disk_id][block_no][k]; } } else{ //Cases of disk failure //Find the single coded block for handling one-node failure decode_block_id = msr_find_single_decode_block_id(msr_block_id, MSR_SEGMENT_SIZE); decode_disk_id = msr_get_code_disk_id(decode_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); decode_block_no = msr_get_code_block_no(decode_block_id, MSR_SEGMENT_SIZE); decode_block_no = decode_block_no + msr_segment_id * MSR_SEGMENT_SIZE; if ( (disk_failed_num == 1) || ((disk_failed_num == 2) && (disk_another_failed_id >= (int)(MSR_N/2)) && (disk_another_failed_id != decode_disk_id)) ){ //Case of single disk failure printf("\nSingle disk failure. msr_block_id: %d. disk_id: %d. block_no: %d\n", msr_block_id, disk_id, block_no); for (k=0; k<BLOCKSIZE; k++){ temp_buf[k] = disk_data[decode_disk_id][decode_block_no][k]; } //Calculate the requested data for (j=0; j<MSR_M; j++){ coefficient = msr_coding_matrix[decode_block_id][j]; if ((j != msr_block_id) && (coefficient != 0)){ temp_disk_id = msr_get_disk_id(j, MSR_SEGMENT_SIZE, MSR_N, MSR_K); temp_block_no = msr_get_block_no(j, MSR_SEGMENT_SIZE); temp_block_no = temp_block_no + msr_segment_id * MSR_SEGMENT_SIZE; for (k=0; k<BLOCKSIZE; k++){ temp_char = (char)gf_mul((unsigned char)coefficient, (unsigned char)disk_data[temp_disk_id][temp_block_no][k], FIELDSIZE); temp_buf[k] = temp_buf[k] ^ temp_char; } } } for (k=0; k<BLOCKSIZE; k++){ read_data[i][k] = (char)gf_div((unsigned char)temp_buf[k], (unsigned char)msr_coding_matrix[decode_block_id][msr_block_id], FIELDSIZE); } } else if ((disk_failed_num == 2) && (disk_another_failed_id == decode_disk_id)){ printf("\nTwo-disk failure (D + primary parity). msr_block_id: %d. disk_id: %d. block_no: %d\n", msr_block_id, disk_id, block_no); //generate block status array int block_status[MSR_M]; //0 for healthy; 1 for failed int code_block_status[MSR_C]; int sec_code_block_id, sec_code_disk_id, sec_code_block_no; int sec_code_block_coeff[MSR_M]; char sec_code_block_value[BLOCKSIZE]; int temp_block_coeff[MSR_M]; char temp_block_value[BLOCKSIZE]; int count_failed_blocks; int temp_coeff1, temp_coeff2; for (j=0; j<MSR_M; j++){ temp_disk_id = msr_get_disk_id(j, MSR_SEGMENT_SIZE, MSR_N, MSR_K); if ((temp_disk_id == disk_id) || (temp_disk_id == disk_another_failed_id)){ block_status[j] = 1; } else{ block_status[j] = 0; } } for (j=0; j<MSR_C; j++){ temp_disk_id = msr_get_code_disk_id(j, MSR_SEGMENT_SIZE, MSR_N, MSR_K); if ((temp_disk_id == disk_id) || (temp_disk_id == disk_another_failed_id)){ code_block_status[j] = 1; } else{ code_block_status[j] = 0; } } //get secondary decode block sec_code_block_id = 0; for (j=0; j<MSR_C; j++){ count_failed_blocks = MSR_M; //find code block having target block and fewest failed blocks if ((code_block_status[j] == 0) && (msr_coding_matrix[j][msr_block_id] != 0)){ temp = 0; for (k=0; k<MSR_M; k++){ if ((k != msr_block_id) && (msr_coding_matrix[j][k] != 0) && (block_status[k] == 1)){ temp++; } } if (temp < count_failed_blocks){ sec_code_block_id = j; count_failed_blocks = temp; } } } sec_code_disk_id = msr_get_code_disk_id(sec_code_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); sec_code_block_no = msr_get_code_block_no(sec_code_block_id, MSR_SEGMENT_SIZE); sec_code_block_no = sec_code_block_no + msr_segment_id * MSR_SEGMENT_SIZE; printf("\n***get sec_decode_block. block_id=%d, sec_code_block_id=%d\n", msr_block_id,sec_code_block_id); //generate temporary coefficient array for (k=0; k<MSR_M; k++){ sec_code_block_coeff[k] = msr_coding_matrix[sec_code_block_id][k]; } for (k=0; k<BLOCKSIZE; k++){ sec_code_block_value[k] = disk_data[sec_code_disk_id][sec_code_block_no][k]; } //eliminate non-target values (failed blocks) for (j=0; j<MSR_M; j++){ if ((j != msr_block_id) && (sec_code_block_coeff[j] != 0) && (block_status[j] != 0)){ printf("\n****eliminate %d\n",j); //find decode block, eliminate the failed block temp_msr_block_id = msr_find_single_decode_block_id(j, MSR_SEGMENT_SIZE); temp_disk_id = msr_get_code_disk_id(temp_msr_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); temp_block_no = msr_get_code_block_no(temp_msr_block_id, MSR_SEGMENT_SIZE); temp_block_no = temp_block_no + msr_segment_id * MSR_SEGMENT_SIZE; printf("****code bock id: %d\n",temp_msr_block_id); for (k=0; k<MSR_M; k++){ temp_block_coeff[k] = msr_coding_matrix[temp_msr_block_id][k]; } if ((temp_disk_id != disk_id) || (temp_disk_id != disk_another_failed_id)){ for (k=0; k<BLOCKSIZE; k++){ temp_block_value[k] = disk_data[temp_disk_id][temp_block_no][k]; } }else{ printf("\nError: Attempt to access failed disk\n"); } temp_coeff1 = sec_code_block_coeff[j]; temp_coeff2 = temp_block_coeff[j]; printf("\n"); for (k=0; k<MSR_M; k++){ //temp = temp_coeff1 * temp_block_coeff[k] // ^ temp_coeff2 * sec_code_block_coeff[k]; temp = (int)((char)gf_mul((unsigned char)temp_coeff1, (unsigned char)temp_block_coeff[k], FIELDSIZE) ^ (char)gf_mul((unsigned char)temp_coeff2, (unsigned char)sec_code_block_coeff[k], FIELDSIZE)); sec_code_block_coeff[k] = temp; printf("%d:%d ",k,temp); } printf("\n"); for (k=0; k<BLOCKSIZE; k++){ sec_code_block_value[k] = (char)gf_mul((unsigned char)sec_code_block_value[k], (unsigned char)temp_coeff2, FIELDSIZE); temp_char = (char)gf_mul((unsigned char)temp_block_value[k], (unsigned char)temp_coeff1, FIELDSIZE); sec_code_block_value[k] ^= temp_char; } } } //eliminate non-target values (healthy blocks) for (j=0; j < MSR_M; j++){ if ((j != msr_block_id) && (sec_code_block_coeff[j] != 0)){ temp_msr_block_id = j; temp_disk_id = msr_get_disk_id(temp_msr_block_id, MSR_SEGMENT_SIZE, MSR_N, MSR_K); temp_block_no = msr_get_code_block_no(temp_msr_block_id, MSR_SEGMENT_SIZE); temp_block_no = temp_block_no + msr_segment_id * MSR_SEGMENT_SIZE; for (k=0; k<BLOCKSIZE; k++){ temp_block_value[k] = disk_data[temp_disk_id][temp_block_no][k]; } temp = sec_code_block_coeff[temp_msr_block_id]; for (k=0; k<BLOCKSIZE; k++){ temp_char = (char)gf_mul((unsigned char)temp, (unsigned char)temp_block_value[k], FIELDSIZE); sec_code_block_value[k] ^= temp_char; } sec_code_block_coeff[temp_msr_block_id] = 0; } } //find target value temp = sec_code_block_coeff[msr_block_id]; for (k=0; k<BLOCKSIZE; k++){ read_data[i][k] = (char)gf_div((unsigned char)sec_code_block_value[k], (unsigned char)temp, FIELDSIZE); } } else{ printf("\nTwo data-disk failure, or more than two disk failure. Non-supported failure."); printf("msr_block_id: %d. disk_id: %d. block_no: %d\n", msr_block_id, disk_id, block_no); } } } //PRINT Read Buffer printf("\n******PRINT Read Buffer******\n"); for (i=0; i <MSR_M * MSR_SEGMENT_NUM; i++){ printf("%d data block: ",i); for (j=0; j<BLOCKSIZE; j++){ printf("%c(%d) ",read_data[i][j],read_data[i][j]); } printf("\n"); } return 0; }