// This is the getdir for use by the EE RPC client // It DMA's entries to the specified buffer in EE memory int fileXio_GetDir_RPC(const char* pathname, struct fileXioDirEntry dirEntry[], unsigned int req_entries) { int matched_entries; int fd, res; iox_dirent_t dirbuf; struct fileXioDirEntry localDirEntry; int intStatus; // interrupt status - for dis/en-abling interrupts struct t_SifDmaTransfer dmaStruct; int dmaID; dmaID = 0; #ifdef DEBUG printf("RPC GetDir Request\n"); printf("dirname: %s\n",pathname); #endif matched_entries = 0; fd = dopen(pathname); if (fd <= 0) { return fd; } { res = 1; while (res > 0) { memset(&dirbuf, 0, sizeof(dirbuf)); res = dread(fd, &dirbuf); if (res > 0) { // check for too many entries if (matched_entries == req_entries) { close(fd); return (matched_entries); } // wait for any previous DMA to complete // before over-writing localDirEntry while(SifDmaStat(dmaID)>=0); DirEntryCopy(&localDirEntry, &dirbuf); // DMA localDirEntry to the address specified by dirEntry[matched_entries] // setup the dma struct dmaStruct.src = &localDirEntry; dmaStruct.dest = &dirEntry[matched_entries]; dmaStruct.size = sizeof(struct fileXioDirEntry); dmaStruct.attr = 0; // Do the DMA transfer CpuSuspendIntr(&intStatus); dmaID = SifSetDma(&dmaStruct, 1); CpuResumeIntr(intStatus); matched_entries++; } // if res } // while } // if dirs and files // cleanup and return # of entries close(fd); return (matched_entries); }
/** * This function deletes the last component of the path (e.g., /a/b/c you * need to remove the file 'c' from the directory /a/b). The steps you * will take will be the following: * * 1. Locate the directory entry for the file by resolving the path - this * will probably involve reading each directory in the path to get * the location of the first data block (or location of data block with * the file's inode) of the specified file. * * 2. Update the directory entry for the deleted file * * 3. Free any data blocks used by the file * * Again, these steps are very general and the actual logistics of how * to locate data blocks of a file, how to free data blocks and how to update * directory entries are dependent on your implementation of directories * and file allocation. * * For time being ignore the fuse_file_info parameter. If you would * like to use please see the open function in fuse.h file for more * detials. * * On error (e.g., the path does not exist) xmp_delete will return -1, * otherwise xmp_delete should return the number of bytes written. * */ static int xmp_delete(const char *path) { int* tuple = traverse_dir_r(path); int ino = tuple[0]; free(tuple); tuple = traverse_dir_w(path); int dir_dnum = tuple[1]; free(tuple); //retrieve inode Inode* ibuf = (Inode*)malloc(sizeof(Inode)*INODE_AMT); Inode* init_ibuf = ibuf; if(dread(global_fd, ino/INODE_AMT, init_ibuf) < 0){ RFAIL; return -1; } ibuf+=ino%INODE_AMT; //retrieve dmap need to implement more if dmap use more than 1 blck char* dmap_buf = (char*)malloc(sizeof(char) * BLOCKSIZE); char* imap_buf = (char*)malloc(sizeof(char) * BLOCKSIZE); if(dread(global_fd, DMAP_OFFSET, dmap_buf) < 0){ RFAIL; return -1; } //remove inode and associated dblck for(int i = 0; i < ibuf->total_blck; i++){ dmap_buf[ibuf->block_pt[i]] = 0; } if(dwrite(global_fd, DMAP_OFFSET, dmap_buf) < 0){ WFAIL; return -1; } if(dread(global_fd, INODE_OFFSET, imap_buf) < 0){ RFAIL; return -1; } imap_buf[ino] = 0; if(dwrite(global_fd, INODE_OFFSET, imap_buf) < 0){ RFAIL; return -1; } //retrieve dir entry Directory* dbuf = (Inode*)malloc(sizeof(Directory) * DIR_AMT); Directory* init_dbuf = dbuf; if(dread(global_fd, DATA_OFFSET + dir_dnum, init_dbuf) < 0){ RFAIL; return -1; } char* last_path; for(char* path_pt = strtok(path, "/"); path_pt!=NULL; path_pt = strtok(NULL, "/")){ last_path = path_pt; } //find last path to remove for(int i = 0; i < DIR_AMT; i++){ if(!strcmp(dbuf->f_name, last_path)){ strcpy(dbuf->f_name, ""); dbuf->inode_num = -1; } } if(dwrite(global_fd, DATA_OFFSET + dir_dnum, init_dbuf) < 0){ WFAIL; return -1; } return 0; }
int main(int argc, char *argv[]){ enum{ P_EXE, P_FRAC, P_NSTEP, P_TOT, }; if(argc!=P_TOT){ info2("Usage: \n\tenv MVM_CLIENT=hostname MVM_PORT=port MVM_SASTEP=sastep ./mvm_cpu fraction nstep\n"); _Exit(0); } int fraction=strtol(argv[P_FRAC], NULL, 10); int nstep=strtol(argv[P_NSTEP], NULL, 10); int nstep0=nstep>1?20:0;//warm up dmat *d_saind=dread("NFIRAOS_saind"); const int nsa=(d_saind->nx-1)/fraction; int *saind=mymalloc((1+nsa),int); for(int i=0; i<nsa+1; i++){ saind[i]=(int)d_saind->p[i]; } dfree(d_saind); const int totpix=saind[nsa]; const int nact=6981;//active subapertures. int ng=nsa*2; float FSMdelta=-0.2; smat *dm=snew(nact,1); smat *mvm=snew(nact, ng); smat *mtch=snew(totpix*2,1); smat *grad=snew(ng,1); smat *im0=snew(totpix,3); short *pix=mymalloc(totpix,short); short *pixbias=mymalloc(totpix,short); { rand_t rseed; seed_rand(&rseed, 1); srandu(mvm, 1e-7, &rseed); srandu(mtch, 1, &rseed); for(int i=0; i<totpix; i++){ pix[i]=(short)(randu(&rseed)*25565); pixbias[i]=(short)(randu(&rseed)*1000); } } smat *mvmt=strans(mvm); int sastep=200;//how many subapertures each time int nrep=1; if(getenv("MVM_NREP")){ nrep=strtol(getenv("MVM_NREP"), NULL, 10); } if(getenv("MVM_SECT")){ sastep=nsa/strtol(getenv("MVM_SECT"), NULL, 10); } if(getenv("MVM_TRANS")){ use_trans=strtol(getenv("MVM_TRANS"), NULL, 10); } if(getenv("MVM_SASTEP")){ sastep=strtol(getenv("MVM_SASTEP"), NULL, 10); } info2("use_trans=%d, nrep=%d, sastep=%d\n", use_trans, nrep, sastep); int sock=-1; char* MVM_CLIENT=getenv("MVM_CLIENT"); if(MVM_CLIENT){ short port=(short)strtol(getenv("MVM_PORT"), NULL, 10); sock=connect_port(MVM_CLIENT, port, 0 ,1); if(sock!=-1) { info2("Connected\n"); int cmd[7]; cmd[0]=nact; cmd[1]=nsa; cmd[2]=sastep; cmd[3]=totpix; cmd[4]=nstep; cmd[5]=nstep0; cmd[6]=2; if(stwriteintarr(sock, cmd, 7) || stwriteintarr(sock, saind, nsa+1) || stwrite(sock, pix, sizeof(short)*totpix)){ close(sock); sock=-1; warning("Failed: %s\n", strerror(errno)); } } } int ready=0; if(sock!=-1 && stwriteint(sock, ready)){ warning("error send ready signal: %s\n", strerror(errno)); close(sock); sock=-1; } smat *timing=snew(nstep, 1); TIC; float timtot=0, timmax=0, timmin=INFINITY; set_realtime(-1, -20); for(int jstep=-nstep0; jstep<nstep; jstep++){ int istep=jstep<0?0:jstep; tic; double theta=M_PI*0.5*istep+FSMdelta; float cd=cos(theta); float sd=cos(theta); szero(dm); for(int isa=0; isa<nsa; isa+=sastep){ int npixleft; int nsaleft; if(nsa<isa+sastep){//terminate npixleft=totpix-saind[isa]; nsaleft=nsa-isa; }else{ npixleft=saind[isa+sastep]-saind[isa]; nsaleft=sastep; } short *pcur=pix+saind[isa]; if(sock!=-1){ if(stread(sock, pcur, sizeof(short)*npixleft)){ warning("failed: %s\n", strerror(errno)); close(sock); sock=-1; _Exit(1); } if(isa==0) tic; } //Matched filter mtch_do(mtch->p, pix, pixbias, grad->p+isa*2, im0->p, im0->p+totpix, im0->p+totpix*2, saind+isa, nsaleft, cd, sd); //MVM for(int irep=0; irep<nrep; irep++){ if(use_trans){ mvmt_do(mvmt->p+isa*2, grad->p+isa*2,dm->p, nact, nsaleft*2, ng); }else{ mvm_do(mvm->p+isa*2*nact, grad->p+isa*2, dm->p, nact, nsaleft*2); } } }//for isa if(sock!=-1){ if(stwrite(sock, dm->p, sizeof(float)*nact)){ warning("error write dmres: %s\n", strerror(errno)); close(sock); sock=-1; _Exit(1); } if(streadint(sock, &ready)){//acknowledgement. warning("error read ack failed: %s\n", strerror(errno)); close(sock), sock=-1; _Exit(1); } timing->p[istep]=ready*1.e-6; }else{ timing->p[istep]=toc3;//do not tic. } if(jstep==istep){ timtot+=timing->p[istep]; if(timmax<timing->p[istep]){ timmax=timing->p[istep]; } if(timmin>timing->p[istep]){ timmin=timing->p[istep]; } } }//for istep float timmean=timtot/nstep; info2("Timing is mean %.3f, max %.3f min %.3f. BW is %.1f of 51.2GB/s\n", timmean*1e3, timmax*1e3, timmin*1e3, nrep*(nact*ng+nact+ng)*sizeof(float)/timmean/(1024*1024*1024)); writebin(timing, "cpu_timing_%s", HOST); if(nstep==1){ writearr("cpu_pix", 1, sizeof(short), M_INT16, NULL, pix, totpix, 1); writearr("cpu_pixbias", 1, sizeof(short), M_INT16, NULL, pixbias, totpix, 1); writebin(dm, "cpu_dm"); writebin(grad, "cpu_grad"); writebin(mvm, "cpu_mvm"); writebin(mtch, "cpu_mtch"); } }
/** * * Given an absolute path to a file/directory * (i.e., /foo/bar ---all paths will start with the root directory, "/"), * you need to return the file attributes that is similar stat system call. * * However you don't need to fill all the attributes except file size, * file size in blocks and block size of file system. * * You can ignore the 'st_dev', 'st_blksize' and 'st_ino' fields * (FUSE ignore these values and for more information look into fuse.h file). * * For st_mode you have to send the S_IFDIR if the entry is directory * or S_IFREG if it is a simple file * * Since we are not implementing permissions, * we pass fixed values to st_uid (5), st_gid(500) entries. * * We are also not implementing hard links, * so set the st_nlinks to 3 (just as safe side). * * Its up to you to implemet the time fields (st_atime, st_mtime, st_ctime), * if didn't impement them just return current time. * * The only thing you would be returning correctly is the file size and * size in blocks (st_size, st_blocks) and file system block size (st_blksize) * * The following are common steps to implement this function: * 1. Resolve the directory path -- this * will probably involve reading each directory in the path to get * the location of the file entry (or location of data block with * the file's inode) of the specified file. * * 2. Fill the file size, file size in blocks, block size information * * You should return 0 on success or -1 on error (e.g., the path doesn't * exist). */ static int xmp_getattr(const char *path, struct stat *stbuf) { /* * I am setting some pluasible values but you can change the following to * other values. */ stbuf->st_nlink = 3; stbuf->st_uid = 5; stbuf->st_gid = 500; stbuf->st_rdev = 0; stbuf->st_atime = time(NULL); stbuf->st_mtime = time(NULL); stbuf->st_ctime = time(NULL); stbuf-> st_blksize = BLOCKSIZE; /* you have to implement the following fields correctly if (The path represents the directory) stbuf->st_mode = 0777 | S_IFDIR; else stbuf->st_mode = 0777 | S_IFREG; stbuf->st_size = // file size stbuf->st_blocks = // file size in blocks stbuf->st_blksize = // block size of you file system */ char *tok_pt; int inum = -1; int datanum = 0; //root at data blck zero //if root dir if(strlen(path) < 2 ){ Inode *root_data = (Inode*) malloc(sizeof(Inode) * INODE_AMT); Inode *initptr = root_data; if(dread(global_fd, INODE_OFFSET, root_data) < 0){ printf("Read fail at Line %d \n",__LINE__); } root_data+=2; stbuf->st_size = root_data->f_size; stbuf->st_blocks = root_data->total_blck; stbuf->st_blksize = 512; if(root_data->f_type){ stbuf->st_mode = 0777 | S_IFDIR; } datanum = root_data->block_pt[0]; //free(initptr); printf("finish fetching from root dir \n"); return 0; }else { //if dir is not root or some other dir for(tok_pt = strtok(path, "/"); tok_pt!=NULL; tok_pt=(NULL, "/")){ printf("Finding file %s of the path: %s \n", tok_pt, path); if(strlen(tok_pt) < 2){ break; } Directory *my_dir = (Directory*)malloc(sizeof(Directory) * DIR_AMT); Directory *init_dir = my_dir; if(dread(global_fd, DATA_OFFSET + datanum, my_dir) < 0){ printf("Read fail at datablck %d \n", datanum); return -1; } //search the directory if((inum = search_dir(tok_pt, datanum)) < 0){ printf("Unable to find the file in dir\n"); return -2; } Inode *ibuf = (Inode*)malloc(sizeof(Inode) * INODE_AMT); Inode *init_ibuf = ibuf; if(dread(global_fd, INODE_OFFSET + inum/INODE_AMT , init_ibuf) < 0){ printf("Read inode fail at inum blck: %d, @Line: %d \n", INODE_OFFSET+ inum/INODE_AMT , __LINE__ ); return -1; } ibuf+= inum % INODE_AMT; printf("Pull from inum number %d, pointing to: %d and inode amt: %d \n" ,inum, inum%INODE_AMT, INODE_AMT); stbuf->st_size = ibuf->f_size; stbuf->st_blocks = ibuf->total_blck; stbuf->st_blksize = 512; printf("Assigning file type: %d from inum %d \n", ibuf->f_type, ibuf->inode_num); if(ibuf->f_type){ printf("This dir is a directory \n"); stbuf->st_mode = 0777 | S_IFDIR; datanum = ibuf->block_pt[0]; }else { printf("This dir is just a regular file\n"); stbuf->st_mode = 0777 | S_IFREG; } DEBUG_ME; } } printf("finish fetching from %s \n", path); return 0; }
/** * Given an absolute path to a directory (which may or may not end in * '/'), xmp_mkdir will create a new directory named dirname in that * directory. Ignore the mode parameter as we are not implementing * the permissions. The steps your implementation will do to make a new * directory will be the following: * * 1. Resolve the directory path * * 2. Allocate and initialize a new directory block * * 3. Update the directory block for 'path' by adding an entry for * the newly created directory. * * 4. You also need to create appropriate entries for "." and ".." in the * New directory * * You should return 0 on success or -1 on error (e.g., the path doesn't * exist, or dirname already does). * */ static int xmp_mkdir(const char *path, mode_t mode) { printf("Start creating directory \n"); int *tup = traverse_dir_w(path); int dir_inum = tup[0]; int dir_dnum = tup[1]; //pull the corresponding dir data blck Directory *dir_buf = (Directory*)malloc(sizeof(Directory) * DIR_AMT); Directory *init_dbuf = dir_buf; char* last_path; for(char* path_pt = strtok(path,"/"); path_pt!=NULL; path_pt = strtok(NULL,"/")){ last_path = path_pt; } if(dread(global_fd, dir_dnum + DATA_OFFSET, init_dbuf) < 0){ RFAIL; return -1; } //finding free inode and dblck for dir int free_inum = assign_bitmap(IMAP_OFFSET); int free_dnum = assign_bitmap(DMAP_OFFSET); printf("Assigning inum : %d, Assigning dnum: %d\n", free_inum, free_dnum); for(int i = 0; i < DIR_AMT; i++){ //finding free blck if(strlen(dir_buf->f_name) < 1){ strcpy(dir_buf->f_name, last_path); dir_buf->inode_num = free_inum; break; } dir_buf++; } //writing into previous dir block before I forgot to do so lol if(dwrite(global_fd, dir_dnum + DATA_OFFSET, init_dbuf) < 0){ RFAIL; return -1; } free(init_dbuf); //make a data block a into a Directory and insert inum of previous and current //into . and .. Directory* new_dbuf = (Directory*)malloc(sizeof(Directory) * DIR_AMT); Directory* init_new_dbuf = new_dbuf; for(int i = 0; i < DIR_AMT; i++){ if(i == 0){ strcpy(new_dbuf->f_name, "."); new_dbuf->inode_num = free_inum; }else if(i == 1){ strcpy(new_dbuf->f_name, ".."); new_dbuf->inode_num = dir_inum; }else { strcpy(new_dbuf->f_name, ""); new_dbuf->inode_num = -1; } new_dbuf++; } if(dwrite(global_fd, DATA_OFFSET + free_dnum, init_new_dbuf) < 0 ){ RFAIL; return -1; } free(init_new_dbuf); //configure inode according to dir Inode *ibuf = (Inode*)malloc(sizeof(Inode) * INODE_AMT); Inode *init_ibuf = ibuf; if(dread(global_fd, INODE_OFFSET + free_inum/INODE_AMT, init_ibuf) < 0){ RFAIL; return -1; } ibuf+=free_inum%(INODE_AMT); ibuf->f_size = 512; ibuf->total_blck = 1; ibuf->block_pt[0] = free_dnum; ibuf->f_type = 1; if(dwrite(global_fd, INODE_OFFSET + free_inum/INODE_AMT, init_ibuf) < 0){ WFAIL; return -1; } return 0; }
unsigned int getRecordsStored() { char buffer[2]; dread(buffer, L_RECORDS, 2); return getUnsignedInt(buffer); }
unsigned int getInterval() { char buffer[2]; dread(buffer, L_INTERVAL, 2); return getUnsignedInt(buffer); }
unsigned int getLocationOfCurrent() { char buffer[2]; dread(buffer, L_CURRENT, 2); return getUnsignedInt(buffer); }
int read_struct (int blocknum, void *structp){ int bytes_read = dread(blocknum, (char *)structp); return bytes_read; }
/** Generate stars for nsky star fields from star catalog. \return a cell array of nskyx1, each cell contains (2+nwvl) x nstar array of location, and magnitudes. */ dcell *genstars(long nsky, /**<number of star fields wanted*/ double lat, /**<galactic latitude.*/ double lon, /**<galactic longitude*/ double catscl, /**<Scale the catlog star count.*/ double fov, /**<diameter of the patrol field of view in arcsec.*/ int nwvl, /**<number of wavelength*/ double *wvls, /**<wavelength vector*/ rand_t *rstat /**<random stream*/ ){ char fn[80]; double cat_fov=0;/*catalogue fov */ int Jind=-1; if(nwvl==2 && fabs(wvls[0]-1.25e-6)<1.e-10 && fabs(wvls[1]-1.65e-6)<1.e-10){ snprintf(fn,80,"besancon/JH_5sqdeg_lat%g_lon%g_besancon.bin", lat, lon); cat_fov=5.0;/*5 arc-degree squared. */ Jind=0; }else if(nwvl==3 && fabs(wvls[0]-1.25e-6)<1.e-10 && fabs(wvls[1]-1.65e-6)<1.e-10 && fabs(wvls[2]-2.2e-6)<1.e-10){ snprintf(fn,80,"besancon/JHK_5sqdeg_lat%g_lon%g_besancon.bin", lat, lon); cat_fov=5.0;/*5 arc-degree squared. */ Jind=0; }else{ Jind=-1; error("We only have stars for J+H and J+H+K band. Please fill this part\n"); } info("Loading star catalogue from %s\n",fn); dmat *catalog=dread("%s",fn); if(catalog->ny!=nwvl){ error("Catalogue and wanted doesn't match\n"); } long ntot=catalog->nx; long nsky0=0; dcell *res=dcellnew(nsky,1); dmat* pcatalog=catalog; double fov22=pow(fov/2/206265,2); double navg0=M_PI*pow(fov/2./3600.,2)/cat_fov * ntot; if(catscl>0){//regular sky coverage sim double navg=navg0*catscl; info("Average number of stars: %g, after scaled by %g\n", navg, catscl); /*generate nstart && magnitude according to distribution.*/ for(long isky=0; isky<nsky; isky++){ long nstar=randp(rstat, navg); if(nstar==0) continue; res->p[isky]=dnew(nwvl+2, nstar); dmat* pres=res->p[isky]; for(long istar=0; istar<nstar; istar++){ long ind=round(ntot*randu(rstat));/*randomly draw a star index in the catlog */ for(int iwvl=0; iwvl<nwvl; iwvl++){ P(pres,2+iwvl,istar)=P(pcatalog,ind,iwvl); } } } }else{ /*instead of doing draws on nb of stars, we scan all possibilities and assemble the curve in postprocessing. catscl is negative, with absolute value indicating the max number of J<=19 stars to consider*/ long nmax=round(-catscl); nsky0=nsky/nmax; if(nsky0*nmax!=nsky){ error("nsky=%ld, has to be dividable by max # of stars=%ld", nsky, nmax); } int counti[nmax];//record count in each bin memset(counti, 0, sizeof(int)*nmax); int count=0; while(count<nsky){ long nstar=randp(rstat, navg0); if(nstar==0) continue; dmat *tmp=dnew(nwvl+2, nstar); dmat* pres=tmp; int J19c=0; for(long istar=0; istar<nstar; istar++){ long ind=round((ntot-1)*randu(rstat)); for(int iwvl=0; iwvl<nwvl; iwvl++){ P(pres,2+iwvl,istar)=P(pcatalog,ind,iwvl); } if(P(pres,2+Jind,istar)<=19){ J19c++; } } //J19c=0 is ok. Do not skip. if(J19c<nmax && counti[J19c]<nsky0){ int isky=counti[J19c]+(J19c)*nsky0; res->p[isky]=dref(tmp); count++; counti[J19c]++; } dfree(tmp); } } /*Fill in the coordinate*/ for(long isky=0; isky<nsky; isky++){ if(!res->p[isky]) continue; long nstar=res->p[isky]->ny; dmat* pres=res->p[isky]; for(long istar=0; istar<nstar; istar++){ /*randomly draw the star location. */ double r=sqrt(fov22*randu(rstat)); double th=2*M_PI*randu(rstat); P(pres,0,istar)=r*cos(th); P(pres,1,istar)=r*sin(th); } } dfree(catalog); return res; }
/* * The function vfs_write will attempt to write 'size' bytes from * memory address 'buf' into a file specified by an absolute 'path'. * It should do so starting at the specified offset 'offset'. If * offset is beyond the current size of the file, you should pad the * file with 0s until you reach the appropriate length. * * You should return the number of bytes written. * * HINT: Ignore 'fi' */ static int vfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { // First, we ensure thepath is valid. if(validate_path(path) != 0) return -1; vcb vb = getvcb(); path++; // Get rid of leading slash in path int byteswritten = 0; // Amount of bytes we've written to disk from buffer int num_pad = 0; // Amount of 0s we need to pad between EOF and offset int write_offset = 0; // variable to hold an offset for vfs_write. dirent de; int found_dirent = 0; int dirent_index = -1; for(int i = vb.de_start; i < vb.de_start + vb.de_length, found_dirent == 0; i++){ de = getdirent(i); if(de.valid == 1) if(strcmp(path,de.name)==0){ found_dirent = 1; dirent_index = i; } } if(found_dirent){ // Begin writing to disk. if(offset > de.size){ // Check for padding. num_pad = (offset - de.size); // Number of 0's to add. } if((size + offset) > de.size){ de.size = (size + offset); // Set the new size of the file. } // Update access modify times of file struct timespec newtime; clock_gettime(CLOCK_REALTIME, &newtime); de.access_time = newtime; de.modify_time = newtime; /* Next, since we have our dirent to write to, we must: - Check to see if the dirent has a FAT entry allocated. - Attempt to allocate one if necessary. x If the dirent has at least one FAT entry, begin writing: x Begin traversing offset, decrementing it as necessary until offset == 0. x Attempt to create new FAT entries if necessary. x Begin padding the file with zeros, if necessary, decrementing num_pad until it == 0. x Attempt to create new FAT entries if necessary. x Begin appending buf to file, decrementing size while doing so. x Attempt to create new FAT entries if necessary. x If, in any of the above cases, creating a new FAT entry fails, return -ENOSPC. */ // Check if found dirent has allocated FAT. If not, attempt to allocate one. if((int) de.first_block == -1){ char block[BLOCKSIZE]; int found_free = 0; for(int i = vb.fat_start;(i < vb.fat_start + ((int) (vb.fat_length/128))) && found_free == 0; i++){ // For each fat block... int block_index = (i-vb.fat_start)*128; memset(block,0,BLOCKSIZE); // Reset block. dread(i, block); // Read FAT Block into block. for(int j = 0; j < 128 && found_free == 0; j++){ fatent fe = getfe( block_index + j); if(fe.used == 0){ de.first_block = block_index + j; fe.used = 1; fe.eof = 1; fe.next = 0; found_free = 1; } } } if(found_free != 1){ return -ENOSPC; } } fatent fe = getfe(de.first_block); char block[BLOCKSIZE]; memset(block,0,BLOCKSIZE); // Expand file and pad 0's, if necessary. if(num_pad > 0){ int eof_fat_idx = get_eof_fe(&fe) + vb.db_start;// find index of eof dread(eof_fat_idx,block); int eof_data_idx; for(int i = 0; block[i] != EOF; i++) eof_data_idx++; eof_data_idx++; // Increment counter so block[eof_data_idx] == EOF. while(num_pad > 0){ if(eof_data_idx < BLOCKSIZE){ memset(&block[eof_data_idx],0,1); eof_data_idx++; num_pad--; if(num_pad == 0){ dwrite(eof_data_idx,block); memset(block,0,BLOCKSIZE); } } else{ dwrite(eof_fat_idx,block); memset(block,0,BLOCKSIZE); if(allocate_fat(&fe) != 0){ return -ENOSPC; } eof_fat_idx = get_eof_fe(&fe) + vb.db_start; eof_data_idx = 0; } } } // Now, we need to start writing size chars from buf into the file, starting at offset // Start by finding where offset is in the datablock. int offset_block = (int)(offset/512); int offset_into_block = offset % 512; int buffer_offset = 0; // Read in offset block, write at offset into block memset(block,0,BLOCKSIZE); dread(offset_block + vb.db_start, block); // Memcpy the rest of the block, or size bytes, whichever bounds first while(offset_into_block < BLOCKSIZE && size > 0){ memcpy(&block[offset_into_block], buf, 1); size--; buf++; buffer_offset++; offset_into_block++; byteswritten++; } // Write block rest of block dwrite(offset_block + vb.db_start, block); // While there remains bytes to be written... while(size > 0){ if(offset_into_block == BLOCKSIZE){ // Write block dwrite(offset_block + vb.db_start, block); // Allocate new fat/data block if(allocate_fat(&fe) != 0){ return -ENOSPC; } // reset offset_into_block offset_into_block = 0; offset_block = get_eof_fe(&fe); memset(block,0,BLOCKSIZE); } memcpy(&block[offset_into_block], &buf[buffer_offset], 1); size--; buffer_offset++; offset_into_block++; byteswritten++; } // Write the rest of size bytes dwrite(offset_block + vb.db_start, block); setdirent(dirent_index,de); return byteswritten; } else{ // No free dirents found return -1; } }
long setup_star_read_ztilt(STAR_S *star, int nstar, const PARMS_S *parms, int seed){ const double ngsgrid=parms->maos.ngsgrid; long nstep=0; TIC;tic; for(int istar=0; istar<nstar; istar++){ STAR_S *stari=&star[istar]; int npowfs=parms->maos.npowfs; stari->ztiltout=dcellnew(npowfs, 1); const double thetax=stari->thetax*206265;/*in as */ const double thetay=stari->thetay*206265; double thxnorm=thetax/ngsgrid; double thynorm=thetay/ngsgrid; long thxl=(long)floor(thxnorm);/*Used to be double, but -0 appears. */ long thyl=(long)floor(thynorm); double wtx=thxnorm-thxl; double wty=thynorm-thyl; for(int ipowfs=0; ipowfs<npowfs; ipowfs++){ const int msa=parms->maos.msa[ipowfs]; const int nsa=parms->maos.nsa[ipowfs]; const int ng=nsa*2; char *fnztilt[2][2]={{NULL,NULL},{NULL,NULL}}; char *fngoff[2][2]={{NULL, NULL}, {NULL, NULL}}; double wtsum=0; for(int ix=0; ix<2; ix++){ double thx=(thxl+ix)*ngsgrid; for(int iy=0; iy<2; iy++){ double thy=(thyl+iy)*ngsgrid; double wtxi=fabs(((1-ix)-wtx)*((1-iy)-wty)); if(wtxi<0.01){ /*info("skipping ix=%d,iy=%d because wt=%g\n",ix,iy,wtxi); */ continue; } fnztilt[iy][ix]=myalloca(PATH_MAX, char); if(parms->skyc.usephygrad){ warning_once("Using phygrad\n"); snprintf(fnztilt[iy][ix],PATH_MAX,"%s/phygrad/phygrad_seed%d_sa%d_x%g_y%g", dirstart,seed,msa,thx,thy); }else{ snprintf(fnztilt[iy][ix],PATH_MAX,"%s/ztiltout/ztiltout_seed%d_sa%d_x%g_y%g", dirstart,seed,msa,thx,thy); } fngoff[iy][ix]=myalloca(PATH_MAX, char); snprintf(fngoff[iy][ix],PATH_MAX,"%s/gradoff/gradoff_sa%d_x%g_y%g", dirstart,msa,thx,thy); if(!zfexist(fnztilt[iy][ix])){ //warning("%s doesnot exist\n",fnwvf[iy][ix]); fnztilt[iy][ix]=fngoff[iy][ix]=NULL; }else{ wtsum+=wtxi; } } } if(wtsum<0.01){ error("PSF is not available for (%g,%g). wtsum=%g\n",thetax,thetay, wtsum); } /*Now do the actual reading */ for(int ix=0; ix<2; ix++){ for(int iy=0; iy<2; iy++){ double wtxi=fabs(((1-ix)-wtx)*((1-iy)-wty))/wtsum; if(fnztilt[iy][ix]){ file_t *fp_ztilt=zfopen(fnztilt[iy][ix],"rb"); header_t header={0,0,0,0}; read_header(&header, fp_ztilt); if(iscell(&header.magic)){ // error("expected data type: %u, got %u\n",(uint32_t)MCC_ANY, header.magic); nstep=header.nx; free(header.str); if(stari->nstep==0){ stari->nstep=nstep; }else{ if(stari->nstep!=nstep){ error("Different type has different steps\n"); } } if(!stari->ztiltout->p[ipowfs]){ stari->ztiltout->p[ipowfs]=dnew(ng, nstep); } dmat *ztiltout=stari->ztiltout->p[ipowfs]; for(long istep=0; istep<nstep; istep++){ dmat *ztilti=dreaddata(fp_ztilt, 0); for(int ig=0; ig<ng; ig++){ ztiltout->p[ig+istep*ng]+=ztilti->p[ig]*wtxi; } dfree(ztilti); } }else{ dmat *tmp=dreaddata(fp_ztilt, &header); dadd(&stari->ztiltout->p[ipowfs], 1, tmp, wtxi ); dfree(tmp); } zfclose(fp_ztilt); }/* if(fnwvf) */ if(fngoff[iy][ix] && zfexist(fngoff[iy][ix])){ if(!stari->goff){ stari->goff=dcellnew(npowfs, 1); } dmat *tmp=dread("%s", fngoff[iy][ix]); dadd(&stari->goff->p[ipowfs], 1, tmp, wtxi); dfree(tmp); } }/*iy */ }/*ix */ }/*ipowfs */ }/*istar */ if(parms->skyc.verbose){ toc2("Reading PSF"); } //close(fd); return nstep; }