From 40e0333edb89563cb832b676fc34fae247ec31f1 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 20 Jun 2009 06:38:36 +0000 Subject: [PATCH] Wider scope of hardlink reconstruction with extract operations --- xorriso/xorriso.c | 67 +++++++++-- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 219 +++++++++++++++++++++++++----------- xorriso/xorrisoburn.h | 8 ++ 4 files changed, 219 insertions(+), 77 deletions(-) diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 02e5f4b2..154aa4d4 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -5392,11 +5392,15 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->node_counter= 0; m->node_array_size= 0; m->node_array= NULL; - m->node_targets= NULL; - m->node_targets_availmem= 0; m->node_disk_prefixes= NULL; m->node_img_prefixes= NULL; + m->hln_count= 0; + m->hln_array= NULL; + m->hln_targets= NULL; + + m->node_targets_availmem= 0; + m->di_count= 0; m->di_array= NULL; @@ -5486,6 +5490,7 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag) Xorriso_lst_destroy_all(&(m->drive_greylist), 0); Xorriso_lst_destroy_all(&(m->drive_whitelist), 0); Xorriso_destroy_node_array(m, 0); + Xorriso_destroy_hln_array(m, 0); Xorriso_destroy_di_array(m, 0); Xorriso_detach_libraries(m, flag&1); @@ -12931,7 +12936,8 @@ int Xorriso_restore_sorted(struct XorrisO *xorriso, int count, int i, ret, with_node_array= 0, hflag= 0, hret; if(xorriso->do_restore_sort_lba || - !((xorriso->ino_behavior & 4) || (flag & 1))) { + !((xorriso->ino_behavior & 4) || (flag & 1) || + xorriso->hln_array != NULL)) { /* Count affected nodes */ Xorriso_destroy_node_array(xorriso, 0); for(i= 0; i < count; i++) { @@ -12978,6 +12984,21 @@ int Xorriso_restore_sorted(struct XorrisO *xorriso, int count, goto ex; } } + + if(xorriso->hln_array == NULL && !xorriso->do_restore_sort_lba) { + /* Unsorted restore is desired and no long term hln array was installed: + Take over node array as hln array for this single run. */ + Xorriso_sort_node_array(xorriso, 0); + xorriso->hln_array= xorriso->node_array; + xorriso->node_array= NULL; + xorriso->node_array_size= 0; + xorriso->hln_count= xorriso->node_counter; + xorriso->node_counter= 0; + /* Allocate new hln_targets array */ + ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1); + if(ret<=0) + goto ex; + } } /* Perform restore operations */ @@ -12986,8 +13007,6 @@ int Xorriso_restore_sorted(struct XorrisO *xorriso, int count, if(ret <= 0) goto ex; } else { - if(with_node_array) - Xorriso_sort_node_array(xorriso, 0); for(i= 0; i < count; i++) { if(src_array[i] == NULL || tgt_array[i] == NULL) continue; @@ -14401,7 +14420,7 @@ ex:; int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { - int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy; + int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy, was_hln_array; char eff_origin[SfileadrL], eff_dest[SfileadrL]; char dest_dir[SfileadrL], leafname[SfileadrL], sfe[5*SfileadrL]; char **eff_src_array= NULL, **eff_tgt_array= NULL; @@ -14410,6 +14429,7 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv, char **optv= NULL; struct stat stbuf; + was_hln_array= (xorriso->hln_array != NULL); ret= Xorriso_cpmv_args(xorriso, "-cp*x", argc, argv, idx, &optc, &optv, eff_dest, 1|4); if(ret<=0) @@ -14519,6 +14539,8 @@ ex:; Sfile_destroy_argv(&i, &eff_tgt_array, 0); Xorriso_opt_args(xorriso, "-cp*x", argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); + if(!was_hln_array) + Xorriso_destroy_hln_array(xorriso, 0); return(ret); } @@ -14962,9 +14984,10 @@ int Xorriso_option_external_filter(struct XorrisO *xorriso, int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path, char *disk_path, int flag) { - int ret; + int ret, was_hln_array; char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth, *eopt[1], *edpt[1]; + was_hln_array= (xorriso->hln_array != NULL); if(xorriso->allow_restore <= 0) { sprintf(xorriso->info_text, "-extract: image-to-disk copies are not enabled by option -osirrox"); @@ -15009,6 +15032,8 @@ int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path, ex:; if(!(flag & (4 | 32))) Xorriso_destroy_node_array(xorriso, 0); + if(!was_hln_array) + Xorriso_destroy_hln_array(xorriso, 0); return(ret); } @@ -15667,11 +15692,19 @@ int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag) Xorriso_destroy_di_array(xorriso, 0); } else if(strcmp(mode, "start_update") == 0) { xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); - ret= Xorriso_make_di_array(xorriso, 0); + ret= Xorriso_make_di_array(xorriso, 1); if(ret <= 0) return(ret); } else if(strcmp(mode, "end_update") == 0) { Xorriso_destroy_di_array(xorriso, 0); + } else if(strcmp(mode, "start_extract") == 0) { + xorriso->do_restore_sort_lba= 0; + xorriso->ino_behavior&= ~(1 | 2 | 4); + ret= Xorriso_make_hln_array(xorriso, 1); + if(ret <= 0) + return(ret); + } else if(strcmp(mode, "end_extract") == 0) { + Xorriso_destroy_hln_array(xorriso, 0); } else { sprintf(xorriso->info_text, "-hardlinks: unknown mode '%s'", mode); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); @@ -15734,9 +15767,11 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -local_charset name", " Override system assumption of the local character set name.", " -hardlinks \"on\"|\"off\"|\"start_update\"|\"end_update\"|\"without_update\"", +" \"start_extract\"|\"end_extract\"", " Enable resp. disable recording and restoring of hard links,", -" or prepare for -update_r, or release prepared memory, or", -" disable hardlink detection with -update_r.", +" resp. prepare for -update_r, resp. release prepared memory,", +" resp. disable hardlink detection with -update_r, resp.", +" prepare for -extract, resp. release prepared memory.", " -acl \"on\"|\"off\"", " Enable resp. disable reading and writing of ACLs.", " -xattr \"on\"|\"off\"", @@ -16623,7 +16658,7 @@ int Xorriso_option_map(struct XorrisO *xorriso, char *disk_path, int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { - int ret, end_idx, optc= 0, was_failure= 1, i, fret, mode; + int ret, end_idx, optc= 0, was_failure= 1, i, fret, mode, made_hln_array= 0; int ns_flag= 2|4, nt_flag= 2, opt_args_flag= 2, made_di_array= 0; char source_prefix[SfileadrL], target_prefix[SfileadrL], *cmd, **optv= NULL; char eff_source[SfileadrL], eff_target[SfileadrL], *source_pt, *s_wd, *t_wd; @@ -16679,6 +16714,14 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv, } for(i= 0; i < optc; i++) eff_src_array[i]= eff_tgt_array[i]= NULL; + if(xorriso->hln_array == NULL && + !(xorriso->do_restore_sort_lba || (xorriso->ino_behavior & 4))) { + /* Create all-image node array sorted by iso image inode number */ + ret= Xorriso_make_hln_array(xorriso, 1); + if(ret <= 0) + goto ex; + made_hln_array= (xorriso->hln_array == NULL); + } } if(mode == 2 && !((xorriso->ino_behavior & 2) || (flag & 16) || xorriso->di_array != NULL)) { @@ -16768,6 +16811,8 @@ ex:; (*idx)= end_idx; if(made_di_array) Xorriso_destroy_di_array(xorriso, 0); + if(made_hln_array) + Xorriso_destroy_hln_array(xorriso, 0); Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256); if(ret<=0) return(ret); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 364a1b92..5fe09c2e 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.06.15.121525" +#define Xorriso_timestamP "2009.06.20.063853" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index eb3ae8c6..fd67ff58 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -142,15 +142,7 @@ int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag) iso_node_unref((IsoNode *) xorriso->node_array[i]); free(xorriso->node_array); } - if(xorriso->node_targets != NULL) { - for(i= 0; i < xorriso->node_counter; i++) - if(xorriso->node_targets[i] != NULL) - free(xorriso->node_targets[i]); - free(xorriso->node_targets); - } xorriso->node_array= NULL; - xorriso->node_targets= NULL; - xorriso->node_targets_availmem= 0; xorriso->node_counter= xorriso->node_array_size= 0; Xorriso_lst_destroy_all(&(xorriso->node_disk_prefixes), 0); Xorriso_lst_destroy_all(&(xorriso->node_img_prefixes), 0); @@ -158,6 +150,32 @@ int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag) } +/* @param flag bit0= do not destroy hln_array but only hln_targets +*/ +int Xorriso_destroy_hln_array(struct XorrisO *xorriso, int flag) +{ + int i; + + + if(xorriso->hln_array != NULL && !(flag & 1)) { + for(i= 0; i < xorriso->hln_count; i++) + iso_node_unref((IsoNode *) xorriso->hln_array[i]); + free(xorriso->hln_array); + xorriso->hln_array= NULL; + xorriso->hln_count= 0; + } + if(xorriso->hln_targets != NULL) { + for(i= 0; i < xorriso->hln_count; i++) + if(xorriso->hln_targets[i] != NULL) + free(xorriso->hln_targets[i]); + free(xorriso->hln_targets); + xorriso->hln_targets= NULL; + } + xorriso->node_targets_availmem= 0; + return(1); +} + + int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag) { int i; @@ -181,16 +199,13 @@ int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag) } -/* @param flag bit0= allocate xorriso->node_targets too -*/ int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, int flag) { int i; - if(xorriso->node_counter <= 0) { - Xorriso_destroy_node_array(xorriso, 0); + if(xorriso->node_counter <= 0) return(1); - } + xorriso->node_array= calloc(xorriso->node_counter, sizeof(IsoNode *)); if(xorriso->node_array == NULL) { Xorriso_no_malloc_memory(xorriso, NULL, 0); @@ -198,24 +213,48 @@ int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, int flag) } for(i= 0; i < xorriso->node_counter; i++) xorriso->node_array[i]= NULL; - if(flag & 1) { - xorriso->node_targets= calloc(xorriso->node_counter, sizeof(char *)); - if(xorriso->node_array == NULL) { - free(xorriso->node_array); - xorriso->node_array= NULL; + xorriso->node_array_size= xorriso->node_counter; + xorriso->node_counter= 0; + return(1); +} + + +/* @param flag bit0= do not allocate hln_array but only hln_targets +*/ +int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag) +{ + int i; + + Xorriso_destroy_hln_array(xorriso, flag & 1); + if(xorriso->hln_count <= 0) + return(1); + + if(!(flag & 1)) { + xorriso->hln_array= calloc(xorriso->hln_count, sizeof(char *)); + if(xorriso->hln_array == NULL) { Xorriso_no_malloc_memory(xorriso, NULL, 0); return(-1); } - for(i= 0; i < xorriso->node_counter; i++) - xorriso->node_targets[i]= NULL; - xorriso->node_targets_availmem= mem_limit - - xorriso->node_counter * sizeof(void *) - - xorriso->node_counter * sizeof(char *); + for(i= 0; i < xorriso->hln_count; i++) + xorriso->hln_array[i]= NULL; + } + + xorriso->hln_targets= calloc(xorriso->hln_count, sizeof(char *)); + if(xorriso->hln_targets == NULL) { + if(!(flag & 1)) { + free(xorriso->hln_array); + xorriso->hln_array= NULL; + } + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + for(i= 0; i < xorriso->hln_count; i++) + xorriso->hln_targets[i]= NULL; + xorriso->node_targets_availmem= mem_limit + - xorriso->hln_count * sizeof(void *) + - xorriso->hln_count * sizeof(char *); if(xorriso->node_targets_availmem < 0) xorriso->node_targets_availmem= 0; - } - xorriso->node_array_size= xorriso->node_counter; - xorriso->node_counter= 0; return(1); } @@ -299,14 +338,14 @@ int Xorriso__search_node(void *node_array[], int n, } -int Xorriso_search_in_node_array(struct XorrisO *xorriso, +int Xorriso_search_in_hln_array(struct XorrisO *xorriso, void *node, int *idx, int flag) { int ret; - if(xorriso->node_array_size <= 0 || xorriso->node_array == NULL) + if(xorriso->hln_array == NULL || xorriso->hln_count <= 0) return(0); - ret= Xorriso__search_node(xorriso->node_array, xorriso->node_counter, + ret= Xorriso__search_node(xorriso->hln_array, xorriso->hln_count, Xorriso__findi_sorted_ino_cmp, node, idx, 0); return ret; } @@ -3832,7 +3871,7 @@ int Xorriso_restore_overwrite(struct XorrisO *xorriso, } -/* @param flag bit0= do not accept node_targets[i] != NULL as *node_idx +/* @param flag bit0= do not accept hln_targets[i] != NULL as *node_idx bit1= use *node_idx as found index rather than searching it */ int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, @@ -3847,16 +3886,16 @@ int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, idx= *node_idx; } else { *node_idx= -1; - ret= Xorriso_search_in_node_array(xorriso, np, &idx, 0); + ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0); if(ret <= 0) return(ret); } for(i= idx - 1; i >= 0 ; i--) - if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i]), &np) != 0) + if(Xorriso__findi_sorted_ino_cmp(&(xorriso->hln_array[i]), &np) != 0) break; *min_hl= i + 1; - for(i= idx + 1; i < xorriso->node_counter; i++) - if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i]), &np) != 0) + for(i= idx + 1; i < xorriso->hln_count; i++) + if(Xorriso__findi_sorted_ino_cmp(&(xorriso->hln_array[i]), &np) != 0) break; *max_hl= i - 1; @@ -3864,9 +3903,9 @@ int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, if(flag & 2) return(1); for(i= *min_hl; i <= *max_hl; i++) - if(xorriso->node_array[i] == np) { - if((flag & 1) && xorriso->node_targets != NULL) - if(xorriso->node_targets[i] != NULL) + if(xorriso->hln_array[i] == np) { + if((flag & 1) && xorriso->hln_targets != NULL) + if(xorriso->hln_targets[i] != NULL) continue; *node_idx= i; break; @@ -3886,7 +3925,7 @@ int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node, { int ret, min_hl, max_hl, i, null_target_sibling= 0, link_sibling= 0; - if(xorriso->node_targets == NULL) + if(xorriso->hln_targets == NULL) return(0); ret= Xorriso_search_hardlinks(xorriso, node, node_idx, &min_hl, &max_hl, 1); if(ret < 0) @@ -3894,13 +3933,13 @@ int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node, if(ret == 0 || *node_idx < 0 || min_hl == max_hl) return(0); for(i= min_hl; i <= max_hl; i++) { - if(xorriso->node_targets[i] == NULL) { + if(xorriso->hln_targets[i] == NULL) { if(i != *node_idx) null_target_sibling= 1; continue; } link_sibling= 1; - ret= Xorriso_restore_make_hl(xorriso, xorriso->node_targets[i], disk_path, + ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path, 0); if(ret > 0) return(1); @@ -3967,12 +4006,12 @@ int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx, if(xorriso->node_targets_availmem == 0) return(2); - if(xorriso->node_targets == NULL || node_idx < 0 || - node_idx >= xorriso->node_array_size || node_idx >= xorriso->node_counter) + if(xorriso->hln_targets == NULL || node_idx < 0 || + node_idx >= xorriso->hln_count) return(0); - if(xorriso->node_targets[node_idx] != NULL) { - xorriso->node_targets_availmem+= strlen(xorriso->node_targets[node_idx]) +1; - free(xorriso->node_targets[node_idx]); + if(xorriso->hln_targets[node_idx] != NULL) { + xorriso->node_targets_availmem+= strlen(xorriso->hln_targets[node_idx]) +1; + free(xorriso->hln_targets[node_idx]); } l= strlen(disk_path); if(xorriso->node_targets_availmem <= l + 1) { @@ -3982,8 +4021,8 @@ int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx, xorriso->node_targets_availmem= 0; return(0); } - xorriso->node_targets[node_idx]= strdup(disk_path); - if(xorriso->node_targets[node_idx] == NULL) { + xorriso->hln_targets[node_idx]= strdup(disk_path); + if(xorriso->hln_targets[node_idx] == NULL) { Xorriso_no_malloc_memory(xorriso, NULL, 0); return(-1); } @@ -11592,26 +11631,12 @@ int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp, } -/* @param flag bit0= overwrite existing di_array (else return 2) - bit1= make di_array despite xorriso->ino_behavior bit 3 -*/ -int Xorriso_make_di_array(struct XorrisO *xorriso, int flag) +int Xorriso_all_node_array(struct XorrisO *xorriso, int flag) { - int ret; + int ret; struct FindjoB *job= NULL; struct stat dir_stbuf; -#ifdef NIX - /* <<< */ - unsigned long old_gdic; - old_gdic= Xorriso_get_di_counteR; -#endif /* NIX */ - - if((xorriso->ino_behavior & 8 ) && !(flag & 2)) - return(2); - if(xorriso->di_array != NULL && !(flag & 1)) - return(2); - Xorriso_destroy_di_array(xorriso, 0); ret= Findjob_new(&job, "/", 0); if(ret<=0) { Xorriso_no_findjob(xorriso, "xorriso", 0); @@ -11631,11 +11656,76 @@ int Xorriso_make_di_array(struct XorrisO *xorriso, int flag) &dir_stbuf, 0, 0); if(ret <= 0) goto ex; + ret= 1; +ex:; + Findjob_destroy(&job, 0); + return(ret); +} + + +/* @param flag bit0= overwrite existing hln_array (else return 2) +*/ +int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag) +{ + int ret; + + if(xorriso->hln_array != NULL && !(flag & 1)) + return(2); + Xorriso_destroy_hln_array(xorriso, 0); + + ret= Xorriso_all_node_array(xorriso, 0); + if(ret <= 0) + goto ex; + Xorriso_sort_node_array(xorriso, 0); + + /* Transfer node_array to di_array without unrefering nodes */ + xorriso->hln_count= xorriso->node_counter; + xorriso->hln_array= xorriso->node_array; + xorriso->node_counter= 0; + xorriso->node_array_size= 0; + xorriso->node_array= NULL; + + /* Allocate hln_targets */ + ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1); + if(ret<=0) + goto ex; + + ret= 1; +ex:; + return(ret); +} + + +/* @param flag bit0= overwrite existing di_array (else return 2) + bit1= make di_array despite xorriso->ino_behavior bit 3 +*/ +int Xorriso_make_di_array(struct XorrisO *xorriso, int flag) +{ + int ret; + +#ifdef NIX + /* <<< */ + unsigned long old_gdic; + old_gdic= Xorriso_get_di_counteR; +#endif /* NIX */ + + if((xorriso->ino_behavior & 8 ) && !(flag & 2)) + return(2); + if(xorriso->di_array != NULL && !(flag & 1)) + return(2); + Xorriso_destroy_di_array(xorriso, 0); + + ret= Xorriso_all_node_array(xorriso, 0); + if(ret <= 0) + goto ex; + + /* Transfer node_array to di_array without unrefering nodes */ xorriso->di_count= xorriso->node_counter; xorriso->di_array= xorriso->node_array; xorriso->node_counter= 0; xorriso->node_array_size= 0; - xorriso->node_array= 0; + xorriso->node_array= NULL; + Xorriso__sort_di((void *) xorriso->di_array, xorriso->di_count, 0); ret= 1; @@ -11647,7 +11737,6 @@ ex:; Xorriso_get_di_counteR - old_gdic); #endif /* NIX */ - Findjob_destroy(&job, 0); return(ret); } diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 91bb01cb..4df32ee1 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -306,12 +306,16 @@ int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag); int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag); +int Xorriso_destroy_hln_array(struct XorrisO *xorriso, int flag); + int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag); int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, int flag); int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag); +int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag); + /* @param flag bit0= allocate xorriso->node_targets too */ int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag); @@ -464,6 +468,10 @@ int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp, */ int Xorriso_make_di_array(struct XorrisO *xorriso, int flag); +/* @param flag bit0= overwrite existing hln_array (else return 2) +*/ +int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag); + /* @param flag bit2= -follow: this is not a command parameter @return -1= severe error