Wider scope of hardlink reconstruction with extract operations

This commit is contained in:
Thomas Schmitt 2009-06-20 06:38:36 +00:00
parent 4d266bc2f5
commit 40e0333edb
4 changed files with 219 additions and 77 deletions

View File

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

View File

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

View File

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

View File

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