/* * af_set_pagesize: * Sets the pagesize. Fails with -1 if it can't be changed. */ int af_set_pagesize(AFFILE *af,u_long pagesize) { /* Allow the pagesize to be changed if it hasn't been set yet * and if this format doesn't support metadata updating (which is the raw formats) */ struct af_vnode_info vni; af_vstat(af,&vni); if(vni.changable_pagesize==0 && af->image_size>0){ if(pagesize==af->image_pagesize) return 0; // it's already set to this, so let it pass errno = EINVAL; return -1; } if(pagesize % af->image_sectorsize != 0){ (*af->error_reporter)("Cannot set pagesize to %d (sectorsize=%d)\n", pagesize,af->image_sectorsize); errno = EINVAL; return -1; } af->image_pagesize = pagesize; if(af_update_seg(af,AF_PAGESIZE,pagesize,0,0)){ if(errno != ENOTSUP) return -1; // error updating (don't report ENOTSUP); } return 0; }
/* af_imagesize: * Return the byte # of last mapped byte in image, or size of device; */ int64 af_imagesize(AFFILE *af) { struct af_vnode_info vni; if(af_vstat(af,&vni)==0){ return vni.imagesize; } return -1; }
/* * the stat of the afm is the stat of the metafile, * but we don't do compression. */ static int afm_raw_vstat(AFFILE *af,struct af_vnode_info *vni) { memset(vni,0,sizeof(*vni)); // clear it struct afm_private *ap = AFM_PRIVATE(af); af_vstat(ap->aff,vni); vni->supports_compression = 0; vni->supports_metadata = 1; return 0; }
/* Return if we are at the end of the file */ int af_eof(AFFILE *af) { af_vnode_info vni; if(af_vstat(af,&vni)) return -1; // that's bad if(vni.use_eof) return vni.at_eof; // if implementation wants to use it, use it if(af->pos<0){ errno = EINVAL; return -1; // this is bad } return (int64)af->pos >= af_imagesize(af); }
/* Return if we are at the end of the file */ int af_eof(AFFILE *af) { AF_READLOCK(af); af_vnode_info vni; if(af_vstat(af,&vni)) return -1; // this is bad; we need vstat... if(vni.use_eof) return vni.at_eof; // if implementation wants to use it, use it if(af->pos<0){ // pos shouldn't be <0 errno = EINVAL; return -1; // this is bad } int ret = (int64_t)af->pos >= (int64_t)vni.imagesize; AF_UNLOCK(af); return ret; }
/* af_set_sectorsize: * Sets the sectorsize. * Fails with -1 if imagesize >=0 unless these changes permitted */ int af_set_sectorsize(AFFILE *af,int sectorsize) { struct af_vnode_info vni; af_vstat(af,&vni); if(vni.changable_pagesize==0 && af->image_size>0){ errno = EINVAL; return -1; } af->image_sectorsize =sectorsize; if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize); else af->badflag = (unsigned char *)realloc(af->badflag,sectorsize); af->badflag_set = 0; if(af_update_seg(af,AF_SECTORSIZE,sectorsize,0,0)){ if(errno != ENOTSUP) return -1; } return 0; }
/* vstat: return information about the EVD */ static int evd_vstat(AFFILE *af,struct af_vnode_info *vni) { struct evd_private *ed = EVD_PRIVATE(af); memset(vni,0,sizeof(*vni)); // clear it /* Return the size of the whole image */ vni->imagesize = 0; // start off with 0 for(unsigned int i=0;i<ed->num_evfs;i++){ /* Stat each file and add its size */ struct af_vnode_info v2; memset(&v2,0,sizeof(v2)); if(af_vstat(ed->evfs[i],&v2)==0){ vni->imagesize += v2.imagesize; } } vni->has_pages = 1; vni->supports_metadata = 0; return 0; }
/* af_get_imagesize: * Return the byte # of last mapped byte in image, or size of device; * No locking is needed because individual elements of the af structure are not accessed. */ int64_t af_get_imagesize(AFFILE *af) { int64_t ret = -1; struct af_vnode_info vni; memset(&vni,0,sizeof(vni)); if(af_vstat(af,&vni)==0){ /* If vni.imagesize is 0 and if there are encrypted segments and if there * is no imagesize segment but there is an encrypted one, then we can't read this encrypted file... */ if(vni.imagesize<=0 && vni.segment_count_encrypted>0){ if(af_get_seg(af,AF_IMAGESIZE,0,0,0)!=0){ errno = EPERM; goto done; } } ret = vni.imagesize; } done:; return ret; }
static int afd_vstat(AFFILE *af,struct af_vnode_info *vni) { struct afd_private *ap = AFD_PRIVATE(af); memset(vni,0,sizeof(*vni)); // clear it /* See if there is some device that knows how big the disk is */ if(ap->num_afs>0){ af_vstat(ap->afs[0],vni); // get disk free bytes } /* Get the file with the largest imagesize from either the * AFD or any of the sub AFDs... */ vni->imagesize = af->image_size; for(int i=0;i<ap->num_afs;i++){ vni->imagesize = max(vni->imagesize,ap->afs[i]->image_size); } vni->has_pages = 1; vni->supports_metadata = 1; return 0; }
Attributes AffNode::_attributes() { Attributes vmap; struct af_vnode_info vni; unsigned long total_segs = 0; unsigned long total_pages = 0; unsigned long total_hashes = 0; unsigned long total_signatures =0; unsigned long total_nulls = 0; vmap["orignal path"] = new Variant(this->originalPath); AFFILE* affile = af_open(this->originalPath.c_str(), O_RDONLY, 0); if (affile) { vmap["dump type"] = new Variant(std::string(af_identify_file_name(this->originalPath.c_str(), 1))); if (af_vstat(affile, &vni) == 0) { if (vni.segment_count_encrypted > 0 || vni.segment_count_signed > 0) { vmap["encrypted segments"] = new Variant(vni.segment_count_encrypted); vmap["signed segments"] = new Variant(vni.segment_count_signed); } vector <string> segments; char segname[AF_MAX_NAME_LEN]; af_rewind_seg(affile); int64_t total_datalen = 0; size_t total_segname_len = 0; size_t datalen = 0; int aes_segs=0; while(af_get_next_seg(affile, segname, sizeof(segname), 0, 0, &datalen)==0) { total_segs++; total_datalen += datalen; total_segname_len += strlen(segname); if(segname[0]==0) total_nulls++; char hash[64]; int64_t page_num = af_segname_page_number(segname); int64_t hash_num = af_segname_hash_page_number(segname,hash,sizeof(hash)); if(page_num>=0) total_pages++; if(hash_num>=0) total_hashes++; if(strstr(segname,AF_SIG256_SUFFIX)) total_signatures++; if(strstr(segname,AF_AES256_SUFFIX)) aes_segs++; if((page_num>=0||hash_num>=0)) continue; if(af_is_encrypted_segment(segname)) continue; this->addSegmentAttribute(&vmap, affile, segname); } vmap["Total segments"] = new Variant((uint64_t)total_segs); vmap["Total segments real"] = new Variant((uint64_t)(total_segs - total_nulls)); if (aes_segs) vmap["Encrypted segments"] = new Variant(aes_segs); vmap["Page segments"] = new Variant((uint64_t)total_pages); vmap["Hash segments"] = new Variant((uint64_t)total_hashes); vmap["Signature segments"] = new Variant((uint64_t)total_signatures); vmap["Null segments"] = new Variant((uint64_t)total_nulls); vmap["Total data bytes"] = new Variant((uint64_t)total_datalen); } } af_close(affile); return vmap; }
/* Requires no locking */ int af_has_pages(AFFILE *af) { struct af_vnode_info vni; if(af_vstat(af,&vni)) return -1; // can't figure it out return vni.has_pages; // will return 0 or 1 }