void affstats(const char *fname) { AFFILE *af = af_open(fname,O_RDONLY,0); if(!af) af_err(1,"af_open(%s)",fname); printf("%s\t",fname); uint32_t segsize=0; int64_t imagesize=0; int64_t blanksectors=0; int64_t badsectors=0; af_get_segq(af,AF_IMAGESIZE,&imagesize); if(af_get_seg(af,AF_PAGESIZE,&segsize,0,0)){ af_get_seg(af,AF_SEGSIZE_D,&segsize,0,0); // check for oldstype } af_get_segq(af,AF_BADSECTORS,&badsectors); af_get_segq(af,AF_BLANKSECTORS,&blanksectors); print_size(imagesize); printf("\t"); fflush(stdout); int64_t compressed_bytes = 0; int64_t uncompressed_bytes = 0; /* Now read through all of the segments and count the number of * data segments. We know the uncompressed size... */ af_rewind_seg(af); char segname[AF_MAX_NAME_LEN+1]; size_t datalen; while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){ int64_t page_num = af_segname_page_number(segname); if(page_num>=0){ compressed_bytes += datalen; uncompressed_bytes += segsize; } } if(uncompressed_bytes > imagesize) uncompressed_bytes = imagesize; print_size(compressed_bytes); printf("\t"); print_size(uncompressed_bytes); printf(" %" I64d " %" I64d,blanksectors,badsectors); putchar('\n'); }
/* af_read_sizes: * Get the page sizes if they are set in the file. */ void af_read_sizes(AFFILE *af) { af_get_seg(af,AF_SECTORSIZE,&af->image_sectorsize,0,0); if(af->image_sectorsize==0) af->image_sectorsize = 512; // reasonable default if(af_get_seg(af,AF_PAGESIZE,&af->image_pagesize,0,0)){ af_get_seg(af,AF_SEGSIZE_D,&af->image_pagesize,0,0); // try old name } /* Read the badflag if it is present */ size_t sectorsize = af->image_sectorsize; if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize); if(af_get_seg(af,AF_BADFLAG,0,af->badflag,(size_t *)§orsize)==0){ af->badflag_set = 1; } /* Read the image file segment if it is present. * If it isn't, scan through the disk image to figure out the size of the disk image. */ if(af_get_segq(af,AF_IMAGESIZE,(int64_t *)&af->image_size)){ /* Calculate the imagesize by scanning all of the pages that are in * the disk image and finding the highest page number. * Then read that page to find the last allocated byte. */ char segname[AF_MAX_NAME_LEN]; size_t datalen = 0; af_rewind_seg(af); // start at the beginning int64_t highest_page_number = 0; while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){ if(segname[0]==0) continue; // ignore sector int64_t pagenum = af_segname_page_number(segname); if(pagenum > highest_page_number) highest_page_number = pagenum; } size_t highest_page_len = 0; if(af_get_page(af,highest_page_number,0,&highest_page_len)==0){ af->image_size = af->image_pagesize * highest_page_number + highest_page_len; } } af->image_size_in_file = af->image_size; }
/* afm_split_raw_setup: * Sets up the parameters of the split-raw by reading from the metadata file. * The advantage of doing it this way is that a new file can be opened, * the metadata parmeters set, and then an af_write() call made, and the values. * get copied. */ static int afm_split_raw_setup(AFFILE *af) { struct afm_private *ap = AFM_PRIVATE(af); if(ap->sr_initialized) return 0; // already setup /* The size of AF_PAGES_PER_RAW_IMAGE_FILE indicates whether the file is split. * If it is not present, or if it is 0-length, assume that the file is not split. */ uint64_t pages_per_file = 0; size_t len = 0; if (af_get_seg(ap->aff,AF_PAGES_PER_RAW_IMAGE_FILE,0,0,&len)) { /* Not in file; put it there based on maxsize and image_pagesize, * both of which better be set at this point */ if (af->image_pagesize < 1) { (*af->error_reporter)("afm_split_raw_setup: image_pagesize==0\n"); return -1; } if (af->maxsize % af->image_pagesize) { (*af->error_reporter)("afm_split_raw_setup: maxsize (%"I64d") " "not a multiple of image_pagesize (%d)\n", af->maxsize,af->image_pagesize); return -1; } pages_per_file = af->maxsize / af->image_pagesize; if (af_update_segq (af, AF_PAGES_PER_RAW_IMAGE_FILE, pages_per_file)) { (*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n", af_filename(af), AF_PAGES_PER_RAW_IMAGE_FILE); return -1; } } /* Now, read the segment (which might have just been put there) and set up the split_raw file */ if(af_get_segq(af,AF_PAGES_PER_RAW_IMAGE_FILE,(int64_t *)&pages_per_file)){ (*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n", af_filename(af), AF_PAGES_PER_RAW_IMAGE_FILE); return -1; } /* Verify that splitraw's notion of the rawfilesize is the same as the * metadata's notion if the AFF image_size has been set */ if (ap->aff->image_size && ap->aff->image_size != ap->sr->image_size) { (*af->error_reporter)("afm_split_raw_setup: internal error. " "AFF image_size %"I64d" != SR image_size %"I64d"\n", ap->aff->image_size,ap->sr->image_size); return -1; } /* Uses pages_per_file to set the maxsize of the split_raw if it hasn't been set yet*/ if(ap->sr->maxsize==0){ ap->sr->maxsize = pages_per_file * af->image_pagesize; } /* Verify that the parameters make sense */ if (ap->sr->maxsize != (pages_per_file * af->image_pagesize) && pages_per_file>0) { (*af->error_reporter)("afm_split_raw_setup: %s: per size indicated by metadata (%d * %d) " "doesn't match maxsize (%"I64d")\n", af_filename(af),pages_per_file,af->image_pagesize,ap->sr->maxsize); return -1; } /* Push down the image_pagesize from the AFM to the split_raw */ uint32_t image_pagesize = af->image_pagesize; // default to what's in memory af_get_seg(af,AF_PAGESIZE,&image_pagesize,0,0); // get from the AFF file if possible ap->sr->image_pagesize = af->image_pagesize; // overwrite the default with what the AFM file ap->sr_initialized = 1; return 0; }