summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/ddhardrescue.c5
-rwxr-xr-xsrc/recover.c16
-rwxr-xr-xsrc/slices.c38
-rwxr-xr-xsrc/slices.h5
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*/