diff options
-rwxr-xr-x | src/ddhardrescue.c | 5 | ||||
-rwxr-xr-x | src/recover.c | 16 | ||||
-rwxr-xr-x | src/slices.c | 38 | ||||
-rwxr-xr-x | src/slices.h | 5 |
4 files changed, 53 insertions, 11 deletions
diff --git a/src/ddhardrescue.c b/src/ddhardrescue.c index a99b9d8..f97ae99 100755 --- a/src/ddhardrescue.c +++ b/src/ddhardrescue.c @@ -24,7 +24,7 @@ int main() { dst="./test.img"; ddOpts=""; beginSector=0; - endSector=19999; + endSector=21474836480ULL; //10 Tio // depth=1; /* endSector=1999999999; @@ -32,13 +32,14 @@ int main() { */ //TODO signal... + srand(4); slices=recover(src,dst,ddOpts,beginSector,endSector/*,depth*/); blockSize=0; dump=slicesDump(slices, &blockSize, 1000, beginSector, endSector); puts(dump); free(dump); - printf("blockSize==%ld\n", blockSize); + printf("blockSize==%lld\n", blockSize); printf("c==%ld\n", c); printf("slices->count==%d\n", slices->count); diff --git a/src/recover.c b/src/recover.c index 0f305a1..5e9e187 100755 --- a/src/recover.c +++ b/src/recover.c @@ -4,10 +4,10 @@ extern unsigned long c; -slices_t *recover(char *src, char *dst, char*ddOpts, address_t beginSector, address_t endSector/*, int depth*/) { +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; + address_t firstError=0, median, foundMax=0; int res; // Initialization : we want to try to recover the beginning of the whole zone @@ -41,7 +41,8 @@ slices_t *recover(char *src, char *dst, char*ddOpts, address_t beginSector, addr /* Now, search the largest S_UNKNOWN zone split it in two parts */ - sliceToRead=slicesFindLargest(slices, S_UNKNOWN); + //sliceToRead=slicesFindLargest(slices, S_UNKNOWN); + sliceToRead=slicesFindLargestFast(slices, &foundMax, S_UNKNOWN, foundMax, sliceToRead->next); if ( sliceToRead == NULL ) { // There is nothing more to recover, bailout end=1; @@ -92,14 +93,20 @@ int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src, seek=sliceToRead->begin; count=sliceToRead->end - seek + 1; - res=snprintf(ddinvocation, 255, "dd %s %s %s seek=%ld skip=%ld count=%ld", src, dst, ddOpts, seek, seek, count); + res=snprintf(ddinvocation, 255, "dd %s %s %s seek=%lld skip=%lld count=%lld", src, dst, ddOpts, seek, seek, count); puts(ddinvocation); +/* // Simulate that we have systematically a read error at first sector *firstError=sliceToRead->begin; res=EIO; +*/ + // Simulate that we have systematically a read error at last sector + *firstError=sliceToRead->end; + res=EIO; /* + // Simulate that we have systematically a read error at first sector // Simulate for each read, tha we have an error just in the middle if read for mor than one sector if ( sliceToRead->begin == sliceToRead->end ) { res=0; @@ -108,7 +115,6 @@ int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src, res=EIO; } */ - /* // Simulate for each read a pseudo random error position and generate some cases of full read without error int error=sliceToRead->begin + rand()%count; diff --git a/src/slices.c b/src/slices.c index 8e9aee6..68e39f9 100755 --- a/src/slices.c +++ b/src/slices.c @@ -113,14 +113,43 @@ slice_t *slicesFindLargest(slices_t *slices, sliceStatus_t status) { return sMax; } +slice_t *slicesFindLargestFast(slices_t *slices, address_t *foundMax, sliceStatus_t status, address_t knownMax, slice_t *firstToTry) { + slice_t *curr, *sMax = NULL; + address_t i, iMax = 0; + + curr = firstToTry; + while (curr != NULL) { + i=curr->end - curr->begin + 1; + if ( curr->status == status ) { + if ( knownMax == i ) { *foundMax=i; return curr; } + if ( i > iMax ) { + iMax = i; + sMax = curr; + } + } + curr=curr->next; + } + curr = slices->first; + while (curr != firstToTry) { + i=curr->end - curr->begin + 1; + if ( curr->status == status && i > iMax ) { + iMax = i; + sMax = curr; + } + curr=curr->next; + } + *foundMax=iMax; + return sMax; +} + char *slicesDump(slices_t *slices, address_t *blockSize, unsigned int charCount, address_t begin, address_t end) { slice_t *curr = slices->first; - unsigned int sb,se,i; + address_t sb,se,i; char *dump, ci; // If blockSize is 0, try to autodetect to display entire slice chain if (*blockSize == 0) { - *blockSize=(end-begin+1)/(charCount+1); + *blockSize=(end-begin+1)/(charCount-1); // If we have a too big zoom factor, draw it at 1:1 scale if (*blockSize==0) *blockSize=1; } @@ -132,6 +161,11 @@ char *slicesDump(slices_t *slices, address_t *blockSize, unsigned int charCount, while (curr != NULL) { sb=curr->begin / *blockSize; //FIXME : gérer le max également ! +/* +if ( curr->end / *blockSize > charCount -1 ) { + printf("\nBUG : end/blkSze==%lli, charCount==%i\n", curr->end / *blockSize,charCount-1); +} +*/ se=min(curr->end / *blockSize,charCount-1); switch (curr->status) { diff --git a/src/slices.h b/src/slices.h index 9f97246..85cb621 100755 --- a/src/slices.h +++ b/src/slices.h @@ -10,10 +10,10 @@ Slice are inclusive intervals. Let say sliceNew(1,2,S_UNKNOWN,NULL) return a [1; */ typedef enum { S_UNKNOWN, S_RECOVERED, S_UNREADABLE } sliceStatus_t; -typedef unsigned long int address_t; +typedef unsigned long long int address_t; typedef struct _slice { - uint32_t begin, end; + address_t begin, end; sliceStatus_t status; struct _slice *next; } slice_t; @@ -29,6 +29,7 @@ int sliceSplit(slices_t *slices, slice_t *initialSlice, address_t splitAt, slice slices_t *slicesNew(); void slicesAppend(slices_t *slices, slice_t *slice); slice_t *slicesFindLargest(slices_t *slices, sliceStatus_t status); +slice_t *slicesFindLargestFast(slices_t *slices, address_t *foundMax, sliceStatus_t status, address_t knownMax, slice_t *firstToTry); char *slicesDump(slices_t *slices, address_t *blockSize, unsigned int charCount, address_t begin, address_t end); #endif /*SLICES_H*/ |