#include #include "recover.h" slices_t *recover(char *src, char *dst, char*ddOpts, address_t beginSector, address_t endSector, int depth) { slices_t *slices; slice_t *sliceToRead; address_t firstError=0, median; int res; // Initialization : we want to try to recover the beginning of the whole zone slices=slicesNew(); sliceToRead=sliceNew(beginSector, endSector, S_UNKNOWN, NULL); if (sliceToRead==NULL) { exit(1);//TODO } slicesAppend(slices, sliceToRead); // Main loop while (!end && slices->count < (endSector-beginSector)/depth) { // try to recover sliceToRead and split it if read error switch ( tryRecoverUntilError(sliceToRead, &firstError) ) { case 0: // slice recovery has been executed without read error sliceToRead->status=S_RECOVERED; break; case EIO: // slice recovery has encuontered a readerror res=sliceSplit(sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN); if (res!=0) { exit(5); } //TODO break; default: exit(2); //TODO } /* Now, search the largest S_UNKNOWN zone split it in two parts */ sliceToRead=slicesFindLargest(slices, S_UNKNOWN); if ( sliceToRead == NULL ) { exit(3); } //TODO median=(sliceToRead->begin+sliceToRead->end)/2; res=sliceSplit(sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN); if (res!=0) { exit(4); } //TODO /* After splitting an S_UNKNOWN zone in two parts take the second for further analysis. We already now that this first one is just preceded by a read error, and errors are frequently grouped in zones, so trying to read a sector just after a faulty sector is most likely a waste of time. */ sliceToRead=sliceToRead->next; } return slices; } int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError) { //TODO : implement realy that int res; if ( sliceToRead->begin == sliceToRead->end ) { res=0; } else { *firstError=(sliceToRead->begin + sliceToRead->end)/2; res=EIO; } return res; }