From e21150e227e28599c7529952d21be5c4fa8694dc Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 27 Jun 2009 11:23:59 +0000 Subject: [PATCH] With -extract : made hardlink registration combinable with sort_lba --- xorriso/xorriso.1 | 19 ++-- xorriso/xorriso.c | 177 +++++++++++++++--------------------- xorriso/xorriso_private.h | 2 + xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 45 +++++---- 5 files changed, 115 insertions(+), 130 deletions(-) diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 2b410b04..a40fe82c 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Jun 23, 2009" +.TH XORRISO 1 "Jun 27, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -668,8 +668,7 @@ terminal where xorriso runs. Before attributing this local character set to the produced ISO image, check whether the terminal properly displays all intended filenames, especially exotic national characters. .TP -\fB\-hardlinks\fR "on" | "off" | "without_update" | "perform_update" | "start_extract" | "end_extract" -.br +\fB\-hardlinks\fR mode[:mode...] Enable or disable loading and recording of hardlink relations. .br In default mode "off", iso_rr files lose their inode numbers at image load @@ -691,15 +690,15 @@ automatic last minute changes before the session gets written. Command Mode "without_update" avoids hardlink processing during update commands. .br xorriso commands which extract files from an ISO image try to hardlink files -with identical inode number. Normally this applies only to files which -get extracted during execution of that same command. One may surround a group -of extraction commands by -hardlinks "start_extract" and --hardlinks "end_extract" to allow hard linking among their extracted files. --osirrox "sort_lba_on" and -hardlinks "start_extract" mutually disable -each other. +with identical inode number. The normal scope of this operation is from +image load to image load. One may give up the accumulated hard link addresses +by -hardlinks "discard_extract". .br A large number of hardlink families may exhaust -temp_mem_limit -if not -osirrox option "sort_lba_on" is in effect. +if not -osirrox "sort_lba_on" and -hardlinks "cheap_sorted_extract" +are both in effect. This restricts hard linking to other files restored by +the same single extract command. -hardlinks "normal_extract" re-enables +wide and expensive hardlink accumulation. .br Hardlink processing automatically enables \fB\-compliance new_rr\fR. This may be overridden by a following -compliance old_rr . In this case diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index ef248507..acbfd47d 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -7627,13 +7627,15 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); - is_default= ((xorriso->ino_behavior & 15) == 7); + is_default= ((xorriso->ino_behavior & 31) == 7); switch (xorriso->ino_behavior & 15) { case 0: form= "on"; break; case 8: form= "without_update"; break; default: form= "off"; } - sprintf(line,"-hardlinks %s\n", form); + sprintf(line,"-hardlinks %s:%s\n", form, + xorriso->ino_behavior & 16 ? + "cheap_sorted_extract" : "normal_extract"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); @@ -12145,7 +12147,7 @@ int Xorriso_restore_make_hl(struct XorrisO *xorriso, Text_shellsafe(new_path, xorriso->info_text, 1); strcat(xorriso->info_text, " -> "); Text_shellsafe(old_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "WARNING", 0); return(0); } @@ -12973,25 +12975,23 @@ 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->hln_array != NULL)) { + if(xorriso->hln_array == NULL && + !(((xorriso->ino_behavior & 16) && xorriso->do_restore_sort_lba) || + (xorriso->ino_behavior & 4) || (flag & 1))) { + ret= Xorriso_make_hln_array(xorriso, 0); + if(ret<=0) + goto ex; + } + if(xorriso->do_restore_sort_lba) { /* Count affected nodes */ Xorriso_destroy_node_array(xorriso, 0); for(i= 0; i < count; i++) { if(src_array[i] == NULL || tgt_array[i] == NULL) continue; - if(xorriso->do_restore_sort_lba) { - /* sort_lba : Make directories plus node_array and then - run array extractor (with eventual hardlink detection) - */ - hflag= (1 << 7) | ((!!(flag & 2)) << 9); - } else { - /* Hardlink detection: Have a sorted node_array with list of pathnames - for binary lookup in Xorriso_restore() - */ - hflag= 3 << 7; - } + /* sort_lba : Make directories plus node_array and then + run array extractor (with eventual hardlink detection) + */ + hflag= (1 << 7) | ((!!(flag & 2)) << 9); ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], (off_t) 0, (off_t) 0, hflag); if(ret <= 0) { @@ -13022,21 +13022,6 @@ 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 */ @@ -14458,7 +14443,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, was_hln_array; + int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy; 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; @@ -14467,7 +14452,6 @@ 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) @@ -14577,8 +14561,6 @@ 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); } @@ -15022,10 +15004,9 @@ 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, was_hln_array; + int ret; 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"); @@ -15070,8 +15051,6 @@ 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); } @@ -15721,38 +15700,59 @@ int Xorriso_option_grow_blindly(struct XorrisO *xorriso, char *msc2, int flag) int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag) { int ret; + char what_data[SfileadrL], *what, *what_next; - if(strcmp(mode, "off") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - xorriso->ino_behavior|= 1 | 2 | 4; - xorriso->ino_behavior&= ~8; - } else if(strcmp(mode, "on") == 0) { - xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); - } else if(strcmp(mode, "without_update") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - xorriso->ino_behavior&= ~(1 | 2 | 4); - xorriso->ino_behavior|= 8; - } else if(strcmp(mode, "start_update") == 0) { - xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); - ret= Xorriso_make_di_array(xorriso, 1); - if(ret <= 0) - return(ret); - } else if(strcmp(mode, "end_update") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - } else if(strcmp(mode, "perform_update") == 0) { - Xorriso_finish_hl_update(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); + if(Sfile_str(what_data, mode, 0)<=0) { + sprintf(xorriso->info_text, + "-hardlinks: mode string is much too long (%d)", + (int) strlen(mode)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); + } + for(what= what_data; what != NULL; what= what_next) { + what_next= strchr(what, ':'); + if(what_next != NULL) { + *what_next= 0; + what_next++; + } + if(strcmp(what, "off") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + xorriso->ino_behavior|= 1 | 2 | 4; + xorriso->ino_behavior&= ~8; + } else if(strcmp(what, "on") == 0) { + xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); + } else if(strcmp(what, "without_update") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + xorriso->ino_behavior&= ~(1 | 2 | 4); + xorriso->ino_behavior|= 8; + } else if(strcmp(what, "start_update") == 0) { + xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); + ret= Xorriso_make_di_array(xorriso, 1); + if(ret <= 0) + return(ret); + } else if(strcmp(what, "end_update") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + } else if(strcmp(what, "perform_update") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + } else if(strcmp(what, "start_extract") == 0) { + xorriso->ino_behavior&= ~(1 | 2 | 4); + ret= Xorriso_make_hln_array(xorriso, 1); + if(ret <= 0) + return(ret); + } else if(strcmp(what, "end_extract") == 0) { + Xorriso_destroy_hln_array(xorriso, 0); + } else if(strcmp(what, "discard_extract") == 0) { + Xorriso_destroy_hln_array(xorriso, 0); + } else if(strcmp(what, "normal_extract") == 0) { + xorriso->ino_behavior&= ~16; + } else if(strcmp(what, "cheap_sorted_extract") == 0) { + xorriso->ino_behavior|= 16; + } else { + sprintf(xorriso->info_text, "-hardlinks: unknown mode '%s' in '%s'", + what, mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } } if(xorriso->ino_behavior & 2) Xorriso_option_compliance(xorriso, "new_rr", 0); @@ -15810,12 +15810,11 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " Like -charset but only for conversion to media.", " -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,", -" resp. prepare for -update_r, resp. release prepared memory,", -" resp. disable hardlink detection with -update_r, resp.", -" prepare for -extract, resp. release prepared memory.", +" -hardlinks mode[:mode ...]", +" Enable resp. disable recording and restoring of hard links.", +" Modes are \"on\", \"off\", \"perform_update\",", +" \"without_update\", \"discard_extract\",", +" \"cheap_sorted_extract\", \"normal_extract\"", " -acl \"on\"|\"off\"", " Enable resp. disable reading and writing of ACLs.", " -xattr \"on\"|\"off\"", @@ -16702,7 +16701,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, made_hln_array= 0; + int ret, end_idx, optc= 0, was_failure= 1, i, fret, mode; 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; @@ -16758,14 +16757,6 @@ 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)) { @@ -16853,15 +16844,6 @@ ex:; i= optc; Sfile_destroy_argv(&i, &eff_tgt_array, 0); (*idx)= end_idx; - -#ifdef NIX - /* <<< */ - if(made_di_array) - Xorriso_finish_hl_update(xorriso, 0); -#endif - - 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); @@ -18770,15 +18752,6 @@ report_outcome:; Xorriso_info(xorriso,0); ex:; - -#ifdef NIX - /* <<< */ - if(made_di_array) { - /* Dispose all-image node array sorted by isofs.di */ - Xorriso_finish_hl_update(xorriso, 0); - } -#endif - if(ret < 0) return(ret); return(1); diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 144db23c..f7ddc32f 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -106,6 +106,8 @@ struct XorrisO { /* the global context of xorriso */ Do not consolidate suitable nodes to hardlinks. bit3= with update: Do not try to detect hardlink splits and joinings. + bit4= with extract: + Do not automatically create hln arrays */ int do_joliet; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 8043da1f..44f1cf15 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.06.25.125048" +#define Xorriso_timestamP "2009.06.27.112408" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index ac027628..8f732493 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -3927,17 +3927,24 @@ int Xorriso_restore_overwrite(struct XorrisO *xorriso, /* @param flag bit0= do not accept hln_targets[i] != NULL as *node_idx bit1= use *node_idx as found index rather than searching it + bit2= with bit1: use xorriso->node_array rather than hln_array */ int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, int *node_idx, int *min_hl, int *max_hl, int flag) { - int idx, ret, i; - void *np; + int idx, ret, i, node_count; + void *np, **node_array; + node_array= xorriso->hln_array; + node_count= xorriso->hln_count; *min_hl= *max_hl= -1; np= node; if(flag & 2) { idx= *node_idx; + if(flag & 4) { + node_array= xorriso->node_array; + node_count= xorriso->node_counter; + } } else { *node_idx= -1; ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0); @@ -3945,11 +3952,11 @@ int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, return(ret); } for(i= idx - 1; i >= 0 ; i--) - if(Xorriso__findi_sorted_ino_cmp(&(xorriso->hln_array[i]), &np) != 0) + if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0) break; *min_hl= i + 1; - for(i= idx + 1; i < xorriso->hln_count; i++) - if(Xorriso__findi_sorted_ino_cmp(&(xorriso->hln_array[i]), &np) != 0) + for(i= idx + 1; i < node_count; i++) + if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0) break; *max_hl= i - 1; @@ -3957,8 +3964,8 @@ int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, if(flag & 2) return(1); for(i= *min_hl; i <= *max_hl; i++) - if(xorriso->hln_array[i] == np) { - if((flag & 1) && xorriso->hln_targets != NULL) + if(node_array[i] == np) { + if((flag & 1) && xorriso->hln_targets != NULL && !(flag & 4)) if(xorriso->hln_targets[i] != NULL) continue; *node_idx= i; @@ -3994,7 +4001,7 @@ int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node, } link_sibling= 1; ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path, - 0); + !!xorriso->do_auto_chmod); if(ret > 0) return(1); } @@ -4015,7 +4022,7 @@ int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node, struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL; ret= Xorriso_search_hardlinks(xorriso, node, &node_idx, &min_hl, &max_hl, - 1 | 2); + 2 | 4); if(ret < 0) return(ret); if(ret == 0 || min_hl == max_hl) @@ -4042,7 +4049,8 @@ int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node, img_path, old_path, hflag); if(ret <= 0) return(ret); - ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path, 1); + ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path, + !!xorriso->do_auto_chmod); if(ret > 0) return(1); } @@ -4168,10 +4176,10 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso, img_path_pt= img_path; - if(!((xorriso->ino_behavior & 4) || (flag & (1 || 16)) || - LIBISO_ISDIR(node))) { + if(!((xorriso->ino_behavior & 4) || (flag & (1 | 16)) || LIBISO_ISDIR(node))){ /* Try to restore as hardlink */ - ret= Xorriso_restore_target_hl(xorriso, node, disk_path, &node_idx, 0); + ret= Xorriso_restore_target_hl(xorriso, node, disk_path, &node_idx, + !!xorriso->do_auto_chmod); if(ret < 0) { goto ex; } else if(ret & 1) { @@ -4823,8 +4831,10 @@ int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag) &stbuf_ret, 64); if(ret<=0 || ret==3) goto was_problem; - - if(i > 0 && !(xorriso->ino_behavior & 4)) { + if(xorriso->hln_array != NULL && !(xorriso->ino_behavior & 16)) { + /* Eventual lookup of hardlinks will be done in + Xorriso_restore_disk_object() */; + } else if(i > 0 && !(xorriso->ino_behavior & 4)) { if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i-1]), &(xorriso->node_array[i])) == 0) { if(faulty_family) { @@ -4853,7 +4863,8 @@ int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag) } ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, - (off_t) 0, (off_t) 0, 4 | 128); + (off_t) 0, (off_t) 0, + 4 | (xorriso->ino_behavior & 16) | 128); if(ret<=0) goto was_problem; if(ret == 4) { @@ -4862,7 +4873,7 @@ int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag) if(ret < 0) goto ex; ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, - (off_t) 0, (off_t) 0, 4); + (off_t) 0, (off_t) 0, 4 | (xorriso->ino_behavior & 16)); if(ret<=0) goto was_problem; Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);