From 2237469e180f1677909015f38a873e5334758eed Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 16 May 2009 16:56:21 +0000 Subject: [PATCH] LBA sorted processing of -compare_r and -update_r for smoother MMC reading --- xorriso/xorriso.c | 34 ++++++- xorriso/xorriso_private.h | 9 +- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 190 ++++++++++++++++++++++++++++++++++-- xorriso/xorrisoburn.h | 6 ++ 5 files changed, 226 insertions(+), 15 deletions(-) diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 734b87e1..3eb9f7d9 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -5378,6 +5378,11 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->start_time= 0.0; m->last_update_time= 0.0; m->find_compare_result= 1; + + m->node_counter= 0; + m->node_array_size= 0; + m->node_array= NULL; + m->perm_stack= NULL; m->result_line[0]= 0; m->result_line_counter= 0; @@ -5443,6 +5448,16 @@ int Xorriso_destroy_re(struct XorrisO *m, int flag) } +int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag) +{ + if(xorriso->node_array != NULL) + free(xorriso->node_array); + xorriso->node_array= NULL; + xorriso->node_counter= xorriso->node_array_size= 0; + return(1); +} + + /* @param flag bit0= global shutdown of libraries */ int Xorriso_destroy(struct XorrisO **xorriso, int flag) { @@ -5461,6 +5476,8 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag) Xorriso_lst_destroy_all(&(m->drive_blacklist), 0); Xorriso_lst_destroy_all(&(m->drive_greylist), 0); Xorriso_lst_destroy_all(&(m->drive_whitelist), 0); + if(m->node_array != NULL) + free(m->node_array); Xorriso_detach_libraries(m, flag&1); free((char *) m); @@ -13961,7 +13978,8 @@ int Xorriso_option_compare(struct XorrisO *xorriso, char *disk_path, argv[2]= "compare"; argv[3]= eff_origin; zero= 0; - ret= Xorriso_option_find(xorriso, 4, argv, &zero, 2); /* -findi */ + ret= Xorriso_option_find(xorriso, 4, argv, &zero, + 2 | (8 * !((xorriso->do_aaip & 96) == 96))); /* -findi */ if(ret>0) { argv[0]= eff_origin; argv[1]= "-exec"; @@ -14746,6 +14764,7 @@ ex:; bit1= do not reset pacifier, no final pacifier message do not reset find_compare_result bit2= do not count deleted files with rm and rm_r + bit3= use Xorriso_findi_sorted() rather than Xorriso_findi() */ int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) @@ -15082,7 +15101,10 @@ sorry_ex:; if(flag&1) ret= Xorriso_findx(xorriso, first_job, "", start_path, &dir_stbuf, 0, NULL, 0); - else + else if(flag & 8) { + cpt= start_path; + ret= Xorriso_findi_sorted(xorriso, first_job, 1, &cpt, 0); + } else ret= Xorriso_findi(xorriso, first_job, NULL, (off_t) 0, NULL, start_path, &dir_stbuf, 0, (flag&4)>>1); ex:; @@ -18132,7 +18154,8 @@ int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path, argv[2]= "update"; argv[3]= eff_origin; zero= 0; - ret= Xorriso_option_find(xorriso, 4, argv, &zero, 2); /* -findi */ + ret= Xorriso_option_find(xorriso, 4, argv, &zero, + 2 | (8 * !((xorriso->do_aaip & 96) == 96))); /* -findi */ } else if(ret==-2) { /* severe error (e.g. lack of image) */ ret= -1; goto report_outcome; @@ -18474,7 +18497,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri", "compare_l","cpr","cpri","cp_rax","cp_rx","cpax","cpx", "du","dui","dus","dusi","dux","dusx","external_filter","extract_l", - "file_size_limit","find","findi","findx", + "file_size_limit","find","findi","finds","findx", "getfacl","getfacli","getfacl_r","getfacl_ri", "getfattr","getfattri","getfattr_r","getfattr_ri", "ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli", @@ -18832,6 +18855,9 @@ next_command:; } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) { ret= Xorriso_option_find(xorriso, argc, argv, idx, 0); + } else if(strcmp(cmd,"find_sorted")==0) { + ret= Xorriso_option_find(xorriso, argc, argv, idx, 8); + } else if(strcmp(cmd,"findx")==0) { ret= Xorriso_option_find(xorriso, argc, argv, idx, 1); diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 528a1fcb..4968e524 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -383,6 +383,10 @@ struct XorrisO { /* the global context of xorriso */ int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */ + int node_counter; + int node_array_size; + void **node_array; + struct PermiteM *perm_stack; /* Temporarily altered dir access permissions */ /* result (stdout, R: ) */ @@ -605,6 +609,7 @@ int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path, int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp, int flag); +int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag); int Sfile_str(char target[SfileadrL], char *source, int flag); @@ -864,13 +869,15 @@ struct FindjoB { 20= is_full_in_iso iso_rr_equiv 21= report_damage 22= report_lba - 23= internal:memorize path of last matching node in found_path + 23= internal: memorize path of last matching node in found_path 24= getfacl 25= setfacl access_acl default_acl 26= getfattr 27= setfattr 28= set_filter name 29= show_stream + 30= internal: count by xorriso->node_counter + 31= internal: register in xorriso->node_array */ int action; int prune; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 6e7abacc..ef779b0e 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.05.14.082045" +#define Xorriso_timestamP "2009.05.16.165616" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index d767c96c..efc72b4c 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -91,8 +91,8 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, char *path, IsoNode **node, int flag); -int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *node, int lba, - char path[SfileadrL], int flag); +int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba, + char path[SfileadrL], int flag); #define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR) @@ -470,8 +470,8 @@ int Xorriso_record_boot_info(struct XorrisO *xorriso, int flag) Xorriso__file_start_lba((IsoNode *) bootimg_node, &(xorriso->loaded_boot_bin_lba), 0); if(bootcat_node != NULL) - Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, 0, - xorriso->loaded_boot_cat_path, 0); + Xorriso_path_from_lba(xorriso, (IsoNode *) bootcat_node, 0, + xorriso->loaded_boot_cat_path, 0); return(1); } @@ -1309,7 +1309,7 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) sprintf(xorriso->info_text, "Patching alleged isolinux boot image"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= Xorriso_path_from_node(xorriso, NULL, xorriso->loaded_boot_bin_lba, + ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba, sfe, 1); if(ret < 0) goto ex; @@ -2470,6 +2470,7 @@ cannot_lstat:; } if(node==NULL) { + if(S_ISLNK(stbuf.st_mode)) { /* ??? NG : A80107 : is this solved now ? */ @@ -2488,6 +2489,7 @@ cannot_lstat:; {ret= 0; goto was_problem;} } } else { + ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name, "", img_path, (off_t) 0, (off_t) 0, &node, 0); @@ -4194,7 +4196,7 @@ no_boot:; image= NULL; if(ret != 1) goto no_boot; - ret= Xorriso_path_from_node(xorriso, NULL, xorriso->loaded_boot_bin_lba, + ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba, path, 1); if(ret > 0) bin_path_valid= 1; @@ -6605,6 +6607,7 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, action= 0; hflag= 16*!(flag&2); + ret= 1; if(action==1) { /* rm (including rmdir) */ ret= Xorriso_fake_stbuf(xorriso, abs_path, &dir_stbuf, &node, 1); if(ret>0) { @@ -6650,7 +6653,7 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, ret= Xorriso_report_damage(xorriso, show_path, node, 0); } else if(action == 22) { ret= Xorriso_report_lba(xorriso, show_path, node, 0); - } else if(action == 23) { + } else if(action == 23) { /* internal: memorize path of last matching node */ ret= Findjob_set_found_path(job, show_path, 0); } else if(action == 24) { ret= Xorriso_getfacl(xorriso, (void *) node, show_path, NULL, 0); @@ -6666,6 +6669,11 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, ret= Xorriso_set_filter(xorriso, (void *) node, show_path, target, 1 | 2); } else if(action == 29) { /* show_stream */ ret= Xorriso_show_stream(xorriso, (void *) node, show_path, 1 | 2); + } else if(action == 30) { /* internal: count */ + xorriso->node_counter++; + } else if(action == 31) { /* internal: register */ + if(xorriso->node_counter < xorriso->node_array_size) + xorriso->node_array[xorriso->node_counter++]= (void *) node; } else { /* includes : 15 in_iso */ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -7218,10 +7226,66 @@ ex:; } +int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node, + char path[SfileadrL], int flag) +{ + int ret, i, comp_count= 0; + IsoNode *node, *parent, **components= NULL; + char *wpt, *npt; + + for(node= in_node; 1; node= parent) { + parent= (IsoNode *) iso_node_get_parent(node); + if(parent == node) + break; + comp_count++; + } + if(comp_count == 0) { + strcpy(path, "/"); + return(1); + } + components= calloc(comp_count, sizeof(IsoNode *)); + if(components == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + i= comp_count; + for(node= in_node; 1; node= parent) { + parent= (IsoNode *) iso_node_get_parent(node); + if(parent == node) + break; + components[--i]= node; + } + + wpt= path; + for(i= 0; i < comp_count; i++) { + npt= (char *) iso_node_get_name(components[i]); + if((wpt - path) + strlen(npt) + 1 >= SfileadrL) { + + /* >>> path is getting much too long */; + + ret= -1; goto ex; + } + *(wpt++)= '/'; + strcpy(wpt, npt); + wpt+= strlen(npt); + *wpt= 0; + } + ret= 1; +ex:; + if(components != NULL) + free(components); + return(ret); +} + + +/* <<< The lookup from node pointer will be done by Xorriso_path_from_node() + (Currently it runs a full tree traversal) + Parameter node and flag bit0 will vanish then +*/ /* @param flag bit0= use lba rather than node pointer */ -int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *node, int lba, - char path[SfileadrL], int flag) +int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba, + char path[SfileadrL], int flag) { int ret; struct FindjoB *job= NULL; @@ -7257,6 +7321,114 @@ int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *node, int lba, } +int Xorriso__findi_sorted_cmp(const void *p1, const void *p2) +{ + int ret; + IsoNode *n1, *n2; + + n1= *((IsoNode **) p1); + n2= *((IsoNode **) p2); + + ret= Xorriso__node_lba_cmp(&n1, &n2); + if(ret) + return (ret > 0 ? 1 : -1); + ret= iso_node_cmp_ino(n1, n2, 0); + return(ret); +} + + +/* @param flag bit0= do not dive into trees + bit1= do not perform job->action on resulting node array +*/ +int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, + int filec, char **filev, int flag) +{ + int i, ret; + struct FindjoB array_job; + struct stat dir_stbuf; + IsoNode *node; + char abs_path[SfileadrL]; + + /* <<< */ + if(job->action>=9 && job->action<=13) { /* actions which have own findjobs */ + + /* >>> cannot deal with chained find yet */; + + return(-1); + } + /* >>> if action == find : array_job would need to replace the hindmost */ + memcpy(&array_job, job, sizeof(struct FindjoB)); + + /* Count matching nodes */ + Xorriso_destroy_node_array(xorriso, 0); + array_job.action= 30; /* internal: count */ + for(i= 0; i < filec; i++) { + if(flag & 1) { + xorriso->node_counter++; + continue; + } + array_job.start_path= filev[i]; + ret= Xorriso_findi(xorriso, &array_job, NULL, (off_t) 0, NULL, + filev[i], &dir_stbuf, 0, 0); + if(ret <= 0) + goto ex; + } + if(xorriso->node_counter <= 0) + return(1); + + /* Copy matching nodes into allocated array */ + xorriso->node_array_size= xorriso->node_counter; + xorriso->node_array= calloc(xorriso->node_array_size, sizeof(IsoNode *)); + if(xorriso->node_array == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + array_job.action= 31; /* internal: register */ + xorriso->node_counter= 0; + for(i= 0; i < filec; i++) { + if(flag & 1) { + ret= Xorriso_get_node_by_path(xorriso, filev[i], NULL, &node, 0); + if(ret <= 0) + goto ex; + if(xorriso->node_counter < xorriso->node_array_size) + xorriso->node_array[xorriso->node_counter++]= (void *) node; + + continue; + } + array_job.start_path= filev[i]; + ret= Xorriso_findi(xorriso, &array_job, NULL, (off_t) 0, NULL, + filev[i], &dir_stbuf, 0, 0); + if(ret <= 0) + goto ex; + } + qsort(xorriso->node_array, xorriso->node_counter, sizeof(IsoNode *), + Xorriso__findi_sorted_cmp); + + if(flag & 2) + return(1); + + /* Perform job->action on xorriso->node_array */; + + /* >>> if action == find : perform action of the hindmost */ + + for(i= 0; i < xorriso->node_counter; i++) { + node= xorriso->node_array[i]; + ret= Xorriso_path_from_node(xorriso, node, abs_path, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi_action(xorriso, job, NULL, (off_t) 0, + abs_path, abs_path, node, 0, 1); + if(ret <= 0) + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + + ret= 1; +ex:; + return(ret); +} + + /* @param flag bit0= do not mark image as changed */ int Xorriso_set_volid(struct XorrisO *xorriso, char *volid, int flag) { diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 9b032f90..3ba4fecc 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -177,6 +177,12 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, void *dir_node_generic, char *dir_path, struct stat *dir_stbuf, int depth, int flag); +/* @param flag bit0= do not dive into trees + bit1= do not perform job->action on resulting node array +*/ +int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, + int filec, char **filev, int flag); + /* @param flag bit0= do not mark image as changed */ int Xorriso_set_volid(struct XorrisO *xorriso, char *volid, int flag);