Gave up risky direct update of hardlink siblings

This commit is contained in:
Thomas Schmitt 2009-06-22 11:28:34 +00:00
parent 40e0333edb
commit 67d7e8821b
6 changed files with 276 additions and 93 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "May 29, 2009" .TH XORRISO 1 "Jun 22, 2009"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -42,7 +42,9 @@ incorporates the libraries of libburnia-project.org .
.br .br
Operates on an existing ISO image or creates a new one. Operates on an existing ISO image or creates a new one.
.br .br
Copies files from filesystem into the ISO image. Copies files from disk filesystem into the ISO image.
.br
Copies files from ISO image to disk filesystem (see osirrox).
.br .br
Renames or deletes file objects in the ISO image. Renames or deletes file objects in the ISO image.
.br .br
@ -57,9 +59,7 @@ Can activate ISOLINUX boot images via El Torito.
.br .br
Can perform multi-session tasks as emulation of mkisofs and cdrecord. Can perform multi-session tasks as emulation of mkisofs and cdrecord.
.br .br
Can restore files from ISO image to disk filesystem (see osirrox). Can record and restore hard links and ACL.
.br
Can record and restore ACL of disk files.
.br .br
Content may get zisofs compressed or filtered by external processes. Content may get zisofs compressed or filtered by external processes.
.br .br
@ -668,7 +668,7 @@ terminal where xorriso runs. Before attributing this local character set
to the produced ISO image, check whether the terminal properly displays to the produced ISO image, check whether the terminal properly displays
all intended filenames, especially exotic national characters. all intended filenames, especially exotic national characters.
.TP .TP
\fB\-hardlinks\fR "on"|"off"|"without_update"|"start_update"|"end_update" \fB\-hardlinks\fR "on"|"off"|"without_update"|"start_update"|"end_update" |"start_extract"|"end_extract"
Enable or disable loading and recording of hardlink relations. Enable or disable loading and recording of hardlink relations.
.br .br
In default mode "off", iso_rr files lose their inode numbers at image load In default mode "off", iso_rr files lose their inode numbers at image load
@ -690,10 +690,15 @@ and -hardlinks "end_update". This avoids multiple sorting of ISO image nodes.
Mode "without_update" avoids hardlink processing during update commands. Mode "without_update" avoids hardlink processing during update commands.
.br .br
xorriso commands which extract files from an ISO image try to hardlink files xorriso commands which extract files from an ISO image try to hardlink files
with identical inode number. This applies only to files which with identical inode number. Normally this applies only to files which
get extracted during execution of that same command. A large number of get extracted during execution of that same command. One may surround a group
hardlink families may exhaust -temp_mem_limit if not -osirrox option of extraction commands by -hardlinks "start_extract" and
"sort_lba_on" is in effect. -hardlinks "end_extract" to allow hard linking among their extracted files.
-osirrox "sort_lba_on" and -hardlinks "start_extract" mutually disable
each other.
.br
A large number of hardlink families may exhaust -temp_mem_limit
if not -osirrox option "sort_lba_on" is in effect.
.br .br
Hardlink processing automatically enables \fB\-compliance new_rr\fR. Hardlink processing automatically enables \fB\-compliance new_rr\fR.
This may be overridden by a following -compliance old_rr . In this case This may be overridden by a following -compliance old_rr . In this case

View File

