diff options
Diffstat (limited to 'src/recover.c')
-rwxr-xr-x | src/recover.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/recover.c b/src/recover.c new file mode 100755 index 0000000..c2c2eff --- /dev/null +++ b/src/recover.c @@ -0,0 +1,68 @@ +#include <errno.h> +#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; +} + |