With -extract : made hardlink registration combinable with sort_lba

master
Thomas Schmitt 14 years ago
parent 9a96d6a175
commit e21150e227
  1. 19
      xorriso/xorriso.1
  2. 177
      xorriso/xorriso.c
  3. 2
      xorriso/xorriso_private.h
  4. 2
      xorriso/xorriso_timestamp.h
  5. 45
      xorriso/xorrisoburn.c

@ -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

@ -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);

@ -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;

@ -1 +1 @@
#define Xorriso_timestamP "2009.06.25.125048"
#define Xorriso_timestamP "2009.06.27.112408"

@ -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);

Loading…
Cancel
Save