diff options
-rw-r--r-- | src/list.c | 83 | ||||
-rw-r--r-- | src/list.h | 27 | ||||
-rw-r--r-- | src/photorec.c | 30 | ||||
-rw-r--r-- | src/phrecn.c | 61 |
4 files changed, 100 insertions, 101 deletions
@@ -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); } } @@ -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", |