PageTable* LongModePaging::allocate_page_directory( unsigned pml4_entry_id , unsigned pdpt_entry_id ) { PageTable* pdp_table = get_next_level_address<PageTable>( pml4 , pml4_entry_id); if( pdp_table ) { if(!is_present(pdp_table , pdpt_entry_id)) { PageTable* table_tmp= gm_memalign<PageTable>( CACHE_LINE_BYTES, 1); PageTable* pd_table = new (table_tmp) PageTable(ENTRY_512); validate_entry(pdp_table , pdpt_entry_id , pd_table); cur_pd_num++; return pd_table; } else { PageTable* table = get_next_level_address<PageTable>( pdp_table, pdpt_entry_id); return table; } } else { if(allocate_page_directory_pointer(pml4_entry_id)) { PageTable* pdpt_table = get_next_level_address<PageTable>(pml4,pml4_entry_id); PageTable* table_tmp= gm_memalign<PageTable>( CACHE_LINE_BYTES, 1); PageTable* pd_table=new (table_tmp)PageTable(ENTRY_512); validate_entry(pdpt_table , pdpt_entry_id , pd_table); cur_pd_num++; return pd_table; } } return NULL; }
/****----basic call back of Legacy-Paging----****/ PageTable* PAEPaging::allocate_page_table( unsigned pdpt_entry_id , unsigned pd_entry_id) { //only on PAE-NORMAL mode,can allocate page table assert( mode == PAE_Normal && cur_pt_num< ENTRY_512); //page directory PageTable* table = get_next_level_address<PageTable>( page_directory_pointer , pdpt_entry_id); PageTable* page=NULL; if( !table) { //page directory table = new PageTable(ENTRY_512); validate_entry( page_directory_pointer , pdpt_entry_id , table); //page table page = new PageTable(ENTRY_512); validate_entry( table, pd_entry_id ,page); cur_pt_num++; cur_pdt_num++; return page; } else { page = get_next_level_address<PageTable>(table,pd_entry_id); if( !page) { //new page table page = new PageTable(ENTRY_512); validate_entry(table , pd_entry_id, page); cur_pt_num++; } //page table already exist } return page; }
PageTable* LongModePaging::allocate_page_table(unsigned pml4_entry_id , unsigned pdpt_entry_id , unsigned pdt_entry_id) { assert( mode == LongMode_Normal); PageTable* pdp_table=get_next_level_address<PageTable>(pml4 , pml4_entry_id); if( pdp_table ) { PageTable* pd_table=get_next_level_address<PageTable>(pdp_table , pdpt_entry_id); if(pd_table) { if(is_present(pd_table , pdt_entry_id)) { PageTable* table = get_next_level_address<PageTable>(pd_table,pdt_entry_id); return table; } else { PageTable* table_tmp= gm_memalign<PageTable>( CACHE_LINE_BYTES, 1); PageTable* table = new (table_tmp)PageTable(ENTRY_512); validate_entry(pd_table , pdt_entry_id ,table ); cur_pt_num++; return table; } } //page_direcory doesn't exist allocate else { if( allocate_page_directory(pml4_entry_id,pdpt_entry_id)) { //get page directory PageTable* page_dir = get_next_level_address<PageTable>( pdp_table , pdpt_entry_id); PageTable* table= gm_memalign<PageTable>( CACHE_LINE_BYTES, 1); PageTable* pg_table=new (table)PageTable(ENTRY_512); validate_entry(page_dir , pdt_entry_id , pg_table ); cur_pt_num++; return pg_table; } } } else { PageTable* g_tables = gm_memalign<PageTable>(CACHE_LINE_BYTES,3); PageTable* pdp_table=new (&g_tables[0])PageTable(ENTRY_512); //std::cout<<"validate pg dir pointer in pml4"<<std::dec<<pml4_entry_id<<std::endl; validate_entry(pml4,pml4_entry_id,pdp_table); cur_pdp_num++; PageTable* pd_table=new (&g_tables[1])PageTable(ENTRY_512); //std::cout<<"validate page directory table in pg dir pointer"<<std::dec<<pdpt_entry_id<<std::endl; validate_entry(pdp_table,pdpt_entry_id , pd_table); cur_pd_num++; PageTable* pg_table=new (&g_tables[2])PageTable(ENTRY_512); //std::cout<<"new page table"<<std::endl; validate_entry(pd_table , pdt_entry_id , pg_table); //std::cout<<"validate: "<<std::dec<<pml4_entry_id<<","<<std::dec<<pdpt_entry_id<<","<<std::dec<<pdt_entry_id<<std::endl; cur_pt_num++; return pg_table; } return NULL; }
/*****-----functional interface of LongMode-Paging----*****/ bool LongModePaging::map_page_table(Address addr , void* pg_ptr , bool pbuffer) { //std::cout<<"map:"<<std::hex<<addr<<std::endl; unsigned pml4,pdp,pd,pt; get_domains(addr , pml4 , pdp , pd , pt , mode); unsigned buffer_entry_id = get_buffer_table_off(addr,buffer_table_shift,mode); assert( (pml4!=(unsigned)(-1)) && (pdp!=(unsigned)(-1))); PageTable* table; if( mode == LongMode_Normal) { assert( (pd!=(unsigned)(-1)) &&(pt!=(unsigned)(-1))); table = allocate_page_table(pml4,pdp,pd); if( !table ) { debug_printf("allocate page table for LongMode_Normal failed!"); return false; } if( pbuffer) { //std::cout<<"extend one buffer map"<<std::endl; extend_one_buffer_map(addr,table,pg_ptr , pt, buffer_entry_id, buffer_table_entry_num); } else { validate_entry(table , pt , pg_ptr); } } else if( mode == LongMode_Middle ) { table = allocate_page_directory( pml4 , pdp); if(!table) { debug_printf("allocate page directory for LongMode_Middle failed!"); return false; } if( pbuffer ) extend_one_buffer_map(addr , table , pg_ptr , pd , buffer_entry_id , buffer_table_entry_num); else validate_entry( table,pd, pg_ptr); } else if( mode == LongMode_Huge ) { table = allocate_page_directory_pointer(pml4); if(!table) { debug_printf("allocate page directory pointer for LongMode_Huge failed!"); return false; } if(pbuffer) extend_one_buffer_map(addr , table ,pg_ptr, pdp,buffer_entry_id , buffer_table_entry_num); else validate_entry(table,pdp,pg_ptr); } return true; }
int validate_interleaved(char *f) { unsigned long cline=1; unsigned long nreads1=0; gzFile fd1=NULL; fprintf(stderr,"Paired-end interleaved\n"); fd1=open_fastq(f); gzFile fdf=open_fixed_fastq(f); while(!gzeof(fd1)) { long start_pos=gztell(fd1); // Read 1 char *hdr1=READ_LINE_HDR(fd1); if ( hdr1==NULL) break; int len; char *seq1=READ_LINE_SEQ(fd1); char *hdr1_2=READ_LINE_HDR2(fd1); char *qual1=READ_LINE_QUAL(fd1); // Read 2 char *hdr2=READ_LINE_HDR2_1(fd1); char *seq2=READ_LINE_SEQ2(fd1); char *hdr2_2=READ_LINE_HDR2_2(fd1); char *qual2=READ_LINE_QUAL2(fd1); if ( seq1==NULL || hdr1_2==NULL || qual1==NULL || hdr2==NULL || seq2==NULL || hdr2_2==NULL || qual2==NULL ) { fprintf(stderr,"\nError in file %s, line %lu: file truncated?\n",f,cline); return(1); } if (validate_entry(hdr1,hdr1_2,seq1,qual1,cline,f)!=0) { return(1); } if (validate_entry(hdr2,hdr2_2,seq2,qual2,cline+4,f)!=0) { return(1); } char* readname1=get_readname(hdr1,&len,cline,f); char* readname2=get_readname(hdr2,&len,cline+4,f); if ( strcmp(readname1,readname2) ) { fprintf(stderr,"\nError in file %s, line %lu: unpaired read - %s\n",f,cline,readname1); return(1); } PRINT_READS_PROCESSED(cline/4); replace_dots(start_pos,seq1,hdr1,hdr1_2,qual1,fdf); replace_dots(start_pos,seq2,hdr2,hdr2_2,qual2,fdf); // cline+=8; nreads1+=2; } printf("\n"); close_fixed_fastq(fdf); gzclose(fd1); return(nreads1); }
int main(int argc, char **argv) { char fbuf[PATH_MAX+1], *fb; FILE *pwf; int c; struct passwd *pw; struct disk *entry; while ((c = getopt(argc, argv, "p:u:")) != EOF) { switch (c) { case 'u': if ((nchrg = fopen(optarg, "w")) == NULL) openerr(optarg); (void) chmod(optarg, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); break; case 'p': pfile = optarg; break; default: exit(1); } } if (pfile) { if ((pwf = fopen(pfile, "r")) == NULL) { openerr(pfile); } /* fill usglist with the user's in the passwd file */ while ((pw = fgetpwent(pwf)) != NULL) { if ((entry = hash_find(pw->pw_uid)) == NULL) entry = hash_insert(pw->pw_uid); validate_entry(entry, pw); } (void) fclose(pwf); } /* charge the files listed in names to users listed in the usglist */ while (fgets(fbuf, sizeof (fbuf), stdin) != NULL) { if ((fb = strchr(fbuf, '\n')) != NULL) { /* * replace the newline char at the end of the * filename with a null character */ *fb = '\0'; } charge(fbuf); } output(); if (nchrg) (void) fclose(nchrg); #ifdef DEBUG pdisk(); #endif return (0); }
/*****-----functional interface of Legacy-Paging----*****/ bool NormalPaging::map_page_table(Address addr ,void* pg_ptr , bool is_buffer) { if( is_buffer ) debug_printf("map address:(%x,%x)",addr); //update page table unsigned pd_entry_id = get_page_directory_off( addr , mode ); unsigned buffer_entry_id = get_buffer_table_off(addr,buffer_table_shift,mode); //4KB small pages if( mode == Legacy_Normal ) { unsigned pt_entry_id = get_pagetable_off(addr , mode); PageTable* table = allocate_one_pagetable( pd_entry_id ); if( !table ) { return false; } if( is_buffer) { //main memory block size is equal to buffer block size extend_one_buffer_map(addr,table,pg_ptr , pt_entry_id ,buffer_entry_id, buffer_table_entry_num); } else { //debug_printf("validate entry %d",pt_entry_id); validate_entry(table , pt_entry_id , pg_ptr , false); } } //4MB Huge pages else if( mode == Legacy_Huge) { if( is_buffer) { extend_one_buffer_map(addr ,page_directory,pg_ptr,pd_entry_id ,buffer_entry_id, buffer_table_entry_num); } else { //std::cout<<"validate "<<pd_entry_id<<std::endl; validate_entry(page_directory,pd_entry_id, pg_ptr, false); //std::cout<<"validate "<<pd_entry_id<<" end"<<std::endl; } } return true; }
static void charge(char *n) { struct stat statb; struct disk *entry; struct passwd *pw; if (lstat(n, &statb) == -1) return; /* * do not count the duplicate entries. */ if (statb.st_nlink > 1) { switch (add_tnode(&tree, statb.st_dev, statb.st_ino)) { case 0: /* already exist */ return; case 1: /* added */ break; default: perror("acctdusg"); exit(1); } } /* * st_blocks is not defined for character/block special files. */ if (S_ISCHR(statb.st_mode) || S_ISBLK(statb.st_mode)) statb.st_blocks = 0; /* * If -p is given, we've all loaded the passwd entries. * Files with unknown uid should go into nchrg. Otherwise * (without -p), we try creating new entry for the uid. */ if ((entry = hash_find(statb.st_uid)) == NULL) { if (pfile == NULL) { pw = getpwuid(statb.st_uid); entry = hash_insert(statb.st_uid); if (pw != NULL) { validate_entry(entry, pw); } } } if (entry != NULL && entry->validuser) { entry->dsk_du += statb.st_blocks; } else if (nchrg) { (void) fprintf(nchrg, "%9ld\t%7llu\t%s\n", statb.st_uid, statb.st_blocks, n); } }
PageTable* NormalPaging::allocate_one_pagetable(unsigned pd_entry_id ) { PageTable* table = get_next_level_address<PageTable>(page_directory,pd_entry_id); if(table == NULL) { assert( cur_page_table_num<= 1024 && mode==Legacy_Normal); table = new PageTable(ENTRY_1024); validate_entry(page_directory , pd_entry_id , table); cur_page_table_num++; } return table; }
void index_file(char *filename,hashtable sn_index,long start_offset,long length) { gzFile fd1=open_fastq(filename); gzFile fdf=open_fixed_fastq(filename); if (fd1==NULL) { fprintf(stderr,"\nError: Unable to open %s\n",filename); exit(1); } // move to the right position if(length>0) { fprintf(stderr, "\nInternal error: Not implemented\n"); exit(2); } long cline=1; // sn_index creation could be done in parallel while(!gzeof(fd1)) { long long start_pos=gztell(fd1); char *hdr=READ_LINE_HDR(fd1); if ( hdr==NULL) break; int len; //fprintf(stderr,"sn_index: =%s=\n",readname); // get seq //printf("cline=%ld\nLEN=%ld hdr=%s\n",cline,len,hdr); char *seq=READ_LINE_SEQ(fd1); char *hdr2=READ_LINE_HDR2(fd1); char *qual=READ_LINE_QUAL(fd1); char* readname=get_readname(hdr,&len,cline,filename); if (seq==NULL || hdr2==NULL || qual==NULL ) { fprintf(stderr,"\nError in file %s, line %lu: file truncated?\n",filename,cline); exit(1); } if (validate_entry(hdr,hdr2,seq,qual,cline,filename)!=0) { exit(1); } // check for duplicates if ( lookup_header(sn_index,readname)!=NULL ) { fprintf(stderr,"\nError in file %s, line %lu: duplicated sequence %s\n",filename,cline,readname); exit(1); } if ( new_indexentry(sn_index,readname,len,start_pos)==NULL) { fprintf(stderr,"\nError in file %s, line %lu: malloc failed?",filename,cline); exit(1); } replace_dots(start_pos,seq,hdr,hdr2,qual,fdf); PRINT_READS_PROCESSED(cline/4); // cline+=4; } close_fixed_fastq(fdf); gzclose(fd1); return; }
//allocate PageTable* LongModePaging::allocate_page_directory_pointer( unsigned pml4_entry_id) { assert( pml4_entry_id<512 && cur_pdp_num<ENTRY_512); if( !is_present(pml4, pml4_entry_id)) { PageTable* table_tmp= gm_memalign<PageTable>( CACHE_LINE_BYTES, 1); PageTable* table = new (table_tmp) PageTable(ENTRY_512); validate_entry(pml4 , pml4_entry_id , table); cur_pdp_num++; return table; } PageTable* pg_dir_p = get_next_level_address<PageTable>( pml4,pml4_entry_id); return pg_dir_p; }
/*****-----functional interface of paging----*****/ bool PAEPaging::map_page_table(Address addr, void* pg_ptr , bool pbuffer) { unsigned pdp_id = get_page_directory_pointer_off( addr , mode); unsigned pd_id = get_page_directory_off(addr,mode); unsigned buffer_entry_id = get_buffer_table_off(addr,buffer_table_shift,mode); PageTable* table; if( mode == PAE_Normal) { unsigned pt_id = get_pagetable_off(addr , mode); if( (table = allocate_page_table(pdp_id , pd_id))==NULL ) { debug_printf("allocate page table failed"); return false; } if( pbuffer ) { extend_one_buffer_map(addr , table , pg_ptr , pt_id , buffer_entry_id , buffer_table_entry_num); } else { validate_entry(table , pt_id ,pg_ptr); } } else if( mode == PAE_Huge) { if( (table=allocate_pdt(pdp_id))==NULL) { debug_printf("allocate page directory failed !"); return false; } if( pbuffer) extend_one_buffer_map(addr,table, pg_ptr , pd_id, buffer_entry_id , buffer_table_entry_num); else validate_entry( table , pd_id , pg_ptr); } return true; }
PageTable* PAEPaging::allocate_pdt( unsigned pdpt_entry ) { assert( cur_pdt_num < 4 && pdpt_entry < 4 ); PageTable* page_dir = NULL; //pdpt_entry of page_direcotry_pointer has already pointed to page directory if( (page_dir = get_next_level_address<PageTable>(page_directory_pointer, pdpt_entry))!=NULL ) return page_dir; else { //page directory page_dir=new PageTable(ENTRY_512); validate_entry( page_directory_pointer , pdpt_entry ,page_dir); cur_pt_num++; } return page_dir; }
static void custom_entry_changed_cb (GtkEditable *entry, gpointer user_data) { NemoMimeApplicationChooser *chooser = user_data; const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (entry)); gboolean empty = g_strcmp0 (entry_text, "") == 0; if (!empty && validate_entry (GTK_ENTRY (entry), entry_text)) { GAppInfo *default_app; gchar *cl = g_strdup_printf ("%s", entry_text); GAppInfo *info = g_app_info_create_from_commandline (cl, get_nice_name (cl), G_APP_INFO_CREATE_NONE, NULL); default_app = g_app_info_get_default_for_type (chooser->details->content_type, FALSE); gtk_widget_set_sensitive (chooser->details->set_as_default_button, !g_app_info_equal (info, default_app)); gtk_widget_set_sensitive (chooser->details->add_button, app_info_can_add (info, chooser->details->content_type)); g_object_unref (default_app); if (chooser->details->custom_info != NULL) { g_object_unref (chooser->details->custom_info); chooser->details->custom_info = NULL; } chooser->details->custom_info = info; } else { if (chooser->details->custom_info != NULL) { g_object_unref (chooser->details->custom_info); chooser->details->custom_info = NULL; } if (empty) { gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, NULL); gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, NULL); } gtk_widget_set_sensitive (chooser->details->set_as_default_button, FALSE); gtk_widget_set_sensitive (chooser->details->add_button, FALSE); } }
int main(int argc, char **argv ) { //long paired=0; unsigned long num_reads1=0, num_reads2=0; is_paired_data=FALSE; is_interleaved=FALSE; fix_dot=FALSE; int nopt=0; int c; opterr = 0; fprintf(stderr,"Version iRAP %s\n",VERSION); while ((c = getopt (argc, argv, "f")) != -1) switch (c) { case 'f': fix_dot = TRUE; fprintf(stderr,"Fixing (-f) enabled: Replacing . by N (creating .fix.gz files)\n"); ++nopt; break; default: ++nopt; fprintf(stderr,"ERROR: Option -%c invalid\n",optopt); exit(1); } if (argc-nopt<2 || argc-nopt>3) { fprintf(stderr,"Usage: fastq_info [-f] fastq1 [fastq2 file|pe]\n"); //fprintf(stderr,"%d",argc); exit(1); } //gzFile fd1=NULL; gzFile fd2=NULL; if (argc-nopt ==3) { is_paired_data=TRUE; //fprintf(stderr,"%d %d %d %s\n",argc,nopt,argc-nopt,argv[2+nopt]); if ( !strncmp(argv[2+nopt],"pe",2) ) { is_interleaved=FALSE; } //else { // fd2=open_fastq(argv[2+nopt]); // gzclose(fd2); // } // ************************************************************ if ( is_interleaved ) { // interleaved num_reads1=validate_interleaved(argv[1+nopt]); } else { // single or pair of fastq file(s) unsigned long cline=1; fprintf(stderr,"HASHSIZE=%lu\n",(long unsigned int)HASHSIZE); //memset(&collisions[0],0,HASHSIZE+1); hashtable sn_index=new_hashtable(HASHSIZE); index_mem+=sizeof(hashtable); index_file(argv[1+nopt],sn_index,0,-1); num_reads1=sn_index->n_entries; fprintf(stderr,"\n"); // print some info fprintf(stderr,"Reads processed: %ld\n",sn_index->n_entries); fprintf(stderr,"Memory used in indexing: ~%ld MB\n",index_mem/1024/1024); // pair-end if (argc-nopt ==3 ) { fprintf(stderr,"File %s processed\n",argv[1+nopt]); fprintf(stderr,"Next file %s\n",argv[2+nopt]); // validate the second file and check if all reads are paired fd2=open_fastq(argv[2+nopt]); gzFile fdf=open_fixed_fastq(argv[2+nopt]); INDEX_ENTRY* e; // read the entry using another fd cline=1; // TODO: improve code - mostly duplicated:( while(!gzeof(fd2)) { long long start_pos=gztell(fd2); char *hdr=READ_LINE_HDR(fd2); if ( hdr==NULL) break; int len; char *seq=READ_LINE_SEQ(fd2); char *hdr2=READ_LINE_HDR2(fd2); char *qual=READ_LINE_QUAL(fd2); char* readname=get_readname(hdr,&len,cline,argv[2+nopt]); if (seq==NULL || hdr2==NULL || qual==NULL ) { fprintf(stderr,"\nError in file %s, line %lu: file truncated?\n",argv[2+nopt],cline); exit(1); } if (validate_entry(hdr,hdr2,seq,qual,cline,argv[2+nopt])!=0) { exit(1); } //fprintf(stderr,"Reads processed: %ld\n",sn_index->n_entries); // check for duplicates if ( (e=lookup_header(sn_index,readname))==NULL ) { fprintf(stderr,"\nError in file %s, line %lu: unpaired read - %s\n",argv[2+nopt],cline,readname); exit(1); } else { ulong key=hashit(readname); // remove entry from sn_index if (delete(sn_index,key,e)!=e) { fprintf(stderr,"\nError in file %s, line %lu: unable to delete entry from sn_index - %s\n",argv[2+nopt],cline,readname); exit(1); } free_indexentry(e); } PRINT_READS_PROCESSED(cline/4); ++num_reads2; // replace_dots(start_pos,seq,hdr,hdr2,qual,fdf); cline+=4; } printf("\n"); close_fixed_fastq(fdf); if (sn_index->n_entries>0 ) { fprintf(stderr,"\nError in file %s: found %lu unpaired reads\n",argv[1+nopt],sn_index->n_entries); exit(1); } } } FILE* out; if (fix_dot) { out=stderr; } else { out=stdout; } fprintf(out,"------------------------------------\n"); if ( num_reads2>0 ) { fprintf(out,"Number of reads: %lu %lu\n",num_reads1,num_reads2); } else { fprintf(out,"Number of reads: %lu\n",num_reads1); } fprintf(out,"Quality encoding range: %lu %lu\n",min_qual,max_qual); char *enc=qualRange2enc(min_qual,max_qual); if ( enc == NULL ) { fprintf(stderr,"\nERROR: Unable to determine quality encoding - unknown range [%lu,%lu]\n",min_qual,max_qual); exit(1); } fprintf(out,"Quality encoding: %s\n",qualRange2enc(min_qual,max_qual)); fprintf(out,"Read length: %lu %lu\n",min_rl,max_rl); fprintf(out,"OK\n"); exit(0); }
/************************************************************************ * BASIC TEST ROUTINES TO CHECK UNIQUE DATA STRUCTURES LIKE SUPERBLOCK AND * ROOT DIRECTORY AND GET MEMORY FOR THE CHECKER * * - Make sure, that the superblock and all copies are valid. * * THIS TEST HAS BEEN REMOVED FROM THE BASIC VERSION, BECAUSE THE SUPERBLOCK * DATA IS ACTUALLY NOT USED BY THE FILE-SERVER. ALL DATA, DESCRIBING A FILE * SYSTEM IS DERIVED FROM 'devinfo'. ON THE OTHER SIDE, IT IS A NON-TRIVIAL * TASK TO FIND OTHER, EVENTUALLY PARTLY DAMAGED SUPERBLOCKS ON THE MEDIA TO * BE CHECKED. TO HAVE A BASIC IDEA, WHETHER THE RELEVANT DATA (number of * cyl.groups, cyl.group size and cyl.group offset) KEPT IN THE 'devinfo'- * FILE AND ON DISK DESCRIBE THE SAME PHYSICAL DISK, THEY ARE COMPARED FOR * ALL CYLINDER-GROUPS. * * - Compare the # number of free blocks in the bit-maps with the * values, referenced in the cylinder group info structs. * - Allocate all needed memory for the checker. * - Check the root-directory inode and look for the /lost+found - directory * * Parameter : - nothing - * Return : TRUE = no error at all * FALSE = occurrence of a fatal error * *************************************************************************/ word check_unique ( void ) { struct fs tmp; /* For intermediate operation */ struct buf *bp, *bp_2; word cgnr, i, j, c, free_cnt, ecnt, try, off; /*--------- Make a basic comparison of file-system parameters ---------*/ IOdebug ("%s*** Step 1.1 : Plausibility test of file-system parameters", S_INFO); /* cgnr and ncg are the values */ /* taken from devinfo. If no */ /* valid superblock is found */ /* there or the disk parameters */ /* are different, the checking */ /* process is aborted. */ /* Make incore copies of the */ /* superblock data into i_fs and*/ /* incore_fs. */ /*------------------ Tests on the super-block -------------------------*/ /* We have to copy the first */ /* superblock from the cg 0 info-block. */ bp = bread ( 0, 2, 1, SAVEA ); memcpy ( &tmp, &bp->b_un.b_info->fs, sizeof (struct fs) ); brelse ( bp->b_tbp, TAIL ); /* Run until we have a valid copy and */ /* scan the cylinder groups */ for ( cgnr = 0 , try = -1 ;; cgnr++ ) { corrupt_cnt = 0; /* At the beginning: no errors at all */ try++; /* Count the tries which are needed to */ /* get a valid super-block. */ #if DEBUG IOdebug (" check_unique : Try to validate a sample superblock."); #endif /*------- I.Definitely errors ----------*/ /* Block-no 1-3 are always the same ! */ if ( tmp.fs_sblknr != 1 || tmp.fs_iblknr != 2 || tmp.fs_rblknr != 3 ) corrupt_cnt++; /* The magic number is fixed. */ if ( tmp.fs_magic != MAGIC_NUMBER ) corrupt_cnt++; if ( tmp.fs_szfs != sizeof (struct fs) ) corrupt_cnt++; if ( tmp.fs_szcg != sizeof (struct cg) ) corrupt_cnt++; /*------ II.Plausibility errors --------*/ if ( tmp.fs_size != tmp.fs_cgsize * tmp.fs_ncg ) corrupt_cnt++; if ( tmp.fs_dsize != tmp.fs_size - tmp.fs_ncg - 3 ) corrupt_cnt++; if ( tmp.fs_fsize != tmp.fs_bsize / tmp.fs_frag ) corrupt_cnt++; if ( tmp.fs_maxdpb != tmp.fs_bsize / sizeof (struct dir_elem) ) corrupt_cnt++; if ( tmp.fs_maxcontig != tmp.fs_bsize / sizeof (daddr_t) ) corrupt_cnt++; if ( tmp.fs_ncgcgoff != tmp.fs_ncg * tmp.fs_cgoffset ) corrupt_cnt++; if ( tmp.fs_minfree < 0 || tmp.fs_minfree > 99 ) corrupt_cnt++; if ( tmp.fs_psmal > tmp.fs_maxpsz || tmp.fs_pmedi > tmp.fs_maxpsz || tmp.fs_phuge > tmp.fs_maxpsz ) corrupt_cnt++; /* Were there errors detected ? */ if ( corrupt_cnt ) { unique_err++; if ( cgnr == 0 ) cgnr++; IOdebug ("The Superblock is damaged (%d errors counted) !", corrupt_cnt); /* Is it possible to select */ /* automatically a new one ? */ if ( tmp.fs_size == tmp.fs_cgsize * tmp.fs_ncg && tmp.fs_ncgcgoff == tmp.fs_cgoffset * tmp.fs_ncg && tmp.fs_size != 0 && tmp.fs_ncgcgoff != 0 ) { IOdebug ("Try to interpret block no: %d as an info-block.", map_cgtoib (cgnr,tmp.fs_cgoffset,tmp.fs_cgsize)); /* Read in info-blk from next cg */ bp = bread ( 0, map_cgtoib (cgnr,tmp.fs_cgoffset,tmp.fs_cgsize), 1, SAVEA ); /* There are possibly two reasons why we cannot */ /* read the block. If we have used a block-num */ /* which is invalid, we need help from the user */ /* to find a correct number for an info-block */ /* Copy in temporary struct */ memcpy ( &tmp, &bp->b_un.b_info->fs, sizeof (struct fs) ); /* Release unused packet */ brelse ( bp->b_tbp, TAIL ); /* Try to validate the new copy */ /* of the Superblock. */ continue; } else /* No automatically selection: */ /* Give the user the choice to */ { /* select manually a new one */ IOdebug ("Unable to select a new info block automatically!"); /* Assisted search or manual */ /* 'rebuild' of a superblock! */ return FALSE; } } else /* No errors were detected */ { if ( try > 0 ) IOdebug ("Valid superblock in use now !"); /* Keep the valid data incore */ /* in a separated storage area. */ memcpy ( &incore_fs, &tmp, sizeof (struct fs) ); /* Make a copy in i_fs, which is*/ /* for exclusive checker's use */ memcpy ( &i_fs, &tmp, sizeof (struct fs) ); break; /* We can finish the search for */ /* a valid superblock ! */ } /* end of <if (corrupt_cnt)> */ } /* end of <for(cgnr)> */ /* At this point we are sure, that the incore- */ /* copy of the super-block is valid. So we can */ /* use it further on, if we need file system */ /* parameters! */ { /* Update each cylinder-group */ /* if necessary. */ for ( cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ ) { /* Read appropriate info block */ bp = bread ( 0, map_cgtoib (cgnr,i_fs.fs_cgoffset,i_fs.fs_cgsize), 1, SAVEA ); #if DEBUG IOdebug (" check_unique : Compare it with the copy in cylinder-group %d.", cgnr); #endif /* Updating is only recommended, */ /* if changes were made. */ if ( my_memcmp ( &i_fs, &bp->b_un.b_info->fs, tmp.fs_szfs ) ) { #if DEBUG IOdebug (" check_unique : Copy superblock to cylinder-group %d.", cgnr); #endif unique_err++; /* Update it's superblock copy */ memcpy ( &bp->b_un.b_info->fs, &i_fs, sizeof (struct fs) ); /* ... and write it back to disk */ fst.corrected_sb++; test_bwrite ( bp ); } else /* They are the same: don't copy */ brelse ( bp->b_tbp, TAIL ); } /* end <for (cgnr)> */ } /* Report differences between data kept */ /* in the superblock and in the 'devinfo'*/ /* structures */ #if DEBUG IOdebug (" check_unique : Compare 'devinfo' data with the superblock"); #endif if ( i_fs.fs_ncg != vvi->CgCount ) IOdebug ("Number of cylinder groups Sb : %4d / devinfo : %d", i_fs.fs_ncg, vvi->CgCount); if ( i_fs.fs_cgsize != vvi->CgSize ) IOdebug ("Size of a cylinder group Sb : %4d / devinfo : %d", i_fs.fs_cgsize, vvi->CgSize); if ( i_fs.fs_cgoffset != vvi->CgOffset ) IOdebug ("Relative offset into a cylinder group Sb : %4d / devinfo : %d", i_fs.fs_cgoffset, vvi->CgOffset); if ( i_fs.fs_psmal != fsi->SmallPkt ) IOdebug ("Size of a of small packet Sb : %d / devinfo : %d", i_fs.fs_psmal, fsi->SmallPkt); if ( i_fs.fs_pmedi != fsi->MediumPkt ) IOdebug ("Size of a of medium packet Sb : %d / devinfo : %d", i_fs.fs_pmedi, fsi->MediumPkt); if ( i_fs.fs_phuge != fsi->HugePkt ) IOdebug ("Size of a huge packet Sb : %d / devinfo : %d", i_fs.fs_phuge, fsi->HugePkt); if ( i_fs.fs_pscnt != fsi->SmallCount ) IOdebug ("Number of samll packets Sb : %d / devinfo : %d", i_fs.fs_pscnt, fsi->SmallCount); if ( i_fs.fs_pmcnt != fsi->MediumCount ) IOdebug ("Number of medium packtes Sb : %d / devinfo : %d", i_fs.fs_pmcnt, fsi->MediumCount); if ( i_fs.fs_phcnt != fsi->HugeCount ) IOdebug ("Number of huge packets Sb : %d / devinfo : %d", i_fs.fs_phcnt, fsi->HugeCount); if ( i_fs.fs_maxnii != fsi->MaxInodes ) IOdebug ("Maximal number of incore inodes Sb : %d / devinfo : %d", i_fs.fs_maxnii, fsi->MaxInodes); if ( i_fs.fs_minfree != vvi->MinFree ) IOdebug ("Percentage of space to be kept free Sb : %d / devinfo : %d", i_fs.fs_minfree, vvi->MinFree); /*---- To ease addressing of info-blocks: create an info-bnr table ----*/ #if DEBUG IOdebug (" check_unique : Create an info-block number table."); #endif /* Calculate all block numbers */ for ( cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ ) /* ... and fill the table */ info_blocks[cgnr] = map_cgtoib (cgnr, i_fs.fs_cgoffset, i_fs.fs_cgsize); /*--------- Discrepancy between bit-maps and cg-info ? ----------------*/ /* This part is only used to detect differences */ /* in the bit-maps and summary-structures and */ /* to report them. No attempts to correct them */ /* are made. This is done later by check_blocks.*/ IOdebug ("%s*** Step 1.2 : First inspection of bitmap-data", S_INFO); /* Scan all cylinder groups */ for ( corrupt_cnt = 0 , cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ ) { /* Read the cg info-block */ bp = bread ( 0, info_blocks[cgnr], 1, SAVEA ); /* Read error */ if ( bp == (struct buf *) NULL ) { IOdebug ("%sUnexpected read error for block no: %d.", S_SERIOUS, info_blocks[cgnr]); return FALSE; } if ( bp->b_un.b_info->cgx.cg_cgx != cgnr ) { IOdebug ("%sInvalid cgnr (%d) found in info block %d!", S_WARNING, bp->b_un.b_info->cgx.cg_cgx ,cgnr); } /* Scan through the bit-map ! */ for ( i = 0 , free_cnt = 0 , ecnt = 0 ; i < i_fs.fs_cgsize ; i++ ) { switch ( bp->b_un.b_info->cgx.cg_free[i] ) { /* Test for errors */ case 0x00 : free_cnt++; break; case 0xff : continue; break; default : ecnt++; fst.bitmap_errors++; corrupt_cnt++; } } if ( free_cnt != bp->b_un.b_info->cgx.cg_s.s_nbfree ) { /* By comparing with cg-sum */ corrupt_cnt++; unique_err++; fst.summary_errors++; IOdebug ("%sDifferent number of free blocks found.", S_WARNING); IOdebug ("%s> Cyl. Group : %d FREE counted= %d cg-summary= %u", S_INFO, cgnr, free_cnt, bp->b_un.b_info->cgx.cg_s.s_nbfree); } /* Definitely errors in maps ? */ if ( ecnt ) /* ( != 0 && != 0xff ) */ { unique_err++; IOdebug ("%sCorrupted bits in bit-map found.", S_WARNING); IOdebug ("%s> Cyl. Group : %d ERRORS =%d blocks", S_INFO, cgnr, ecnt); /* We have reached the limit ? */ if ( ecnt > i_fs.fs_cgsize * maxbmerr / 100 ) { /* Note cg-bitmap as unusable */ cg_bitmap_usable[cgnr] = FALSE; IOdebug ("%sThe bit-map is not usable!", S_SERIOUS); } else cg_bitmap_usable[cgnr] = TRUE; } /* We have found a bitmap in an */ else /* usable state ! */ cg_bitmap_usable[cgnr] = TRUE; /* Release unused block */ brelse ( bp->b_tbp, TAIL ); } /* end < for (cgnr) > */ /*--------- Allocate enough memory for a reference bit-map array ------*/ IOdebug ("%s*** Step 1.3 : Allocate memory for reference bit-map array.", S_INFO); bit_maps_allocated = alloc_ref_maps (); if ( ! bit_maps_allocated ) /* No success again, that's bad! */ { IOdebug ("%sUnable to allocate memory for reference bit-maps.", S_FATAL); return FALSE; } /* Blocks 0-2 always allocated ! */ bit_maps[0][0] = 1; /* Boot-block */ found_blocks++; bitmap_incr (1); /* Summary block */ found_blocks++; /* Mark all info-blocks as being */ /* allocated. */ for ( cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ ) { found_blocks++; bitmap_incr (info_blocks[cgnr]); } /*----------- Prepare the hash-table for directory entries ------------*/ #if DEBUG IOdebug (" check_unique : Prepare directory-entry hash table."); #endif /* We have to initialize all */ for ( i = 0 ; i < DEHASHSZ ; i++ ) /* hash-pointers ! */ de_hash_tab[i].denxt = (struct de_name *) NULL; /*------ Prepare the hash-table for duplicate block numbers ---------*/ #if DEBUG IOdebug (" check_unique : Prepare duplicate block-number hash table."); #endif /* We have to initialize all */ for ( i = 0 ; i < DUPHASHSZ ; i++ ) /* hash-pointers ! */ dup_hash_tab[i].dupnxt = (struct dup_bnr *) NULL; /*-------- Prepare the hash-table for symbolic link references ------*/ #if DEBUG IOdebug (" check_unique : Prepare symbolic-link hash-table."); #endif /* We have to initialize all */ for ( i = 0 ; i < LINKHASHSZ ; i++ ) /* hash-pointers */ link_hash_tab[i].lnnxt = (struct de_link *) NULL; /*--------------- Valid root directory data ? -------------------------*/ IOdebug ("%s*** Step 1.4 : Check the root directory inode.", S_INFO); /* Read summary block with the */ bp = bread ( 0, 1, 1, SAVEA ); /* root-dir inode in it. */ /* if read fails, longjmp */ /* term_jmp */ changes_de = 0; /* Nothing done so far ... */ /* Check the root-dir entry */ if ( ! validate_entry ( &bp->b_un.b_sum->root_dir , "/", Type_Directory, TRUE ) ) { /* Is it totally damaged ! */ /* It is a very dangerous situation, if we have no root-*/ /* directory available. The user can create an */ /* empty one and hope, that lost subdiretory-information*/ /* is picked up during the "lost+found" pass over the */ /* cylinder-group bit-maps. */ unique_err++; IOdebug ("%sThe root-directory is not usable !", S_SERIOUS); /* Pioneer's work: we create a */ /* new inode from scratch ! */ IOdebug ("%sA new root-directory is created from scratch.", S_INFO); /* Pioneer's work: we create a */ /* new root-inode from scratch */ create_new_root_dir ( &bp->b_un.b_sum->root_dir ); /* Write the root-inode back on */ /* disk. */ test_bwrite ( bp ); } else /* After finding a usable root- */ { /* directory entry ... */ if (!bp->b_un.b_sum->sum_same) unique_err++; if ( changes_de ) /* Any changes made ? */ { #if DEBUG IOdebug (" check_unique : Update root-directory inode on disk."); #endif unique_err++; /* Write corrected summary-block */ test_bwrite ( bp ); /* directly to disk */ } else brelse ( bp->b_tbp, TAIL ); } /*---------------- Look for the "lost+found" directory --------------*/ IOdebug ("%s*** Step 1.5 : Look for the '/lost+found'- directory.", S_INFO); bp = bread ( 0, 1, 1, SAVEA ); /* Get root-directory */ /* if read fails, longjmp */ /* term_jmp */ /* Look for the "lost+found"-dir */ bp_2 = search_entry ( &bp->b_un.b_sum->root_dir.de_inode, "lost+found", &off ); /* We have found it ? */ if ( bp_2 != (struct buf *) NULL ) { /* We have found a usable */ lost_found = TRUE; /* /lost+found - directory. */ brelse ( bp_2->b_tbp, TAIL ); brelse ( bp->b_tbp, TAIL ); } /* If we have not found the */ else /* /lost+found-inode, we have to */ { /* create a new one. */ IOdebug ("%sUnable to find a '/lost+found' entry in the root-directory.", S_WARNING); IOdebug ("%sA new '/lost+found' entry is created.", S_INFO); unique_err++; if ( create_lostfound_inode ( &bp->b_un.b_sum->root_dir.de_inode ) ) { IOdebug ("%sHave created a new /lost+found directory!", S_INFO); lost_found = TRUE; test_bwrite ( bp ); /* Write modified root back. */ } else /* We cannot create a /lost+found*/ { /* inode, because we have no */ /* slot available. */ IOdebug ("%sCannot create a new '/lost+found' directory !", S_WARNING); lost_found = FALSE; brelse ( bp->b_tbp, TAIL ); } } return TRUE; } /*-- Procedures dealing with the creation of a new basic structures ---*/ /************************************************************************ * CREATE A TOTALLY EMPTY ROOT-DIRECTORY ENTRY FROM SCRATCH * * - This procedure is called, if the checker was not able to find a * valid root-directory. * * Parameter : dp = Pointer to the root directory-element * Return : - nothing - * ***********************************************************************/ static void create_new_root_dir ( struct dir_elem *dp ) { Date date; #if DEBUG IOdebug (" create_new_root_dir : Create the new entry"); #endif /* Clear the directory-entry */ memset ( dp, 0, sizeof (struct dir_elem) ); /* .. and fill in with the data */ /* for the root-directory */ strcpy ( dp->de_name, i_fs.fs_name ); dp->de_inode.i_mode = Type_Directory; dp->de_inode.i_matrix = DefDirMatrix; date = GetDate (); dp->de_inode.i_ctime = date; dp->de_inode.i_mtime = date; dp->de_inode.i_atime = date; }
int main(int argc, char **argv ) { //long paired=0; is_paired_data=0; is_interleaved=0; printf("Version iRAP %s\n",VERSION); if (argc<2 || argc>3) { fprintf(stderr,"Usage: fastq_validator fastq1 [fastq2 file|pe]\n"); //fprintf(stderr,"%d",argc); exit(1); } FILE *fd1=NULL; FILE *fd2=NULL; // open & close fd1=open_fastq(argv[1]); fclose(fd1); //fprintf(stderr,"%d\n",argc); //bin/fprintf(stderr,"%s\n",argv[0]); if (argc ==3) { is_paired_data=1; if ( !strncmp(argv[2],"pe",2) ) { is_interleaved=1; } else { fd2=open_fastq(argv[2]); fclose(fd2); } } // ************************************************************ // casava 1.8? is_casava_18=is_casava_1_8(argv[1]); if (is_casava_18) fprintf(stderr,"CASAVA=1.8\n"); // ************************************************************ //off_t cur_offset=1; // interleaved if ( is_interleaved ) { exit(validate_interleaved(argv[1])); } unsigned long cline=1; fprintf(stderr,"HASHSIZE=%lu\n",(long unsigned int)HASHSIZE); //memset(&collisions[0],0,HASHSIZE+1); hashtable sn_index=new_hashtable(HASHSIZE); index_mem+=sizeof(hashtable); index_file(argv[1],sn_index,0,-1); fprintf(stderr,"\n"); // print some info fprintf(stderr,"Reads processed: %ld\n",sn_index->n_entries); fprintf(stderr,"Memory used in indexing: ~%ld MB\n",index_mem/1024/1024); // pair-end if (argc ==3 ) { fprintf(stderr,"File %s processed\n",argv[1]); fprintf(stderr,"Next file %s\n",argv[2]); // validate the second file and check if all reads are paired fd2=open_fastq(argv[2]); INDEX_ENTRY* e; // read the entry using another fd cline=1; // TODO: improve code - mostly duplicated:( while(!feof(fd2)) { //long start_pos=ftell(fd2); char *hdr=READ_LINE_HDR(fd2); if ( hdr==NULL) break; int len; char *seq=READ_LINE_SEQ(fd2); char *hdr2=READ_LINE_HDR2(fd2); char *qual=READ_LINE_QUAL(fd2); char* readname=get_readname(hdr,&len,cline,argv[2]); if (seq==NULL || hdr2==NULL || qual==NULL ) { fprintf(stderr,"Error in file %s, line %lu: file truncated?\n",argv[2],cline); exit(1); } if (validate_entry(hdr,hdr2,seq,qual,cline,argv[2])!=0) { exit(1); } //fprintf(stderr,"Reads processed: %ld\n",sn_index->n_entries); // check for duplicates if ( (e=lookup_header(sn_index,readname))==NULL ) { fprintf(stderr,"Error in file %s, line %lu: unpaired read - %s\n",argv[2],cline,readname); exit(1); } else { ulong key=hashit(readname); // remove entry from sn_index if (delete(sn_index,key,e)!=e) { fprintf(stderr,"Error in file %s, line %lu: unable to delete entry from sn_index - %s\n",argv[2],cline,readname); exit(1); } free_indexentry(e); } PRINT_READS_PROCESSED(cline/4); // cline+=4; } printf("\n"); if (sn_index->n_entries>0 ) { fprintf(stderr,"Error in file %s: found %lu unpaired reads\n",argv[1],sn_index->n_entries); exit(1); } } printf("OK\n"); exit(0); }
/************************************************************************* * TESTS ON SINGLE DATA STRUCTURES LIKE INODES * * - This procedure is the central routine for working on the directory * tree. A backtracking mechanism with no recursive procedure-overhead * is used to avoid memory allocation and stack overflow problems. * - It is called as "step 2" during the checking process after working * on unique data-structures and allocation all needed buffers for * tables etc. * - The root-inode was validated during a separate step in check_unique(). * * Parameter : root_de = The directory-entry of the local root which * has to be examined * root_bnr = The number of the directory block which keeps * the root entry * root_offs = The offset in this directory block * Return : TRUE : under all normal checking conditions * FALSE : if a fatal error occurs * *************************************************************************/ word check_inodes ( struct dir_elem *root_de, daddr_t root_bnr, word root_offs ) { word spare; /* # of entries in the direct. */ daddr_t bnr; /* For temporary storage */ word offset; word depth; /* To keep track about the dis- */ /* tance from the root-direct. */ struct buf *bpar; /* Points to the current parent */ /* directory - block */ struct buf *blpt; /* For symbolic-link reference- */ /* path block */ tree_e head; word first_time; /* Used to signal, if an entry */ /* is scanned the first time */ tree_e *parent; /* Pointer to the actual parent */ /* tree-element */ tree_e *tpt; /* Pointer to the actual wor- */ /* king element. */ struct dir_elem *de_pt; /* Used for temporary storage */ /*---------------------- Init operations ----------------------------*/ head.bnr = root_bnr; /* Init the head element */ head.offset = root_offs; head.parent_used = TRUE; /* Copy the root entry */ memcpy ( (void *) &head.de, (void *) root_de, sizeof (struct dir_elem) ); head.enxt = (tree_e *) NULL; /* Zero the head-pointers */ head.eprv = (tree_e *) NULL; head.lnxt = (tree_e *) NULL; head.lprv = (tree_e *) NULL; /* Clear the comparison struct */ memset ( &dir_cmp, 0, sizeof (struct dir_elem) ); strcpy ( path, "/" ); /* Set the name of the root */ strcat ( path, head.de.de_name ); /* of the filesystem */ spare = 0; /* No entry at the beginning */ first_time = TRUE; /* Start up value */ parent = &head; /* At the beginning the head */ tpt = &head; /* element is the only one. */ remove_de_hash (); /* Free previously used hash- */ /* table elements */ changes_de = 0; /* Nothing changed so far... */ depth = 0; /* We start on root-position */ /*--------------- Traverse the whole directory tree -----------------*/ for ( ;; ) { /* Get the next entry to check */ de_pt = get_next_entry ( &parent->de.de_inode, first_time, &bnr, &offset ); first_time = FALSE; /* We want to get all other en- */ /* tries from this directory */ /* We have got an entry ? */ if ( de_pt != (struct dir_elem *) NULL ) { strncpy (actual_path, path, 512); #if 0 IOdebug ("%sChecking %s / [%s]", S_INFO, path, de_pt->de_name); #endif /* An entry was extracted. Now */ /* check it's validity */ if ( validate_entry ( de_pt, path, UNKNOWN, TRUE ) ) { /* Put the entry name into the */ /* appropriate hash-queue */ append_de_hash ( de_pt->de_name ); /* We have to increment the */ spare++; /* total count of entries */ /*-------------- Storage of symbolic-link information ----------------*/ /* Was it a symbolic link ? */ if ( de_pt->de_inode.i_mode == Type_Link ) { /* Read the block with the re- */ /* ference path in buffer-cache */ blpt = bread ( 0, de_pt->de_inode.i_db[0], 1, SAVEA ); /* Append the link to the hash- */ /* table for symbolic links */ append_link_hash ( bnr, offset, parent->bnr, parent->offset, blpt->b_un.b_link->name); /* One more symbolic link found */ found_links++; /* The ref-block is not used */ /* anymore */ brelse ( blpt->b_tbp, TAIL ); } /*----- Appending new elements to the hierarchical directory-tree ----*/ if ( de_pt->de_inode.i_mode == Type_Directory ) { /* Increment the counter for */ /* the number of valid directo- */ /* ries in a cylinder group. */ add_dir ( bnr ); found_dirs++; if ( tpt == parent ) /* Add a new directory level */ tpt = append_level ( tpt ); else /* .. or a new entry */ tpt = append_entry ( tpt ); /* Save the entry's location */ tpt->bnr = bnr; tpt->offset = offset; /* Save the entry's content */ memcpy ( &tpt->de, de_pt, sizeof (struct dir_elem) ); /* At this time NOT used as a */ /* parent-dir */ tpt->parent_used = FALSE; #if DEBUG IOdebug (" check_inodes : New element created for %s (bnr= %d, off= %d)", tpt->de.de_name, tpt->bnr, tpt->offset ); #endif } /* Update the actual number of */ /* file checked. */ if ( de_pt->de_inode.i_mode == Type_File ) found_files++; } else /* If the validation does not */ { /* succeeds: */ /* We have to make a note, if */ /* /lost+found will be deleted ! */ if ( depth == 0 && ! strcmp ( de_pt->de_name, "lost+found" ) ) { IOdebug ("%sUnusable /lost+found-dir !", S_WARNING); lost_found = FALSE; } IOdebug ("%sThe entry is invalid and will be deleted!", S_SERIOUS); if ( ! no_corrections ) { /* We cannot make use anymore */ /* of the corrupted entry and */ /* delete it. */ memset ( (void *) de_pt, 0, sizeof (struct dir_elem) ); /* Note the deletion */ fst.deleted_inodes++; changes_de++; } } } /*------ After checking a complete directory with all entries: --------*/ else /* One directory fully scanned: */ { #if DEBUG IOdebug (" check_inodes : Have examined all entries. Change the directory"); IOdebug (" Current parent = %s 'used' = %d", parent->de.de_name, parent->parent_used); IOdebug (" Current entry = %s 'used' = %d", tpt->de.de_name, tpt->parent_used); #endif /*------- Go on with the last directory of the current sub-dir ------*/ if ( tpt->enxt == (tree_e *) NULL && tpt->lnxt == (tree_e *) NULL && tpt != parent && ! tpt->parent_used ) { #if DEBUG IOdebug (" check_inodes : Take the last sub-dir as parent directory"); #endif #if DEBUG IOdebug (" check_inodes : Spare value found = %d , counted = %d", parent->de.de_inode.i_spare, spare ); #endif /* Different # of entries ? */ if ( spare != parent->de.de_inode.i_spare ) { /* Save the new spare value */ /* Read the parent-directory */ #if DEBUG IOdebug (" check_inodes : Correct number of entries (spare value)"); #endif bpar = bread ( 0, parent->bnr, 1, SAVEA ); /* Change the entry */ if ( parent->bnr == 1 ) { /* Special handling for root */ bpar->b_un.b_sum->root_dir.de_inode.i_spare = spare; bpar->b_un.b_sum->root_dir.de_inode.i_size = spare * sizeof(struct dir_elem); } else { bpar->b_un.b_dir[parent->offset].de_inode.i_spare = spare; bpar->b_un.b_dir[parent->offset].de_inode.i_size = spare * sizeof(struct dir_elem); } /* ... and write it back. */ test_bwrite ( bpar ); } /* Prepare the tree-element */ /* for a new pass as "parent": */ parent = tpt; parent->parent_used = TRUE; first_time = TRUE; spare = 0; /* Append to the pathname-string*/ strcat ( path , "/" ); /* ... a new sub-dir branch */ strcat ( path , parent->de.de_name ); /* One level lower than the */ depth++; /* root-directory */ /* Clear the name-hash-table */ remove_de_hash (); /* Begin with the first entry.. */ continue; /* and scan again all entries. */ } /*-------------------- Backtracking conditions ----------------------*/ if ( tpt->enxt == (tree_e *) NULL && tpt->lnxt == (tree_e *) NULL && tpt == parent && tpt->parent_used ) { #if DEBUG IOdebug (" check_inodes : Use backtracking to get a new parent-dir"); #endif #if DEBUG IOdebug (" check_inodes : Spare value found = %d , counted = %d", parent->de.de_inode.i_spare, spare ); #endif /* Different # of entries ? */ if ( spare != parent->de.de_inode.i_spare ) { #if DEBUG IOdebug (" check_inodes : Correct number of entries (spare value)"); #endif /* Save the new spare value */ /* Read the directory block */ bpar = bread ( 0, parent->bnr, 1, SAVEA ); /* Change the entry */ if ( parent->bnr == 1 ) { /* Special handling for root */ bpar->b_un.b_sum->root_dir.de_inode.i_spare = spare; bpar->b_un.b_sum->root_dir.de_inode.i_size = spare * sizeof(struct dir_elem); } else { bpar->b_un.b_dir[parent->offset].de_inode.i_spare = spare; bpar->b_un.b_dir[parent->offset].de_inode.i_size = spare * sizeof(struct dir_elem); } /* ... and write it back. */ test_bwrite ( bpar ); } /* Look for a directory, which */ /* wasn't used as a "parent" */ do { /* THE MAIN EXIT-POINT ! */ if ( tpt->eprv == (tree_e *) NULL && tpt->lprv == (tree_e *) NULL ) return TRUE; /* The "move-back" operation */ if ( tpt->lprv != (tree_e *) NULL ) { /* Remove the lowest level */ parent = remove_level ( tpt ); depth--; } else /* Remove the last entry from */ /* the directory */ parent = remove_entry ( tpt ); /* Adjust the work-pointer */ tpt = parent; /* Cut the pathname string and */ *( strrchr ( path , '/' ) ) = '\0'; #if DEBUG IOdebug (" check_inodes : Backtracking to path = %s (depth: %d)", path, depth ); #endif } /* try it again until an unused */ /* dir-entry is found */ while ( tpt->parent_used ); /* Append the new sub-dir */ if ( tpt->de.de_name ) { strcat ( path, "/" ); strcat ( path, tpt->de.de_name ); } /* Prepare the tree-element as */ /* the new parent-directory */ tpt->parent_used = TRUE; first_time = TRUE; spare = 0; /* Clear the hash-table */ remove_de_hash (); /* ... and go to the beginning */ continue; /* Now we will examine the en- */ /* tries of the "new" directory.*/ } } } /* end of <for (;;)> */ }