/* * af_make_badflag: * Create a randomized bag flag and * leave an empty segment of how many badsectors there are * in the image... */ int af_make_badflag(AFFILE *af) { #ifdef HAVE_OPENSSL_RAND_H /* Use a good random number generator if we have it */ RAND_pseudo_bytes(af->badflag,af->image_sectorsize); strcpy((char *)af->badflag,"BAD SECTOR"); #else /* Otherwise use a bad one */ for(int i=0;i<af->image_sectorsize;i++){ af->badflag[i] = rand() & 0xff; } #endif AF_WRLOCK(af); af->badflag_set = 1; if(af_update_seg(af,AF_BADFLAG,0,af->badflag,af->image_sectorsize)){ AF_UNLOCK(af); return -1; } if(af_update_segq(af,AF_BADSECTORS,0)){ AF_UNLOCK(af); return -1; } AF_UNLOCK(af); return 0; }
/* Close the image and unallocate fields */ int af_close(AFFILE *af) { int ret = 0; AF_WRLOCK(af); af_cache_flush(af); // flush the cache (if writing) if(af->image_size != af->image_size_in_file){ af_update_segq(af,AF_IMAGESIZE,(int64_t)af->image_size); af->image_size_in_file = af->image_size; } if(getenv(AFFLIB_CACHE_STATS)){ fputc('\n',stderr); af_stats(af,stderr); } (*af->v->close)(af); af_deallocate(af); return ret; }
/* Close the image */ int af_close(AFFILE *af) { int ret = 0; if(af->writing){ ret = af_purge(af); // empty any buffers in memory } if(af->writing && af->image_size != af->image_size_in_file){ af_update_segq(af,AF_IMAGESIZE,(int64)af->image_size,1); af->image_size_in_file = af->image_size; } (*af->v->close)(af); if(af->pagebuf){ memset(af->pagebuf,0,af->image_pagesize); // clean object reuse free(af->pagebuf); } if(af->fname) free(af->fname); if(af->badflag) free(af->badflag); memset(af,0,sizeof(*af)); // clean object reuse free(af); return ret; }
/* 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; }