@ -5398,6 +5398,9 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->hln_count= 0; m->hln_count= 0;
m->hln_array= NULL; m->hln_array= NULL;
m->hln_targets= NULL; m->hln_targets= NULL;
m->di_do_widen= NULL;
m->di_disk_paths= NULL;
m->di_iso_paths= NULL;
m->node_targets_availmem= 0; m->node_targets_availmem= 0;
@ -8351,6 +8354,28 @@ ex:;
} }
int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path,
char *iso_prefix, char *disk_prefix,
char disk_path[SfileadrL], int flag)
{
int ret;
char adrc[SfileadrL];
if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0)
return(-1);
if(strlen(disk_prefix) + strlen(iso_path) - strlen(iso_prefix)+1 >= SfileadrL)
return(-1);
if(iso_path[strlen(iso_prefix)] == '/')
strcpy(adrc, iso_path + strlen(iso_prefix) + 1);
else
strcpy(adrc, iso_path + strlen(iso_prefix));
ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4 | 8);
if(ret <= 0)
return(ret);
return(1);
}
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image /* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world Set to NULL if calling this function from outside ISO world
@param flag bit0= update rather than compare @param flag bit0= update rather than compare
@ -8363,19 +8388,11 @@ int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
int flag) int flag)
{ {
int ret, result, uret, follow_links, deleted= 0; int ret, result, uret, follow_links, deleted= 0;
char disk_path[SfileadrL], adrc[SfileadrL]; char disk_path[SfileadrL];
if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0) ret= Xorriso_pfx_disk_path(xorriso, iso_path, iso_prefix, disk_prefix,
return(-1); disk_path, 0);
if(strlen(disk_prefix)+strlen(iso_path)-strlen(iso_prefix)+1>=SfileadrL) if(ret <= 0)
return(-1);
if(iso_path[strlen(iso_prefix)]=='/')
strcpy(adrc, iso_path+strlen(iso_prefix)+1);
else
strcpy(adrc, iso_path+strlen(iso_prefix));
ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4|8);
if(ret<=0)
return(ret); return(ret);
/* compare exclusions against disk_path resp. leaf name */ /* compare exclusions against disk_path resp. leaf name */
@ -8390,7 +8407,7 @@ int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
follow_links= (xorriso->do_follow_links || follow_links= (xorriso->do_follow_links ||
(xorriso->do_follow_param && !(flag&2))) <<28; (xorriso->do_follow_param && !(flag&2))) <<28;
ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, adrc, &result, ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, "", &result,
2 | follow_links | ((!(flag&2))<<27) | ((flag&1)<<31)); 2 | follow_links | ((!(flag&2))<<27) | ((flag&1)<<31));
/* was once: | ((!(flag&1))<<29) */ /* was once: | ((!(flag&1))<<29) */
if(ret<xorriso->find_compare_result) if(ret<xorriso->find_compare_result)
@ -15359,13 +15376,16 @@ not_enough_exec_arguments:;
Findjob_set_action_subjob(job, 13, new_job, 0); Findjob_set_action_subjob(job, 13, new_job, 0);
job= new_job; job= new_job;
} else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0) { } else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0 ||
strcmp(cpt, "widen_hardlinks")==0) {
if(i+1>=end_idx) if(i+1>=end_idx)
goto not_enough_exec_arguments; goto not_enough_exec_arguments;
i++; i++;
action= 14; action= 14;
if(strcmp(cpt, "update")==0) if(strcmp(cpt, "update")==0)
action= 17; action= 17;
if(strcmp(cpt, "widen_hardlinks")==0)
action= 32;
ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, argv[i], ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, argv[i],
other_path_start, 1|2|4|8); other_path_start, 1|2|4|8);
if(ret<=0) if(ret<=0)
@ -15689,14 +15709,14 @@ int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag)
} else if(strcmp(mode, "without_update") == 0) { } else if(strcmp(mode, "without_update") == 0) {
xorriso->ino_behavior&= ~(1 | 2 | 4); xorriso->ino_behavior&= ~(1 | 2 | 4);
xorriso->ino_behavior|= 8; xorriso->ino_behavior|= 8;
Xorriso_destroy_di_array(xorriso, 0); Xorriso_finish_hl_update(xorriso, 0);
} else if(strcmp(mode, "start_update") == 0) { } else if(strcmp(mode, "start_update") == 0) {
xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); xorriso->ino_behavior&= ~(1 | 2 | 4 | 8);
ret= Xorriso_make_di_array(xorriso, 1); ret= Xorriso_make_di_array(xorriso, 1);
if(ret <= 0) if(ret <= 0)
return(ret); return(ret);
} else if(strcmp(mode, "end_update") == 0) { } else if(strcmp(mode, "end_update") == 0) {
Xorriso_destroy_di_array(xorriso, 0); Xorriso_finish_hl_update(xorriso, 0);
} else if(strcmp(mode, "start_extract") == 0) { } else if(strcmp(mode, "start_extract") == 0) {
xorriso->do_restore_sort_lba= 0; xorriso->do_restore_sort_lba= 0;
xorriso->ino_behavior&= ~(1 | 2 | 4); xorriso->ino_behavior&= ~(1 | 2 | 4);
@ -16810,7 +16830,7 @@ ex:;
Sfile_destroy_argv(&i, &eff_tgt_array, 0); Sfile_destroy_argv(&i, &eff_tgt_array, 0);
(*idx)= end_idx; (*idx)= end_idx;
if(made_di_array) if(made_di_array)
Xorriso_destroy_di_array(xorriso, 0); Xorriso_finish_hl_update(xorriso, 0);
if(made_hln_array) if(made_hln_array)
Xorriso_destroy_hln_array(xorriso, 0); Xorriso_destroy_hln_array(xorriso, 0);
Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256); Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256);
@ -18558,7 +18578,7 @@ int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag)
int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path, int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path,
char *iso_path, int flag) char *iso_path, int flag)
{ {
int ret, mem_pci, zero= 0, result, uret, follow_links; int ret, mem_pci, zero= 0, result, uret, follow_links, do_register= 1;
int not_in_iso= 0, not_on_disk= 0, made_di_array= 0; int not_in_iso= 0, not_on_disk= 0, made_di_array= 0;
double mem_lut= 0.0, start_time; double mem_lut= 0.0, start_time;
char *ipth, *argv[6], sfe[5*SfileadrL]; char *ipth, *argv[6], sfe[5*SfileadrL];
@ -18605,13 +18625,33 @@ int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path,
if(ret!=0) if(ret!=0)
goto report_outcome; goto report_outcome;
if(!((xorriso->ino_behavior & 2) || (flag & 16) || if(!(xorriso->ino_behavior & 2)) {
xorriso->di_array != NULL)) { if(!(xorriso->di_array != NULL || (flag & 16))) {
/* Create all-image node array sorted by isofs.di */ /* Create all-image node array sorted by isofs.di */
made_di_array= 1; made_di_array= 1;
ret= Xorriso_make_di_array(xorriso, 0); ret= Xorriso_make_di_array(xorriso, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
}
if(xorriso->di_array != NULL) {
if(!(flag & 8)) {
/* If directory with -update : do not register di_*_paths */
ret= lstat(eff_origin, &stbuf);
if(ret != -1)
if(S_ISDIR(stbuf.st_mode))
do_register= 0;
}
if(do_register) {
ret= Xorriso_lst_append_binary(&(xorriso->di_disk_paths), eff_origin,
strlen(eff_origin) + 1, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_lst_append_binary(&(xorriso->di_iso_paths), eff_dest,
strlen(eff_dest) + 1, 0);
if(ret <= 0)
goto ex;
}
}
} }
if(flag&8) { if(flag&8) {
@ -18703,7 +18743,7 @@ report_outcome:;
ex:; ex:;
if(made_di_array) { if(made_di_array) {
/* Dispose all-image node array sorted by isofs.di */ /* Dispose all-image node array sorted by isofs.di */
Xorriso_destroy_di_array(xorriso, 0); Xorriso_finish_hl_update(xorriso, 0);
} }
if(ret < 0) if(ret < 0)
return(ret); return(ret);

View File

@ -391,18 +391,31 @@ struct XorrisO { /* the global context of xorriso */
int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */ int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */
/* LBA sorting and hardlink matching facility */ /* Tree node collection and LBA sorting facility */
int node_counter; int node_counter;
int node_array_size; int node_array_size;
void **node_array; void **node_array;
char **node_targets; /* Memorizes eventual hardlink target paths */
off_t node_targets_availmem;
struct Xorriso_lsT *node_disk_prefixes; struct Xorriso_lsT *node_disk_prefixes;
struct Xorriso_lsT *node_img_prefixes; struct Xorriso_lsT *node_img_prefixes;
/* Array of all nodes in the tree, sorted by disk dev,ino */ /* Hardlink matching at restore time memorizes hardlink target paths.
Array of nodes sorted by LBA. */
int hln_count;
void **hln_array;
void **hln_targets;
/* >>> this should count all temp_mem and thus change its name */
off_t node_targets_availmem;
/* Hardlink matching at update time:
Array of all nodes in the tree, sorted by disk dev,ino.
Bitmap of nodes which possibly got new hardlink siblings.
List of involved disk-iso path pairs. */
int di_count; int di_count;
void **di_array; void **di_array;
char *di_do_widen;
struct Xorriso_lsT *di_disk_paths;
struct Xorriso_lsT *di_iso_paths;
struct PermiteM *perm_stack; /* Temporarily altered dir access permissions */ struct PermiteM *perm_stack; /* Temporarily altered dir access permissions */
@ -518,6 +531,10 @@ int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done,
off_t count, off_t todo, char *current_object, off_t count, off_t todo, char *current_object,
int flag); int flag);
int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path,
char *iso_prefix, char *disk_prefix,
char disk_path[SfileadrL], int flag);
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image /* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world Set to NULL if calling this function from outside ISO world
@param flag bit0= update rather than compare @param flag bit0= update rather than compare
@ -918,6 +935,7 @@ struct FindjoB {
29= show_stream 29= show_stream
30= internal: count by xorriso->node_counter 30= internal: count by xorriso->node_counter
31= internal: register in xorriso->node_array 31= internal: register in xorriso->node_array
32= internal: widen_hardlinks disk_equiv: update nodes marked in di_do_widen
*/ */
int action; int action;
int prune; int prune;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2009.06.20.063853" #define Xorriso_timestamP "2009.06.22.112850"

View File

@ -187,6 +187,12 @@ int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag)
free(xorriso->di_array); free(xorriso->di_array);
xorriso->di_array= NULL; xorriso->di_array= NULL;
} }
if(xorriso->di_do_widen != NULL) {
free(xorriso->di_do_widen);
xorriso->di_do_widen= NULL;
}
Xorriso_lst_destroy_all(&(xorriso->di_disk_paths), 0);
Xorriso_lst_destroy_all(&(xorriso->di_iso_paths), 0);
xorriso->di_count= 0; xorriso->di_count= 0;
#ifdef NIX #ifdef NIX
@ -253,8 +259,8 @@ int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag)
xorriso->node_targets_availmem= mem_limit xorriso->node_targets_availmem= mem_limit
- xorriso->hln_count * sizeof(void *) - xorriso->hln_count * sizeof(void *)
- xorriso->hln_count * sizeof(char *); - xorriso->hln_count * sizeof(char *);
if(xorriso->node_targets_availmem < 0) if(xorriso->node_targets_availmem < 0)
xorriso->node_targets_availmem= 0; xorriso->node_targets_availmem= 0;
return(1); return(1);
} }
@ -471,6 +477,46 @@ int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
} }
/* @param flag bit0= return 1 even if matching nodes were found but node is
not among them
bit1= use Xorriso__di_cmp() rather than Xorriso__di_ino_cmp()
*/
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
int *idx, int *low, int *high, int flag)
{
int ret, i, found;
int (*cmp)(const void *p1, const void *p2)= Xorriso__di_ino_cmp;
if(flag & 2)
cmp= Xorriso__di_cmp;
*high= *low= *idx= -1;
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
cmp, node, &found, 0);
if(ret <= 0)
return(0);
*low= *high= found;
for(i= found + 1; i < xorriso->di_count; i++)
if(xorriso->di_array[i] != NULL) {
if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
break;
*high= i;
}
for(i= found - 1; i >= 0; i--)
if(xorriso->di_array[i] != NULL) {
if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
break;
*low= i;
}
for(i= *low; i <= *high; i++)
if(xorriso->di_array[i] == node) {
*idx= i;
break;
}
return(*idx >= 0 || (flag & 1));
}
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
@ -606,6 +652,7 @@ int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag)
xorriso->in_volset_handle= NULL; xorriso->in_volset_handle= NULL;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
Xorriso_destroy_di_array(xorriso, 0); Xorriso_destroy_di_array(xorriso, 0);
Xorriso_destroy_hln_array(xorriso, 0);
} }
if(flag&1) { if(flag&1) {
if(xorriso->libs_are_started==0) if(xorriso->libs_are_started==0)
@ -764,6 +811,7 @@ int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag)
xorriso->in_volset_handle= NULL; xorriso->in_volset_handle= NULL;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
Xorriso_destroy_di_array(xorriso, 0); Xorriso_destroy_di_array(xorriso, 0);
Xorriso_destroy_hln_array(xorriso, 0);
xorriso->loaded_volid[0]= 0; xorriso->loaded_volid[0]= 0;
xorriso->volset_change_pending= 0; xorriso->volset_change_pending= 0;
xorriso->no_volset_present= 0; xorriso->no_volset_present= 0;
@ -1041,6 +1089,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
iso_image_unref((IsoImage *) xorriso->in_volset_handle); iso_image_unref((IsoImage *) xorriso->in_volset_handle);
xorriso->in_volset_handle= NULL; xorriso->in_volset_handle= NULL;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
Xorriso_destroy_hln_array(xorriso, 0);
Xorriso_destroy_di_array(xorriso, 0); Xorriso_destroy_di_array(xorriso, 0);
/* check for invalid state */ /* check for invalid state */
@ -1233,6 +1282,7 @@ int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag)
xorriso->in_volset_handle= NULL; xorriso->in_volset_handle= NULL;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
Xorriso_destroy_di_array(xorriso, 0); Xorriso_destroy_di_array(xorriso, 0);
Xorriso_destroy_hln_array(xorriso, 0);
xorriso->loaded_volid[0]= 0; xorriso->loaded_volid[0]= 0;
xorriso->isofs_st_out= time(0) - 1; xorriso->isofs_st_out= time(0) - 1;
xorriso->isofs_st_in= 0; xorriso->isofs_st_in= 0;
@ -1505,6 +1555,10 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
int profile_number; int profile_number;
char profile_name[80]; char profile_name[80];
ret= Xorriso_finish_hl_update(xorriso, 0);
if(ret <= 0)
return(ret);
out_cs= xorriso->out_charset; out_cs= xorriso->out_charset;
if(out_cs == NULL) if(out_cs == NULL)
Xorriso_get_local_charset(xorriso, &out_cs, 0); Xorriso_get_local_charset(xorriso, &out_cs, 0);
@ -7373,6 +7427,46 @@ int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path,
} }
int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter,
IsoNode *node,
char *abs_path, char *iso_prefix, char *disk_prefix,
int flag)
{
int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0;
char disk_path[SfileadrL];
/* Lookup all di_array instances of node */
if(LIBISO_ISDIR(node))
return(1);
ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2);
if(ret <= 0)
return(1);
/* Check and reset di_do_widen bits */
for(i= low; i <= high; i++) {
if(node != xorriso->di_array[i]) /* might be NULL */
continue;
if(xorriso->di_do_widen[i / 8] & (1 << (i % 8)))
do_widen= 1;
xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8));
}
if(idx < 0 || !do_widen)
return(1);
ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix,
disk_path, 0);
if(ret <= 0)
return(ret);
/* >>> compare_result bit17 = is_split */;
ret= Xorriso_update_interpreter(xorriso, boss_iter, compare_result, disk_path,
abs_path, 1);
if(ret <= 0)
return(ret);
return 1;
}
/* @param flag bit0= not a command parameter (directory iteration or recursion) /* @param flag bit0= not a command parameter (directory iteration or recursion)
bit1= do not count deleted files with rm and rm_r bit1= do not count deleted files with rm and rm_r
@return <=0 error, @return <=0 error,
@ -7470,6 +7564,11 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
iso_node_ref(node); /* In case node gets deleted from tree during iso_node_ref(node); /* In case node gets deleted from tree during
the lifetime of xorriso->node_array */ the lifetime of xorriso->node_array */
} }
} else if(action == 32) { /* internal: widen_hardlinks disk_equiv */
Findjob_get_start_path(job, &iso_prefix, 0);
ret= Xorriso_widen_hardlink(xorriso, (void *) boss_iter, node, abs_path,
iso_prefix, target, 0);
} else { /* includes : 15 in_iso */ } else { /* includes : 15 in_iso */
sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0));
Xorriso_result(xorriso, 0); Xorriso_result(xorriso, 0);
@ -7926,7 +8025,8 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
mem= boss_mem; mem= boss_mem;
hflag= 1; hflag= 1;
if(action==1 || action==2 || action==3 || action==17 || action == 28) if(action==1 || action==2 || action==3 || action==17 || action == 28 ||
action == 32)
hflag|= 2; /* need freedom to manipulate image */ hflag|= 2; /* need freedom to manipulate image */
if(action==14 || action==17 || action == 28) if(action==14 || action==17 || action == 28)
hflag|= 4; /* need LBA sorted iteration for good data reading performance */ hflag|= 4; /* need LBA sorted iteration for good data reading performance */
@ -11689,6 +11789,7 @@ int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag)
ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1); ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
if(ret<=0) if(ret<=0)
goto ex; goto ex;
xorriso->node_targets_availmem= xorriso->temp_mem_limit;
ret= 1; ret= 1;
ex:; ex:;
@ -11701,7 +11802,7 @@ ex:;
*/ */
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag) int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
{ {
int ret; int ret, bytes;
#ifdef NIX #ifdef NIX
/* <<< */ /* <<< */
@ -11713,11 +11814,17 @@ int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
return(2); return(2);
if(xorriso->di_array != NULL && !(flag & 1)) if(xorriso->di_array != NULL && !(flag & 1))
return(2); return(2);
Xorriso_destroy_di_array(xorriso, 0); Xorriso_finish_hl_update(xorriso, 0);
ret= Xorriso_all_node_array(xorriso, 0); ret= Xorriso_all_node_array(xorriso, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
bytes= xorriso->node_array_size / 8 + 1;
xorriso->di_do_widen= calloc(bytes, 1);
if(xorriso->di_do_widen == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
/* Transfer node_array to di_array without unrefering nodes */ /* Transfer node_array to di_array without unrefering nodes */
xorriso->di_count= xorriso->node_counter; xorriso->di_count= xorriso->node_counter;
@ -11741,41 +11848,6 @@ ex:;
} }
/* @param flag bit0= return 1 even if matching nodes were found but node is
not among them
*/
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
int *idx, int *low, int *high, int flag)
{
int ret, i, found;
*high= *low= *idx= -1;
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
Xorriso__di_ino_cmp, node, &found, 0);
if(ret <= 0)
return(0);
*low= *high= found;
for(i= found + 1; i < xorriso->di_count; i++)
if(xorriso->di_array[i] != NULL) {
if(Xorriso__di_ino_cmp(&node, &(xorriso->di_array[i])) != 0)
break;
*high= i;
}
for(i= found - 1; i >= 0; i--)
if(xorriso->di_array[i] != NULL) {
if(Xorriso__di_ino_cmp(&node, &(xorriso->di_array[i])) != 0)
break;
*low= i;
}
for(i= *low; i <= *high; i++)
if(xorriso->di_array[i] == node) {
*idx= i;
break;
}
return(*idx >= 0 || (flag & 1));
}
/* /*
@param flag bit0= iso_rr_path is freshly added and up to date @param flag bit0= iso_rr_path is freshly added and up to date
bit2= -follow: this is not a command parameter bit2= -follow: this is not a command parameter
@ -11788,13 +11860,18 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
char *disk_path, char *iso_rr_path, int flag) char *disk_path, char *iso_rr_path, int flag)
{ {
int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0; int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0;
int follow_links, node_result, old_idx= -1; int follow_links, old_idx= -1;
char node_path[SfileadrL];
IsoNode *node; IsoNode *node;
struct stat stbuf; struct stat stbuf;
dev_t old_dev; dev_t old_dev;
ino_t old_ino; ino_t old_ino;
#ifdef Xorriso_hardlink_update_direcT
/* <<< */
int node_result;
char node_path[SfileadrL];
#endif
if(xorriso->di_array == NULL) if(xorriso->di_array == NULL)
return(1); return(1);
follow_links= xorriso->do_follow_links || follow_links= xorriso->do_follow_links ||
@ -11862,7 +11939,7 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
{ret= 0; goto ex;} {ret= 0; goto ex;}
#ifdef NIX #ifdef Xorriso_hardlink_update_debuG
/* <<< */ /* <<< */
if(low < high || idx < 0) { if(low < high || idx < 0) {
fprintf(stderr, fprintf(stderr,
@ -11876,20 +11953,14 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
if(idx >= 0 && idx != old_idx) if(idx >= 0 && idx != old_idx)
fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx); fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx);
} }
#endif /* NIX */ #endif /* Xorriso_hardlink_update_debuG */
/* Overwrite all valid siblings : */ /* Overwrite all valid siblings : */
for(i= low; i <= high; i++) { for(i= low; i <= high; i++) {
if(i == idx || xorriso->di_array[i] == NULL) if(i == idx || xorriso->di_array[i] == NULL)
continue; continue;
/* Is the alleged sibling still a valid mirror of disk_path ? */
ret= Xorriso_path_from_node(xorriso, xorriso->di_array[i], node_path, 0);
if(ret < 0)
goto ex;
if(ret == 0)
continue; /* Node is deleted from tree */
#ifdef NIX #ifdef Xorriso_hardlink_update_debuG
/* <<< */ /* <<< */
{ {
ino_t ino; ino_t ino;
@ -11899,7 +11970,17 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %lu\n", fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %lu\n",
node_path, (unsigned long) dev, (unsigned long) ino); node_path, (unsigned long) dev, (unsigned long) ino);
} }
#endif /* NIX */ #endif /* Xorriso_hardlink_update_debuG */
#ifdef Xorriso_hardlink_update_direcT
/* <<< */
/* Is the alleged sibling still a valid mirror of disk_path ? */
ret= Xorriso_path_from_node(xorriso, xorriso->di_array[i], node_path, 0);
if(ret < 0)
goto ex;
if(ret == 0)
continue; /* Node is deleted from tree */
node_result= 0; node_result= 0;
ret= Xorriso_compare_2_files(xorriso, disk_path, node_path, "", ret= Xorriso_compare_2_files(xorriso, disk_path, node_path, "",
@ -11913,6 +11994,13 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
if(ret < 0) if(ret < 0)
goto ex; goto ex;
} }
#else /* Xorriso_hardlink_update_direcT */
xorriso->di_do_widen[i / 8]|= 1 << (i % 8);
#endif /* ! Xorriso_hardlink_update_direcT */
} }
ret= 1; ret= 1;
@ -11928,3 +12016,33 @@ ex:;
return(ret); return(ret);
} }
int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag)
{
int ret, zero= 0;
char *argv[4];
struct Xorriso_lsT *disk_lst, *iso_lst;
if(xorriso->di_array == NULL)
{ret= 1; goto ex;}
disk_lst= xorriso->di_disk_paths;
iso_lst= xorriso->di_iso_paths;
while(disk_lst != 0 && iso_lst != NULL) {
argv[0]= Xorriso_lst_get_text(iso_lst, 0);
argv[1]= "-exec";
argv[2]= "widen_hardlinks";
argv[3]= Xorriso_lst_get_text(disk_lst, 0);
zero= 0;
ret= Xorriso_option_find(xorriso, 4, argv, &zero, 0); /* -findi */
if(ret < 0)
goto ex;
disk_lst= Xorriso_lst_get_next(disk_lst, 0);
iso_lst= Xorriso_lst_get_next(iso_lst, 0);
}
ret= 1;
ex:;
Xorriso_destroy_di_array(xorriso, 0);
return(ret);
}

View File

@ -482,6 +482,8 @@ int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag);
int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result, int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
char *disk_path, char *iso_rr_path, int flag); char *disk_path, char *iso_rr_path, int flag);
int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag);
/* A pseudo file type for El-Torito bootsectors as in man 2 stat : /* A pseudo file type for El-Torito bootsectors as in man 2 stat :
For now take the highest possible value. For now take the highest possible value.