summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2011-02-22 16:23:52 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2011-02-22 16:23:52 +0000
commitebc3e0991986c8cf300312fff557b9670835cdb4 (patch)
treeb1e7e0924c237557ddcf47d2a36d60e8a6b81451
parent319f923c57c640dd35679817924d063e6741b623 (diff)
download2011-ddhardrescue-ebc3e0991986c8cf300312fff557b9670835cdb4.tar.gz
2011-ddhardrescue-ebc3e0991986c8cf300312fff557b9670835cdb4.tar.bz2
2011-ddhardrescue-ebc3e0991986c8cf300312fff557b9670835cdb4.zip
Fonction slicesFindLargestFast() et semble bien marcher.
Passage au 64 bits (long long int), correction de quelques cast implicites détruisant de l'information utile. Peaufinnage de la fonction slicesDump(), mais c'est pas encore terminé. En tout cas le calcul du blockSize à l'air d'être meilleur à présent, disons qu'on voit la fin des informations. git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@4 d3078510-dda0-49f1-841c-895ef4b7ec81
-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*/