summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/list.c83
-rw-r--r--src/list.h27
-rw-r--r--src/photorec.c30
-rw-r--r--src/phrecn.c61
4 files changed, 100 insertions, 101 deletions
diff --git a/src/list.c b/src/list.c
index e914ad9b..042bb499 100644
--- a/src/list.c
+++ b/src/list.c
@@ -31,77 +31,24 @@
#include "list.h"
#include "log.h"
-/* #define DEBUG_LIST_APPEND_BLOCK */
-void list_append_block(alloc_list_t *list, const uint64_t offset, const uint64_t blocksize, const unsigned int data)
+void list_truncate(alloc_list_t *list, const uint64_t file_size)
{
- alloc_list_t *prev;
-#ifdef DEBUG_LIST_APPEND_BLOCK
- log_debug("list_append_block([");
- for(prev=list;prev!=NULL;prev=prev->next)
+ struct td_list_head *tmp;
+ struct td_list_head *next;
+ uint64_t size=0;
+ td_list_for_each_safe(tmp, next, &list->list)
{
- log_debug("%llu-%llu", (long long unsigned)prev->start, (long long unsigned)prev->end);
- }
- log_debug("], %llu, %llu, %d)\n", (long long unsigned)offset,
- (long long unsigned) blocksize, data);
-#endif
- if(list!=NULL && list->end==0)
- { /* Use preallocated list */
- list->start=offset;
- list->end=offset+blocksize-1;
- list->prev=NULL;
- list->next=NULL;
- list->data=data;
- return ;
- }
- for(prev=list;prev!=NULL && prev->next!=NULL; prev=prev->next);
- if(prev!=NULL && prev->end+1==offset && prev->data==data)
- {
- prev->end=offset+blocksize-1;
- return ;
- }
- {
- alloc_list_t *new_list=(alloc_list_t *)MALLOC(sizeof(*new_list));
- new_list->start=offset;
- new_list->end=offset+blocksize-1;
- new_list->prev=prev;
- new_list->next=(prev!=NULL?prev->next:NULL);
- new_list->data=data;
- if(prev!=NULL)
- prev->next=new_list;
- if(new_list->next!=NULL)
- new_list->next->prev=new_list;
- }
-}
-
-void list_truncate(alloc_list_t *list, uint64_t size)
-{
- alloc_list_t *element;
- uint64_t file_size=0;
- /* uint64_t file_size_on_disk=0; */
- for(element=list;element!=NULL;element=element->next)
- {
- /* file_size_on_disk+=(element->end-element->start+1); */
- if(element->data>0)
+ alloc_list_t *element=td_list_entry(tmp, alloc_list_t, list);
+ if(size>=file_size)
{
- file_size+=(element->end-element->start+1);
- if(file_size>=size)
- {
- element->end-=(file_size-size);
- td_list_delete(element->next);
-// element->next=NULL; already done by td_list_delete
- }
+ td_list_del(tmp);
+ free(element);
+ }
+ else if(element->data>0)
+ {
+ size+=(element->end-element->start+1);
+ if(size>=file_size)
+ element->end-=(size-file_size);
}
- }
-}
-
-void td_list_delete(alloc_list_t *list)
-{
- alloc_list_t *next;
- if(list!=NULL && list->prev!=NULL)
- list->prev->next=NULL;
- for(;list!=NULL;list=next)
- {
- next=list->next;
- free(list);
}
}
diff --git a/src/list.h b/src/list.h
index e4170412..a7747d64 100644
--- a/src/list.h
+++ b/src/list.h
@@ -21,22 +21,6 @@
*/
#ifndef _LIST_H
#define _LIST_H
-typedef struct struct_mediaspace alloc_list_t;
-
-struct struct_mediaspace
-{
- uint64_t start;
- uint64_t end;
- alloc_list_t *prev;
- alloc_list_t *next;
- unsigned int data;
-};
-
-void list_append_block(alloc_list_t *list, const uint64_t offset, const uint64_t blocksize, const unsigned int data);
-void list_truncate(alloc_list_t *list, uint64_t size);
-void td_list_delete(alloc_list_t *list);
-
-
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
@@ -376,4 +360,15 @@ static inline int td_list_add_sorted_uniq(struct td_list_head *newe, struct td_l
td_list_add_tail(newe, head);
return 0;
}
+
+typedef struct alloc_list_s alloc_list_t;
+struct alloc_list_s
+{
+ struct td_list_head list;
+ uint64_t start;
+ uint64_t end;
+ unsigned int data;
+};
+
+void list_truncate(alloc_list_t *list, const uint64_t file_size);
#endif
diff --git a/src/photorec.c b/src/photorec.c
index 949e2e9c..9bf7f9d7 100644
--- a/src/photorec.c
+++ b/src/photorec.c
@@ -259,14 +259,15 @@ void sighup_hdlr(int shup)
void list_space_used(const file_recovery_t *file_recovery, const unsigned int sector_size)
{
- const alloc_list_t *element;
+ struct td_list_head *tmp;
uint64_t file_size=0;
uint64_t file_size_on_disk=0;
if(file_recovery->filename==NULL)
return;
log_info("%s\t",file_recovery->filename);
- for(element=&file_recovery->location;element!=NULL;element=element->next)
+ td_list_for_each(tmp, &file_recovery->location.list)
{
+ const alloc_list_t *element=td_list_entry(tmp, alloc_list_t, list);
file_size_on_disk+=(element->end-element->start+1);
if(element->data>0)
{
@@ -318,7 +319,6 @@ static void list_free_add(const file_recovery_t *file_recovery, alloc_data_t *li
static alloc_data_t *update_search_space(const file_recovery_t *file_recovery, alloc_data_t *list_search_space, alloc_data_t **new_current_search_space, uint64_t *offset, const unsigned int blocksize)
{
- const alloc_list_t *element;
struct td_list_head *search_walker = NULL;
#ifdef DEBUG_UPDATE_SEARCH_SPACE
log_trace("update_search_space\n");
@@ -327,6 +327,7 @@ static alloc_data_t *update_search_space(const file_recovery_t *file_recovery, a
td_list_for_each(search_walker, &list_search_space->list)
{
+ struct td_list_head *tmp;
alloc_data_t *current_search_space;
current_search_space=td_list_entry(search_walker, alloc_data_t, list);
if(current_search_space->start <= file_recovery->location.start &&
@@ -334,8 +335,9 @@ static alloc_data_t *update_search_space(const file_recovery_t *file_recovery, a
{
*offset=file_recovery->location.start;
*new_current_search_space=current_search_space;
- for(element=&file_recovery->location;element!=NULL;element=element->next)
+ td_list_for_each(tmp, &file_recovery->location.list)
{
+ const alloc_list_t *element=td_list_entry(tmp, alloc_list_t, list);
uint64_t end=(element->end-(element->start%blocksize)+blocksize-1+1)/blocksize*blocksize+(element->start%blocksize)-1;
list_search_space=update_search_space_aux(list_search_space, element->start, end, new_current_search_space, offset);
}
@@ -500,8 +502,8 @@ void reset_file_recovery(file_recovery_t *file_recovery)
file_recovery->handle=NULL;
file_recovery->file_size=0;
file_recovery->file_size_on_disk=0;
- file_recovery->location.prev=NULL;
- file_recovery->location.next=NULL;
+ file_recovery->location.list.prev=&file_recovery->location.list;
+ file_recovery->location.list.next=&file_recovery->location.list;
file_recovery->location.start=0;
file_recovery->location.end=0;
file_recovery->location.data=0;
@@ -1261,6 +1263,19 @@ void file_check_size(file_recovery_t *file_recovery)
file_recovery->file_size=file_recovery->calculated_file_size;
}
+static void free_list_allocation(alloc_list_t *list_allocation)
+{
+ struct td_list_head *tmp = NULL;
+ struct td_list_head *tmp_next = NULL;
+ td_list_for_each_safe(tmp,tmp_next,&list_allocation->list)
+ {
+ alloc_list_t *allocated_space;
+ allocated_space=td_list_entry(tmp, alloc_list_t, list);
+ td_list_del(tmp);
+ free(allocated_space);
+ }
+}
+
/* file_finish() returns
-1: file not recovered, file_size=0 offset_error!=0
0: file not recovered
@@ -1346,8 +1361,7 @@ int file_finish(file_recovery_t *file_recovery, const char *recup_dir, const int
list_search_space=update_search_space(file_recovery,list_search_space,current_search_space,offset,blocksize);
file_recovered=1;
}
- td_list_delete(file_recovery->location.next);
- file_recovery->location.next=NULL;
+ free_list_allocation(&file_recovery->location);
}
if(file_recovery->file_size==0 && file_recovery->offset_error!=0)
file_recovered=-1;
diff --git a/src/phrecn.c b/src/phrecn.c
index 5164b96b..b17bb384 100644
--- a/src/phrecn.c
+++ b/src/phrecn.c
@@ -149,6 +149,7 @@ void get_next_sector(alloc_data_t *list_search_space, alloc_data_t **current_sea
{
return ;
}
+#ifdef DEBUG_GET_NEXT_SECTOR
if(! ((*current_search_space)->start <= *offset && (*offset)<=(*current_search_space)->end))
{
log_critical("BUG: get_next_sector stop everything %llu (%llu-%llu)\n",
@@ -156,16 +157,58 @@ void get_next_sector(alloc_data_t *list_search_space, alloc_data_t **current_sea
(unsigned long long)((*current_search_space)->start/512),
(unsigned long long)((*current_search_space)->end/512));
log_flush();
-#ifdef DEBUG_GET_NEXT_SECTOR
bug();
-#endif
exit(1);
}
+#endif
if((*offset)+blocksize <= (*current_search_space)->end)
*offset+=blocksize;
else
get_next_header(list_search_space, current_search_space, offset);
}
+
+static inline void file_recovery_cpy(file_recovery_t *dst, file_recovery_t *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+#if 0
+ if(td_list_empty(&src->location.list))
+ {
+ dst->location.list.prev=&dst->location.list;
+ dst->location.list.next=&dst->location.list;
+ }
+ else
+ {
+ src->location.list.prev=&src->location.list;
+ src->location.list.next=&src->location.list;
+ dst->location.list.prev->next=&dst->location.list;
+ dst->location.list.next->prev=&dst->location.list;
+ }
+#else
+ dst->location.list.prev=&dst->location.list;
+ dst->location.list.next=&dst->location.list;
+#endif
+}
+
+static inline void list_append_block(alloc_list_t *list, const uint64_t offset, const uint64_t blocksize, const unsigned int data)
+{
+ if(!td_list_empty(&list->list))
+ {
+ alloc_list_t *prev=td_list_entry(list->list.prev, alloc_list_t, list);
+ if(prev->end+1==offset && prev->data==data)
+ {
+ prev->end=offset+blocksize-1;
+ return ;
+ }
+ }
+ {
+ alloc_list_t *new_list=(alloc_list_t *)MALLOC(sizeof(*new_list));
+ new_list->start=offset;
+ new_list->end=offset+blocksize-1;
+ new_list->data=data;
+ td_list_add_tail(&new_list->list, &list->list);
+ }
+}
+
/* ==================== INLINE FUNCTIONS ========================= */
#ifdef HAVE_NCURSES
@@ -550,7 +593,7 @@ static int photorec_bf(disk_t *disk_car, partition_t *partition, const int verbo
}
if(file_recovery.file_stat==NULL)
{ /* Header found => file found */
- memcpy(&file_recovery, &file_recovery_new, sizeof(file_recovery));
+ file_recovery_cpy(&file_recovery, &file_recovery_new);
}
else if(file_recovery_new.file_stat->file_hint!=NULL)
{
@@ -723,10 +766,10 @@ static int photorec_bf_aux(disk_t *disk_car, partition_t *partition, const int p
#endif
/* Get the last block added to the file */
extrablock_offset=0;
+ if(!td_list_empty(&file_recovery->location.list))
{
- const alloc_list_t *element;
- for(element=&file_recovery->location;element!=NULL;element=element->next)
- extrablock_offset=element->end/blocksize*blocksize;
+ const alloc_list_t *element=td_list_entry(file_recovery->location.list.prev, alloc_list_t, list);
+ extrablock_offset=element->end/blocksize*blocksize;
}
/* Get the corresponding search_place */
extractblock_search_space=td_list_entry(list_search_space->list.next, alloc_data_t, list);
@@ -799,8 +842,8 @@ static int photorec_bf_aux(disk_t *disk_car, partition_t *partition, const int p
log_trace("offset_error %llu %llu\n",
(long long unsigned) file_recovery->offset_error,
(long long unsigned) offset_error_tmp);
-#endif
log_flush();
+#endif
fseek(file_recovery->handle, save_seek, SEEK_SET);
} while(file_recovery->offset_error/blocksize*blocksize > offset_error_tmp/blocksize*blocksize);
}
@@ -922,7 +965,7 @@ static int photorec_find_blocksize(disk_t *disk_car, partition_t *partition, con
/* A new file begins, backup file offset */
alloc_data_t *new_file_alloc;
file_recovery_new.location.start=offset;
- memcpy(&file_recovery, &file_recovery_new, sizeof(file_recovery));
+ file_recovery_cpy(&file_recovery, &file_recovery_new);
new_file_alloc=(alloc_data_t*)MALLOC(sizeof(*new_file_alloc));
new_file_alloc->start=offset;
new_file_alloc->end=0;
@@ -1112,7 +1155,7 @@ static int photorec_aux(disk_t *disk_car, partition_t *partition, const int verb
forget(list_search_space,current_search_space);
if(move_next!=0)
{
- memcpy(&file_recovery, &file_recovery_new, sizeof(file_recovery));
+ file_recovery_cpy(&file_recovery, &file_recovery_new);
if(verbose>1)
{
log_info("%s header found at sector %lu\n",