static s64_t sbp_read_or_write(s64_t fd, void* buf, u64_t len, char* method) { if (fds[fd] == NULL) return -1; char tran_fd[32]; char tran_offset[32]; char tran_len[32]; s64_t ret = -1; SBP_PREPARE_REQUEST sprintf(tran_fd, "%lld", fds[fd]->server_fd); sprintf(tran_offset, "%lld", fds[fd]->offset); sprintf(tran_len, "%lld", len); mkent(head,METHOD,method); mkent(head,ARGC,"3"); mkent(head,"Arg0",tran_fd); mkent(head,"Arg1",tran_offset); mkent(head,"Arg2",tran_len); mkent(head,CONTENT_LEN,"0"); SBP_SEND_AND_PROCESS_REPLY if (strncmp(head.title, REQUEST_OK, strlen(REQUEST_OK)) == 0) { u64_t content_l = -1; char* value = get_head_entry_value(&head, CONTENT_LEN); if (value == NULL) { seterr(HEAD_ERR,NO_CONTENT_LEN); goto err_exit3; } content_l = atoll(value); if (content_l % sizeof(struct block_entry)) { printf("content l :%lld :%ld\n", content_l, sizeof(struct block_entry)); seterr(DATA_ERR,DATA_LEN); goto err_exit3; } u64_t block_ent_num = content_l / sizeof(struct block_entry); struct block_entry* ents = (struct block_entry*) (rec_data + head.head_len); if (strcmp(method, "WRITE") == 0) { ret = write_blocks(ents, block_ent_num, buf, fds[fd]->auth_code); } else if (strcmp(method, "READ") == 0) { ret = read_blocks(ents, block_ent_num, buf, fds[fd]->auth_code); } if (ret >= 0){ fds[fd]->offset += ret; //printf("fds offset :%lld\n",fds[fd]->offset); } goto ok_exit; } else if (strncmp(head.title, REQUEST_ERR, strlen(REQUEST_ERR)) == 0) { sbp_update_err(&head); goto err_exit3; } else { seterr(HEAD_ERR, UNKNOWN_HEAD); } err_exit3: free_head(&head); err_exit2: free(rec_data); err_exit1: free(data); err_exit: free(usr); free(pass); return ret; ok_exit: free(data); free(rec_data); free_head(&head); free(usr); free(pass); return ret; }
/* returns negative value on error file is name of the disk that was given to testfs. this function initializes all the in memory data structures maintained by the sb block. */ int testfs_init_super_block(const char *file, int corrupt, struct super_block **sbp) { struct super_block *sb = malloc(sizeof(struct super_block)); char block[BLOCK_SIZE]; int ret, sock; if (!sb) { return -ENOMEM; } if ((sock = open(file, O_RDWR #ifndef DISABLE_OSYNC | O_SYNC #endif )) < 0) { return errno; } else if ((sb->dev = fdopen(sock, "r+")) == NULL) { return errno; } // sb->dev type = FILE // read from sb into block. read_blocks(sb, block, 0, 1); // copy only 24 bytes from block corresponding to dsuper_block _memcpy(&sb->sb, block, sizeof(struct dsuper_block)); // 64 * 1 * 8 // bitmap create will return a inode_bitmap structure. // and point sb->inode_freemap to that structure. // currently the inode bitmap is all 0. // at the end of this function, bitmap is created in memory ret = bitmap_create(BLOCK_SIZE * INODE_FREEMAP_SIZE * BITS_PER_WORD, &sb->inode_freemap); if (ret < 0) return ret; // bitmap_getdata returns v -> the byte array containing bit info // read_blocks reads sb->v into sb at offset freemap_start till // INODE_FREEMAP_SIZE // sb is only sent to read_blocks since we need the sb device handle. // data from sb->dev is used to populate arg 2 sb->inode_freemap read_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); ret = bitmap_create(BLOCK_SIZE * BLOCK_FREEMAP_SIZE * BITS_PER_WORD, &sb->block_freemap); if (ret < 0) return ret; read_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); sb->csum_table = malloc(CSUM_TABLE_SIZE * BLOCK_SIZE); if (!sb->csum_table) return -ENOMEM; read_blocks(sb, (char *) sb->csum_table, sb->sb.csum_table_start, CSUM_TABLE_SIZE); sb->tx_in_progress = TX_NONE; /* inode_hash_init() initializes inode_hash_table of size 256 bytes each entry of the inode table contains a first pointer. each node of the first pointer has a prev pointer and a next pointer. */ inode_hash_init(); *sbp = sb; return 0; }
/* given logical block number, read the corresponding physical block into block. * return physical block number. * returns 0 if physical block does not exist. * returns negative value on other errors. */ static int testfs_read_block(struct inode *in, int log_block_nr, char *block) { //printf("log_block_nr:%d\n",log_block_nr); int phy_block_nr = 0; assert(log_block_nr >= 0); // when log block number is less 0~9 if (log_block_nr < NR_DIRECT_BLOCKS) { phy_block_nr = (int)in->in.i_block_nr[log_block_nr]; } else { log_block_nr -= NR_DIRECT_BLOCKS; if (log_block_nr >= NR_INDIRECT_BLOCKS) { //need to implement DID part, not done yet. if (in->in.i_dindirect > 0) { log_block_nr -= NR_INDIRECT_BLOCKS; //log block ranges from 0 ~ 4194303 int level1_block = DIVROUNDUP(log_block_nr + 1,2048) - 1; // ranges 0~2047 int level2_block= log_block_nr % 2048; read_blocks(in->sb, block, in->in.i_dindirect, 1); if (((int*)block)[level1_block]!=0) { read_blocks(in->sb, block, ((int*)block)[level1_block], 1); if (((int*)block)[level2_block]!=0) { phy_block_nr = ((int *)block)[level2_block]; read_blocks(in->sb, block, phy_block_nr, 1); return phy_block_nr; } } } return phy_block_nr; } if (in->in.i_indirect > 0) { read_blocks(in->sb, block, in->in.i_indirect, 1); phy_block_nr = ((int *)block)[log_block_nr]; } } if (phy_block_nr > 0) { read_blocks(in->sb, block, phy_block_nr, 1); } else { /* we support sparse files by zeroing out a block that is not * allocated on disk. */ bzero(block, BLOCK_SIZE); } return phy_block_nr; }
void sfs_write(int fd, char *buf, int length){ int i; int position = 0; int maxLength; int apendLength; int FATi; int currFATi; int newBlock; writeLength = length; currmyfile = fd; writeBuff = (char *) malloc(length); appendBuff = (char *) malloc(1024 + length); for(i=0; i < writeLength; i++){ writeBuff[i] = buf[i]; } writeBuff[writeLength] = 0; myfile = directory[FDT[currmyfile].dirIndex]; rootFAT = myfile.indFAT; currFATi = rootFAT; for(i=0; i < 1024; i++){//get last block in myfile if(FDT[currmyfile].write - position > 1024){ position = position + 1024; currFATi = FAT[currFATi][1]; } } read_blocks(FAT[currFATi][0], 1, appendBuff); appendBuff[FDT[currmyfile].write - position] = 0; maxLength = FDT[currmyfile].write + writeLength; strcat(appendBuff, writeBuff); apendLength = FDT[currmyfile].write - position + writeLength; appendBuff[apendLength] = 0; for(i=0; i < apendLength;i++){ if(apendLength - 1024 <= 0){ write_blocks(FAT[currFATi][0],1,appendBuff); FAT[currFATi][1] = EOF; } else{ write_blocks(FAT[currFATi][0],1,appendBuff); appendBuff = appendBuff + 1024; apendLength = apendLength - 1024; newBlock = searchBlockSpace(); FATi = searchFAT(); if(newBlock > 0){ FAT[currFATi][1] = FATi; FAT[FATi][0] = newBlock; FAT[FATi][1] = EOF; free_list[newBlock] = '1'; currFATi = FATi; } else{ error = 1; } } } if(error != 1){ FDT[currmyfile].write = maxLength; directory[FDT[fd].dirIndex].date = time(NULL); directory[FDT[fd].dirIndex].size = directory[FDT[fd].dirIndex].size + length; updateDisk(); free(writeBuff); free(appendBuff); printf("Data writing successfull\n"); } else{ printf("ERROR!!!--end of free blocks\n"); } }
int sfs_fwrite(int fileID, const char *buf, int length){ int inode_index = dir_table[fileID].inode_number; int num_bytes_to_be_written=0; //index of rw pointers which points to the current block of inode int rw_index = file_des_t[fileID].rw_pointer/BLOCKSIZE+1; //rw pointer offset within its current block int rw_offset = file_des_t[fileID].rw_pointer%BLOCKSIZE; //calculate number of blocks to be written int num_blocks; if(length<BLOCKSIZE-rw_offset){ num_blocks=1; } else{ num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first & last partial blocks } //writing to an empty file. if(inodes[inode_index].pointers[0]==0){ //If file is empty all inode pointers will be zero int num_bytes_to_be_written = 0; int inode_index=dir_table[fileID].inode_number; int num_blocks=length/(BLOCKSIZE)+1; if(num_blocks<=(INODE_POINTERS-1)){ //don't need the indirect pointer int j; char write_block_buffer[BLOCKSIZE]; for(j=0;j<num_blocks-1;j++){ //reset buffer memset(write_block_buffer,0,BLOCKSIZE); memcpy(write_block_buffer,buf,BLOCKSIZE); inodes[inode_index].pointers[j]=findfreeblock(); int flag = write_blocks(inodes[inode_index].pointers[j],1,write_block_buffer); if(flag){ //if write into disk successfully,count the number of bytes written num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE; } //upodate the bitmap markfreeblock(inodes[inode_index].pointers[j]); } //last block could be a partial block char direct_pointer_buf_last[BLOCKSIZE]; memset(direct_pointer_buf_last,0,BLOCKSIZE); memcpy(direct_pointer_buf_last, buf+(num_blocks-1)*BLOCKSIZE, length % BLOCKSIZE); //find a free block for the last direct pointer int last_direct_pointer = findfreeblock(); markfreeblock(last_direct_pointer); inodes[inode_index].pointers[num_blocks-1] = last_direct_pointer; //if write into disk successfully then count the number of bytes int flag = write_blocks(last_direct_pointer,1,direct_pointer_buf_last); if(flag){ num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE; } //update the information in file descriptor table file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length; inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written; //update info on the disk int inode_number = inode_index; int block_of_inode=inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); return num_bytes_to_be_written; } else{ //else need the indirect pointer int m; char write_block_buffer[BLOCKSIZE]; //handle all the direct pointer firstly,similar as the above for(m=0;m<INODE_POINTERS-1;m++){ memset(write_block_buffer,0,BLOCKSIZE); memcpy(write_block_buffer,buf,BLOCKSIZE); inodes[inode_index].pointers[m]=findfreeblock(); int flag=write_blocks(inodes[inode_index].pointers[m],1,write_block_buffer); if(flag){num_bytes_to_be_written+=BLOCKSIZE;} markfreeblock(inodes[inode_index].pointers[m]); } //now let's handle the indirect pointer int num_indirect_pointers = num_blocks-(INODE_POINTERS-1); //get free blocks for indirect pointer int freeblock_indirect = findfreeblock(); markfreeblock(freeblock_indirect); int arr_of_indirectptr[num_indirect_pointers]; int k; //write the remaining data to the indirect blocks char indirect_pointer_buf[BLOCKSIZE]; for(k=0;k<num_indirect_pointers-1;k++){ arr_of_indirectptr[k] = findfreeblock(); memset(indirect_pointer_buf,0,BLOCKSIZE); memcpy(indirect_pointer_buf, buf+(INODE_POINTERS-1)*BLOCKSIZE + k*BLOCKSIZE, BLOCKSIZE); int flag=write_blocks(arr_of_indirectptr[k],1,indirect_pointer_buf); if(flag){num_bytes_to_be_written+=BLOCKSIZE;} markfreeblock(arr_of_indirectptr[k]); } //handle partial indirect block int last_indirect_pointers = findfreeblock(); arr_of_indirectptr[num_indirect_pointers-1] = last_indirect_pointers; markfreeblock(last_indirect_pointers); char last_indirect_pointer_buf[BLOCKSIZE]; memset(last_indirect_pointer_buf,0,BLOCKSIZE); memcpy(last_indirect_pointer_buf,buf+(INODE_POINTERS-1)*BLOCKSIZE+(num_indirect_pointers-1)*BLOCKSIZE,length%BLOCKSIZE); int flag = write_blocks(arr_of_indirectptr[num_indirect_pointers-1],1,last_indirect_pointer_buf); if(flag){ num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE; } //Write the indirect pointers to the indirect block char indirect_buffer[BLOCKSIZE]; memset(indirect_buffer,0,BLOCKSIZE); memcpy(indirect_buffer,arr_of_indirectptr,num_indirect_pointers*sizeof(int)); write_blocks(freeblock_indirect,1,indirect_buffer); inodes[inode_index].pointers[INODE_POINTERS-1]=freeblock_indirect; file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length; inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written; //update all the info into the disk int inode_number = inode_index; int block_of_inode = inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); return num_bytes_to_be_written; } } //file not empty int number_pointers; if(get_num_pointers_inode(inode_index)>INODE_POINTERS-1){ //first ignore the indrect pointers if it is used number_pointers = get_num_pointers_inode(inode_index)-1; } else{ number_pointers = get_num_pointers_inode(inode_index); } int array_blockptr[number_pointers]; get_pointers(inode_index,array_blockptr,number_pointers); int num_unchanged_blocks = rw_index; //Update all those blocks int updated_array_blockptr[num_blocks + num_unchanged_blocks]; memset(updated_array_blockptr,0,num_blocks*sizeof(int)); //Copy the unchanged blocks int p; for(p = 0; p < rw_index-1; p++){ updated_array_blockptr[p] = array_blockptr[p]; } int s; for(s=rw_index-1; s<((num_blocks+num_unchanged_blocks)-1); s++){ //Allocate additional free blocks when s>total intial blocks if(s>number_pointers-1){ //free block is not enough, find more if(s==(num_blocks+num_unchanged_blocks-2)){ //last block need to do a partial write int free_block = findfreeblock(); updated_array_blockptr[s] = free_block; markfreeblock(free_block); if(num_blocks==1){ update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length); num_bytes_to_be_written=num_bytes_to_be_written+length; } else{ if((BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)<0){ return -1;//write in last block } update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written + (length-(BLOCKSIZE-rw_offset)) % BLOCKSIZE; } } else{ int free_block = findfreeblock(); updated_array_blockptr[s] = free_block; markfreeblock(free_block); update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE; } } else{ markfreeblock(array_blockptr[s]); updated_array_blockptr[s] = array_blockptr[s]; if(s==rw_index-1){ //Overwriting the first block of write if(num_blocks==1){ //if only updating one block - will not be filling the first block of the write. update_block(array_blockptr[s],(char*)buf,rw_offset,length); num_bytes_to_be_written = num_bytes_to_be_written + length; } else{ update_block(array_blockptr[s],(char*)buf,rw_offset,BLOCKSIZE-rw_offset); num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE-rw_offset; } } else if(s==(num_blocks + num_unchanged_blocks-2)){ //last block may be partial if(num_blocks==1){ //special case for one block write. update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length); num_bytes_to_be_written = num_bytes_to_be_written+length; } else{ update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written+(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE; } } else{ //overwriting a full block update_block(array_blockptr[s],(char *)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written+BLOCKSIZE; } } } //storing the block pointers and put updated_array_blockptr into inode update_inode_pointers(inode_index,updated_array_blockptr,num_blocks+num_unchanged_blocks); int f_num_pointers = get_num_pointers_inode(inode_index); if(f_num_pointers > INODE_POINTERS-1){ //exclude superblock if it is used f_num_pointers--; } int final_inode_pointers[f_num_pointers]; get_pointers(inode_index,final_inode_pointers,f_num_pointers); file_des_t[fileID].rw_pointer+=length; inodes[inode_index].size = return_filesize(inode_index); //writing into disk int inode_number = inode_index; int block_of_inode=inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); return num_bytes_to_be_written; }
int sfs_remove(char *file){ int i; for(i=0;i<TOTAL_NUM_FILES;i++){ if(strncmp(dir_table[i].filename, file, MAXFILENAME)==0){//find the file to be removed in directory table //clear data int inode_index = dir_table[i].inode_number; int num_pointers_in_inode = get_num_pointers_inode(inode_index); int indirect_pointer = 0; if(num_pointers_in_inode>=INODE_POINTERS){ //get the indirect block address indirect_pointer = inodes[inode_index].pointers[INODE_POINTERS-1]; //and remove it from number of pointers num_pointers_in_inode--; } int array_blockptr[num_pointers_in_inode]; get_pointers(inode_index, array_blockptr,num_pointers_in_inode);//get all pointers in array_blockptr //remove indirect pointer if(indirect_pointer){ char buffer[BLOCKSIZE];//write a empty buffer into disk to overwrite indirect_pointer memset(buffer,0,BLOCKSIZE); write_blocks(indirect_pointer,1,buffer); set_freeblock(indirect_pointer);//set it free again } //handle other pointers //reset the inode INODE free_inode={ .mode=0, .link_cnt=0, .uid=0, .gid=0, .size=0, .pointers={0,0,0,0,0,0,0,0,0,0,0,0,0} //set all the pointers to 0 }; int n; char empty_block_buf[BLOCKSIZE]; for(n=0; n < num_pointers_in_inode; n++){ memset(empty_block_buf,0,BLOCKSIZE); write_blocks(array_blockptr[n],1,empty_block_buf); set_freeblock(array_blockptr[n]); } inodes[inode_index] = free_inode; write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); //update the free_bitmap //write the updated inode in disk int inode_number = inode_index; int block_of_inode=inode_number/8+1; char update_inode_buffer[BLOCKSIZE]; memset(update_inode_buffer,0, BLOCKSIZE); read_blocks(block_of_inode, 1, update_inode_buffer); memcpy((void *)update_inode_buffer+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, update_inode_buffer); //set information in directory table to 0 memset(dir_table[i].filename,0,MAXFILENAME); dir_table[i].inode_number=0; //update this information into disk char dir_entry_buffer[BLOCKSIZE]; int block_dir_entry=i/NUM_ENTRIES_PERBLOCK+8+1; memset(dir_entry_buffer,0, BLOCKSIZE); read_blocks(block_dir_entry, 1, dir_entry_buffer); memcpy((void *)dir_entry_buffer+(i%21)*sizeof(dir_entry),(const void *) &dir_table[i], sizeof(dir_entry)); write_blocks(block_dir_entry,1,dir_entry_buffer); //clear file descriptor table file_des_t[inode_index-1].open=0; file_des_t[inode_index-1].rw_pointer=0; return 0; } } //files does not exist, return -1 return -1; }
uint64_t write_file(file_descriptor* fd, void* buf, uint64_t length) { // Store number of bytes written. uint64_t written = 0; int read_error, write_error; // Pull inode. inode_t* inode = &table[fd->inode]; // Allocate room for a block size in memory. void* block = (void*)malloc(BLOCK_SZ); // Write from block at RW pointer until length is complete. int starting_block_index = fd->rwptr / BLOCK_SZ; int current_block_count = starting_block_index; while (length) { // Get block index. int block_index = get_block_at(inode, current_block_count, true); if (block_index < 0) { perror("write_file()"); break; } // Read from block. clear_block(block, 0, BLOCK_SZ); read_error = read_blocks(block_index, 1, block); if (read_error < 0) { perror("write_file(): read chunk from block"); break; } // Modify block in memory. for (int j = fd->rwptr % BLOCK_SZ; j < BLOCK_SZ; j++) { // Copy current byte into buffer. memcpy(block + j, buf, 1); // Increment pointers. fd->rwptr += 1; buf += 1; // Increment number written. written += 1; // Decrement length. length -= 1; if (length == 0) { // Done in the middle of a block. break; } } // Write block. write_error = write_blocks(block_index, 1, block); if (write_error < 0) { perror("write_file(): write chunk to block"); break; } // Increment block. current_block_count += 1; } // Free block. free(block); // Update inode size. if (fd->rwptr > inode->size) { inode->size = fd->rwptr; } // Write inodes and free blocks. write_inode_table(); write_free_blocks(); // Return number of bytes written. return written; }
static gboolean sync_read (f_str_t * in, void *arg) { struct rspamd_sync_ctx *ctx = arg; gchar buf[256]; guint64 rev = 0; time_t ti = 0; if (in->len == 0) { /* Skip empty lines */ return TRUE; } switch (ctx->state) { case SYNC_STATE_GREETING: /* Skip greeting line and write sync command */ /* Write initial data */ statfile_get_revision (ctx->real_statfile, &rev, &ti); rev = rspamd_snprintf (buf, sizeof (buf), "sync %s %uL %T" CRLF, ctx->st->symbol, rev, ti); ctx->state = SYNC_STATE_READ_LINE; return rspamd_dispatcher_write (ctx->dispatcher, buf, rev, FALSE, FALSE); break; case SYNC_STATE_READ_LINE: /* Try to parse line from server */ if (!parse_revision_line (ctx, in)) { msg_info ("cannot parse line of length %z: '%*s'", in->len, (gint)in->len, in->begin); close (ctx->sock); rspamd_remove_dispatcher (ctx->dispatcher); ctx->is_busy = FALSE; return FALSE; } else if (ctx->state != SYNC_STATE_QUIT) { if (ctx->new_len > 0) { ctx->state = SYNC_STATE_READ_REV; rspamd_set_dispatcher_policy (ctx->dispatcher, BUFFER_CHARACTER, ctx->new_len); } } else { /* Quit this session */ msg_info ("sync ended for: %s", ctx->st->symbol); close (ctx->sock); rspamd_remove_dispatcher (ctx->dispatcher); ctx->is_busy = FALSE; /* Immediately return from callback */ return FALSE; } break; case SYNC_STATE_READ_REV: /* In now contains all blocks of specified revision, so we can read them directly */ if (!read_blocks (ctx, in)) { msg_info ("cannot read blocks"); close (ctx->sock); rspamd_remove_dispatcher (ctx->dispatcher); ctx->is_busy = FALSE; return FALSE; } statfile_set_revision (ctx->real_statfile, ctx->new_rev, ctx->new_time); msg_info ("set new revision: %uL, readed %z bytes", ctx->new_rev, in->len); /* Now try to read other revision or END line */ ctx->state = SYNC_STATE_READ_LINE; rspamd_set_dispatcher_policy (ctx->dispatcher, BUFFER_LINE, 0); break; case SYNC_STATE_QUIT: close (ctx->sock); rspamd_remove_dispatcher (ctx->dispatcher); ctx->is_busy = FALSE; return FALSE; } return TRUE; }
int sfs_fread(int fileID, char *buf, int length){ if (check_open(fileID) == 0){ printf("Can't write, file not opened\n"); return -1; } //SETTING UP META INFO FOR EASY ACCESS int blk_inode = fd_table[fileID].inode; //inode index of file we are reading from int read_ptr = fd_table[fileID].rptr; //read pointer in bytes int blk_offset = read_ptr % BLOCK_SIZE; //offset in bytes of the wptr within the first block int blk_index = read_ptr / BLOCK_SIZE; //inode pointer of first block we start to read from int block_nmb; /*printf("===================================\n"); printf("Read Pointer is at : %d\n", read_ptr); printf("Length taken as argument: %d\n", length); printf("File size: %d\n", inode_table[blk_inode].size);*/ if (inode_table[blk_inode].size == 0){ printf("File is empty, nothing to read\n"); free(buffer); return 0; } if ((read_ptr + length) > inode_table[blk_inode].size) { length = inode_table[blk_inode].size - read_ptr; } buffer = (void*) malloc(BLOCK_SIZE); int nmb_of_bytes_read = 0; block_nmb = fetch_block(blk_inode, blk_index); //====================if the data we want to read is less than a block======================== if ((blk_offset + length) < BLOCK_SIZE){ read_blocks(block_nmb,1,buffer); memcpy(buf, (buffer+blk_offset), length); //copy to buf only starting from offset nmb_of_bytes_read += length; //====================if the data we want to read is more than a block======================== }else{ // (1) READING REST OF FIRST BLOCK WHERE RPTR IS TO BUFFER read_blocks(block_nmb,1,buffer); memcpy(buf, (buffer+blk_offset), (BLOCK_SIZE - blk_offset)); //copy to buf only starting from offset blk_index++; nmb_of_bytes_read += BLOCK_SIZE - blk_offset; // (2) READING THE FULL BLOCKS int nmb_of_fullblocks = (length - (BLOCK_SIZE - blk_offset)) / BLOCK_SIZE; for (int i = 0; i < nmb_of_fullblocks; i++){ block_nmb = fetch_block(blk_inode, blk_index); read_blocks(block_nmb,1,buffer); memcpy((buf + nmb_of_bytes_read),buffer,BLOCK_SIZE); nmb_of_bytes_read += BLOCK_SIZE; blk_index++; } // (3) READING THE LAST BLOCK block_nmb = fetch_block(blk_inode, blk_index); read_blocks(block_nmb,1,buffer); memcpy(buf + nmb_of_bytes_read, buffer, length - nmb_of_bytes_read); nmb_of_bytes_read += length - nmb_of_bytes_read; } //printf("Number of bytes read: %d\n", nmb_of_bytes_read); //printf("\nIn buf:\n%s\n", buf); //END THE READ //printf("String Length:%lu\n", strlen(buf)); //printf("Length:%d\n", length); free(buffer); return length; }
uint64_t read_file(file_descriptor* fd, void* buf, uint64_t length) { // Store number of bytes read. uint64_t read = 0; int read_error; // Pull inode. inode_t* inode = &table[fd->inode]; // Allocate room for a block size in memory. void* block = (void*)malloc(BLOCK_SZ); // Read from block at RW pointer until length is complete. int starting_block_index = fd->rwptr / BLOCK_SZ; int current_block_count = starting_block_index; while (length) { // Get block index. int block_index = get_block_at(inode, current_block_count, false); if (block_index < 0) { perror("read_file()"); break; } // Read from block. clear_block(block, 0, BLOCK_SZ); read_error = read_blocks(block_index, 1, block); if (read_error < 0) { perror("read_file(): read chunk from block"); break; } // Modify block in memory. for (int j = fd->rwptr % BLOCK_SZ; j < BLOCK_SZ; j++) { // Check if EOF. if (fd->rwptr == inode->size) { // Reached end of file. Done. break; } // Copy current byte into buffer. memcpy(buf, block + j, 1); // Increment pointers. fd->rwptr += 1; buf += 1; // Increment number of bytes read. read += 1; // Decrement length. length -= 1; if (length == 0) { // Done in the middle of a block. break; } } // Increment block. current_block_count += 1; } // Free memory buffer. free(block); // Return bytes read. return read; }
int sfs_fwrite(int fileID, char *buf, int length){ if (check_open(fileID) == 0){ printf("Can't write, file not opened\n"); return -1; } //SETTING UP META INFO FOR EASY ACCESS buffer = (void*) malloc(BLOCK_SIZE); int blk_inode = fd_table[fileID].inode; //inode index of file we are writing in int current_size = inode_table[blk_inode].size; //file size in bytes int write_ptr = fd_table[fileID].wptr; //write pointer in bytes int blk_offset = write_ptr % BLOCK_SIZE; //offset in bytes of the wptr within the first block int blk_index = write_ptr / BLOCK_SIZE; //inode pointer of first block we start to write in //get block number where wptr is located within sfs int block_nmb = fetch_block(blk_inode, blk_index); //get the block number in the sfs if (block_nmb == -1){ return -1; } //GETTING THE BLOCK WHERE WPTR IS read_blocks(block_nmb,1,buffer); //read what's already on the block /*printf("WPTR AT: %d\n", write_ptr); printf("File size before read: %d\n", current_size); printf("current_size: %d\n", current_size); printf("Write pointer + length: %d\n", write_ptr + length);*/ //UPDATING INODE SIZE if (current_size < write_ptr + length) { inode_table[blk_inode].size = write_ptr + length; } fd_table[fileID].wptr = write_ptr + length; //==========================if the data WILL NOT overflow to next block======================== if (blk_offset + length < BLOCK_SIZE) { memcpy((buffer+blk_offset),buf,length); //write the whole block with added data in buffer //WRITE THE BLOCK ON DISK write_blocks(block_nmb, 1, buffer); //==========================if the data WILL overflow to next block============================= } else { int nmb_of_bytes_copied = 0; //WRITING THE FIRST BLOCK memcpy(buffer+blk_offset,buf,(BLOCK_SIZE-blk_offset)); //write the whole block with added data in buffer nmb_of_bytes_copied += BLOCK_SIZE - blk_offset; //(1) WRITE THE FIRST BLOCK ON DISK write_blocks(block_nmb, 1, buffer); blk_index++; //(2) WRITE THE FULL BLOCKS int nmb_of_fullblocks = (length - (BLOCK_SIZE-blk_offset)) / BLOCK_SIZE; for (int i = 0; i < nmb_of_fullblocks; i++){ memcpy(buffer,(buf+nmb_of_bytes_copied),BLOCK_SIZE); nmb_of_bytes_copied += BLOCK_SIZE; block_nmb = fetch_block(blk_inode, blk_index); //get the block number in the sfs if (block_nmb == -1){ return -1; } write_blocks(block_nmb, 1, buffer); blk_index++; } //(3) WRITE LAST BLOCK memcpy(buffer,(buf+nmb_of_bytes_copied),(length-nmb_of_bytes_copied)); block_nmb = fetch_block(blk_inode, blk_index); //get the block number in the sfs if (block_nmb == -1){ return -1; } write_blocks(block_nmb, 1, buffer); } //printf("Length written: %d\n", length); //printf("File size after read: %d\n", inode_table[blk_inode].size); //END THE WRITE free(buffer); flush_to_disk(blk_inode, 2); //flushing with option 2 return length; }
/* given logical block number, allocate a new physical block, if it does not * exist already, and return the physical block number that is allocated. * returns negative value on error. */ static int testfs_allocate_block(struct inode *in, int log_block_nr, char *block) { int phy_block_nr; char indirect[BLOCK_SIZE]; int indirect_allocated = 0; assert(log_block_nr >= 0); phy_block_nr = testfs_read_block(in, log_block_nr, block); /* phy_block_nr > 0: block exists, so we don't need to allocate it, phy_block_nr < 0: some error */ if (phy_block_nr != 0) return phy_block_nr; /* allocate a direct block */ if (log_block_nr < NR_DIRECT_BLOCKS) { assert(in->in.i_block_nr[log_block_nr] == 0); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr >= 0) { in->in.i_block_nr[log_block_nr] = phy_block_nr; } return phy_block_nr; } log_block_nr -= NR_DIRECT_BLOCKS; if (log_block_nr >= NR_INDIRECT_BLOCKS) { log_block_nr -= NR_INDIRECT_BLOCKS; char dindirect[BLOCK_SIZE]; int dindirect_allocated = 0; int position = log_block_nr/NR_INDIRECT_BLOCKS; if (log_block_nr >= NR_INDIRECT_BLOCKS * NR_INDIRECT_BLOCKS) { return -EFBIG; } //get the double indirect block first if(in->in.i_dindirect == 0){ bzero(dindirect, BLOCK_SIZE); phy_block_nr = testfs_alloc_block_for_inode(in); if(phy_block_nr < 0) return phy_block_nr; dindirect_allocated = 1; in->in.i_dindirect = phy_block_nr; } else{ read_blocks(in->sb, dindirect, in->in.i_dindirect, 1); } //get the indirect block in double indirect block if(((int*) dindirect)[position] == 0) { bzero(indirect, BLOCK_SIZE); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr < 0){ if (dindirect_allocated) { testfs_free_block_from_inode(in, in->in.i_dindirect); return phy_block_nr; } } else{ indirect_allocated = 1; ((int *) dindirect)[position] = phy_block_nr; write_blocks(in->sb, dindirect, in->in.i_dindirect, 1); } }else{ read_blocks(in->sb, indirect, ((int*) dindirect)[position], 1); } //get the direct block assert(((int *) indirect)[log_block_nr % NR_INDIRECT_BLOCKS] == 0); phy_block_nr = testfs_alloc_block_for_inode(in); if(phy_block_nr < 0){ if(dindirect_allocated){ testfs_free_block_from_inode(in, ((int *)dindirect)[position]); testfs_free_block_from_inode(in, in->in.i_dindirect); }else if(indirect_allocated) testfs_free_block_from_inode(in, ((int *)dindirect)[position]); return phy_block_nr; } else if (phy_block_nr >= 0) { ((int *) indirect)[log_block_nr % NR_INDIRECT_BLOCKS] = phy_block_nr; write_blocks(in->sb, indirect, ((int *)dindirect)[position], 1); } return phy_block_nr; } if (in->in.i_indirect == 0) { /* allocate an indirect block */ bzero(indirect, BLOCK_SIZE); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr < 0) return phy_block_nr; indirect_allocated = 1; in->in.i_indirect = phy_block_nr; } else { /* read indirect block */ read_blocks(in->sb, indirect, in->in.i_indirect, 1); } /* allocate direct block */ assert(((int *) indirect)[log_block_nr] == 0); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr >= 0) { /* update indirect block */ ((int *) indirect)[log_block_nr] = phy_block_nr; write_blocks(in->sb, indirect, in->in.i_indirect, 1); } else if (indirect_allocated) { /* free the indirect block that was allocated */ testfs_free_block_from_inode(in, in->in.i_indirect); } return phy_block_nr; }
void sfs_read(int fd, char *buf, int length){ currmyfile = fd; int blockID = 1; int position = 0; int diff; int spaceLeft; int i,j; int currFATi; int temptr; readBuff = (char *) malloc(1024); tempbuff = (char *) malloc(1024); tempbuff2 = (char *) malloc(1024); tempbuff3 = (char *) malloc(1024); readLen = length; spaceLeft = readLen; myfile = directory[FDT[fd].dirIndex]; rootFAT = myfile.indFAT; currFATi = rootFAT; for(i=0; i < 1024; i++){ if(FDT[currmyfile].read - position > 1024){ position = position + 1024; blockID = blockID + 1; currFATi = FAT[currFATi][1]; } } diff = (blockID * 1024) - FDT[currmyfile].read; temptr = FDT[currmyfile].read; for(i=0; i < 1024;i++){ if(readLen > diff){ read_blocks(FAT[currFATi][0],1,readBuff); for(j=0; j < diff; j++){ tempbuff[j] = readBuff[j+FDT[currmyfile].read]; } readLen = readLen - diff; temptr = temptr + diff; currFATi = FAT[currFATi][1]; blockID = blockID + 1; position = position + 1024; diff = 1024; } else{ read_blocks(FAT[currFATi][0],1,readBuff); if(FDT[currmyfile].read==0){ for(j=0; j < readLen; j++){ tempbuff[j] = readBuff[j+FDT[currmyfile].read]; } } else{ if(diff != 1024){ for(j=0; j < diff; j++){ tempbuff[j] = readBuff[j+FDT[currmyfile].read -(blockID-1)*1024]; } } if(diff == 1024){ for(j=0; j < readLen; j++){ tempbuff2[j] = readBuff[j]; } } } } } strcpy(buf,tempbuff); strcat(buf,tempbuff2); FDT[currmyfile].read = FDT[currmyfile].read + length; }
int main (int argc, char **argv) { FILE *fd; uint16_t i; int rv; int error = 0; TALLOC_CTX *mem_ctx; if (argc == 1) { puts("Usage: chkregf REGFILE"); return 1; } if (!(fd = fopen(argv[1], "r"))) { puts("Error: file not found"); return 2; } mem_ctx = talloc_init("chkregf registry checker"); if (!mem_ctx) { printf("Memory allocation error\n"); return 3; } printf("\nPass 1: Checking registry regf header\n\n"); if (!read_regf_header(fd)) { printf("Regf header contains errors\n"); return 1; } printf("\nPass 2: Checking keys for incorrect values\n\n"); for(i = 0; i < regf.data_size / 0x1000; i++) { uint32_t size; if (!(size = get_hbin_header(fd, 0x1000 * i))) { printf("Errors in hbin header at 0x%lx.", (long int) (0x1000 * i) + 0x1000); return 1; } rv = read_blocks(mem_ctx, fd, 0x1000 * i); if (!rv) { error = 1; } if (size / 0x1000 > 1) { i += (size/0x1000) - 1; } } printf("\nPass 3: Checking offsets and tree\n"); rv = parse_tree(mem_ctx, fd, regf.key_offset, 0, "nk", 0); if (!rv) { error = 1; } if (error) { printf("Errors encountered\n"); return 1; } printf("\nDone checking, no errors...\n\n"); fclose(fd); return 0; }
int get_block_at(inode_t* inode, int i, bool create) { int block_index = -1; // Get direct block. if (i < NUM_DIRECT_BLOCKS) { if (inode->direct_blocks[i]) { // It exists. return inode->direct_blocks[i]; } else if (create) { // Yield free block. block_index = yield_block(); if (block_index < 0) { errno = ENOSPC; return block_index; } // Add to inode. inode->direct_blocks[i] = block_index; write_inode_table(); return block_index; } } // Not enough blocks. if (i >= MAX_BLOCKS_PER_INODE) { // File too big. errno = EFBIG; return block_index; } // Otherwise, get indirect block. if (i >= NUM_DIRECT_BLOCKS) { uint64_t* block; if (inode->indirect_block || create) { // Create buffer in memory. block = (uint64_t*)malloc(BLOCK_SZ); clear_block(block, 0, BLOCK_SZ); if (create && inode->indirect_block == 0) { // Create if needed. int indirect_block_index = yield_block(); if (indirect_block_index < 0) { free(block); errno = ENOSPC; return indirect_block_index; } // Write to inode. inode->indirect_block = indirect_block_index; write_inode_table(); } uint64_t indirect_block_ptr = i - NUM_DIRECT_BLOCKS; read_blocks(inode->indirect_block, 1, block); if (block[indirect_block_ptr] > 0) { block_index = block[indirect_block_ptr]; } else if (create) { // Create if needed. block_index = yield_block(); if (block_index > 0) { // Succeeded, so write to disk. block[indirect_block_ptr] = block_index; write_blocks(inode->indirect_block, 1, block); } } // Free memory. free(block); } } if (block_index < 0) { errno = EFAULT; } return block_index; }
static long int jitter_read (cdrom_drive_t *d, void *p, lsn_t begin, long i_sectors, jitter_baddness_t jitter_badness) { static int i_jitter=0; int jitter_flag; long i_sectors_orig = i_sectors; long i_jitter_offset = 0; char *p_buf=malloc(CDIO_CD_FRAMESIZE_RAW*(i_sectors+1)); if (d->i_test_flags & CDDA_TEST_ALWAYS_JITTER) jitter_flag = 1; else #ifdef HAVE_DRAND48 jitter_flag = (drand48() > .9) ? 1 : 0; #else jitter_flag = (((float)rand()/RAND_MAX) > .9) ? 1 : 0; #endif if (jitter_flag) { int i_coeff = 0; int i_jitter_sectors = 0; switch(jitter_badness) { case JITTER_SMALL : i_coeff = 4; break; case JITTER_LARGE : i_coeff = 32; break; case JITTER_MASSIVE: i_coeff = 128; break; case JITTER_NONE : default : ; } #ifdef HAVE_DRAND48 i_jitter = i_coeff * (int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8); #else i_jitter = i_coeff * (int)((((float)rand()/RAND_MAX)-.5)*CDIO_CD_FRAMESIZE_RAW/8); #endif /* We may need to add another sector to compensate for the bytes that will be dropped off when jittering, and the begin location may be a little different. */ i_jitter_sectors = i_jitter / CDIO_CD_FRAMESIZE_RAW; if (i_jitter >= 0) i_jitter_offset = i_jitter % CDIO_CD_FRAMESIZE_RAW; else { i_jitter_offset = CDIO_CD_FRAMESIZE_RAW - (-i_jitter % CDIO_CD_FRAMESIZE_RAW); i_jitter_sectors--; } if (begin + i_jitter_sectors > 0) { #if TRACE_PARANOIA char buffer[256]; sprintf(buffer, "jittering by %d, offset %ld\n", i_jitter, i_jitter_offset); cdmessage(d,buffer); #endif begin += i_jitter_sectors; i_sectors ++; } else i_jitter_offset = 0; } i_sectors = read_blocks(d, p_buf, begin, i_sectors); if (i_sectors < 0) return i_sectors; if (i_sectors < i_sectors_orig) { /* Had to reduce # of sectors due to read errors. So give full amount, with no jittering. */ if (p) memcpy(p, p_buf, i_sectors*CDIO_CD_FRAMESIZE_RAW); } else { /* Got full amount, but now adjust size for jittering. */ if (p) memcpy(p, p_buf+i_jitter_offset, i_sectors_orig*CDIO_CD_FRAMESIZE_RAW); i_sectors = i_sectors_orig; } free(p_buf); return(i_sectors); }
void mksfs(int fresh){ //Implement mksfs here if (fresh == 1){ //deletes fs if it already exists if(access(DISK_FILE, F_OK) != -1){ unlink(DISK_FILE); } //fs creation printf("Initalizing sfs\n"); init_fresh_disk(DISK_FILE, BLOCK_SIZE, MAX_BLOCKS); //zero_everything(); // writes superblock to the first block printf("Writing superblocks\n"); init_superblock(); write_blocks(0, 1, &sb); // write the inode table to the 2nd block printf("Writing inode table\n"); init_inode_table(); //add_root_dir_inode(); //add_dummy_file_inode(); //write_blocks(1, 1, &inode_table); // creates free list init_free_list(); // write root directory data to the 3rd block printf("Writing root dir\n"); init_root_dir(); //allocate memory for directory inode inode_t *inode = malloc(ADJUST((MAX_FILES+1)*sizeof(inode_t))); read_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode); if(inode == NULL){ return; } //set first inode to point to directory inode[0].size = DIRECTORY_SIZE*BLOCK_SIZE; inode[0].link_cnt = DIRECTORY_SIZE; inode[0].exists = 1; //check to see if we need to use ref_ptr //if(DIRECTORY_SIZE > 12){ //inode[0].ref_ptr = search(); //setAlloc(inode[0].ref_ptr); //unsigned int *buffer = malloc(BLOCK_SIZE); //write_blocks(19 + inode[0].ref_ptr, 1, buffer); //free(buffer); //assign the pointers the location of directory files int i; for(i = 0; i < DIRECTORY_SIZE; i++){ if(i > 11){ unsigned int *buffer = malloc(BLOCK_SIZE); read_blocks(19+ inode[0].ref_ptr, 1, buffer); buffer[i - 12] = 2 + i; write_blocks(19+ inode[0].ref_ptr, 1, buffer); free(buffer); } else{ inode[0].data_ptrs[i] = 2 + i; } } //update inode and free memory write_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode); free(inode); } else if (fresh == 0){ if(init_disk(DISK_FILE, BLOCK_SIZE, MAX_BLOCKS) != 0){ printf("Error initializing disk\n"); return; } } //allocate main memory for filesystem data structures int *superblock = malloc(BLOCK_SIZE*SUPERBLOCK_SIZE); if(superblock == NULL){ printf("Error allocating memory for superblock\n"); return; } read_blocks(0, SUPERBLOCK_SIZE, superblock); //allocate main memory for directory root_dir = malloc(ADJUST(sizeof(dir_entry_t)*MAX_FILES)); if(root_dir == NULL){ printf("Error allocating memory for root directory\n"); return; } read_blocks(2, DIRECTORY_SIZE, root_dir); //allocate memory for inode table inode_table = malloc(ADJUST(sizeof(inode_t)*(MAX_FILES+1))); if(inode_table == NULL){ printf("Error allocating memory for inode table"); return; } read_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode_table); fileCount = 0; fd_table = NULL; return; }
int sfs_fopen(char *name){ int i; for(i=0;i<TOTAL_NUM_FILES;i++){ if(strncmp(dir_table[i].filename, name, MAXFILENAME+1+MAXFILEEXTENTSION)==0){ //check the whole name including the extention if(file_des_t[i].open == 1){//check if it is opened return i; //return the index in file descriptor table } //else open this file file_des_t[i].open = 1; //put the pointer after the new opened file file_des_t[i].rw_pointer = inodes[i+1].size; return i; } } //file does not exist int unoccupied_inode_index; int j; for(j=1;j<NUMBER_INODES;j++){//j =1 because j = 0 is the root inode if(inodes[NUMBER_INODES-1].link_cnt==1){ return -1; } if(inodes[j].link_cnt==0){ //link_cnt = 0,means unoccupied unoccupied_inode_index=j; break; } } //initialize a new node INODE new_inode={ .mode=0777, .link_cnt=1, // has one link pointing to it .uid=0, .gid=0, .size=0, .pointers={0,0,0,0,0,0,0,0,0,0,0,0,0} }; inodes[unoccupied_inode_index] = new_inode; int inode_num = unoccupied_inode_index; int num_blocks = inode_num/8+1; char update_inode_buffer[BLOCKSIZE]; memset(update_inode_buffer,0, BLOCKSIZE); read_blocks(num_blocks, 1, update_inode_buffer); memcpy((void *)update_inode_buffer+(inode_num%8)*sizeof(INODE),(const void *) &inodes[inode_num], sizeof(INODE)); write_blocks(num_blocks, 1, update_inode_buffer); //find a free position in directory table int index_of_directory; for (index_of_directory=0; index_of_directory < TOTAL_NUM_FILES; index_of_directory++){ if(dir_table[index_of_directory].inode_number==0){ break; } } //initialize new directory entry in dir_entry new_dir_entry; strcpy(new_dir_entry.filename, name); new_dir_entry.inode_number=unoccupied_inode_index; dir_table[index_of_directory]=new_dir_entry; //write it into disk int index_dir_entry_block = index_of_directory/NUM_ENTRIES_PERBLOCK+BLOCKS_INODES_TABLE+1; //+1 for superblock char buf[BLOCKSIZE]; memset(buf,0, BLOCKSIZE); read_blocks(index_dir_entry_block, 1, buf); memcpy((void *)buf+(index_of_directory%NUM_ENTRIES_PERBLOCK)*sizeof(dir_entry),(const void *) &dir_table[index_of_directory], sizeof(dir_entry)); write_blocks(index_dir_entry_block,1,buf); file_des_t[index_of_directory].open = 1; return index_of_directory; } //close opened file by setting open arrtibute to 0 int sfs_fclose(int fileID){ if(file_des_t[fileID].open==1){ file_des_t[fileID].open=0; return 0; } else { return -1; } } //helper function to help update the block numbers by received an offset bytes and update the buffered memory of the block int update_block(int block_num, char *data, int offset_bytes, int num_bytes_write){ char buffer[BLOCKSIZE]; memset(buffer, 0, BLOCKSIZE); //read existing blocks into buffer read_blocks(block_num,1, buffer); memcpy(buffer+offset_bytes, data, num_bytes_write); int flag = write_blocks(block_num, 1, buffer); if(flag){ return num_bytes_write; } else{ return -1; } }
int sfs_fread(int fileID, char *buf, int length){ //Implement sfs_fread here // error check if(fd_table[fileID] == NULL || length < 0 || fileID > fileCount || buf == NULL){ printf("Error reading file\n"); return -1; } fd_table_t *read = fd_table[fileID]; inode_t *temp_inode = &(inode_table[read->inode_idx]); if(read->inode_idx == LIMIT){ printf("Inode error\n"); return -1; } if(read->rd_write_ptr + length > temp_inode->size){ length = temp_inode->size - read->rd_write_ptr; } char *buffer = malloc(BLOCK_SIZE); int readLength = length, offset = 0; int block = (read->rd_write_ptr)/BLOCK_SIZE; int bytes = (read->rd_write_ptr)%BLOCK_SIZE; int endOfBlock = (temp_inode->size)/BLOCK_SIZE; unsigned int readLocation; if(block > 139){ printf("ERROR: Cannot read. File exceeds maximum size\n"); return -1; } else if(block > 11){ unsigned int *tempBuf = malloc(BLOCK_SIZE); read_blocks(19 + temp_inode->ref_ptr, 1, tempBuf); readLocation = tempBuf[block - 12]; free(tempBuf); } else{ readLocation = temp_inode->data_ptrs[block]; } while(length > 0){ read_blocks((19 + readLocation), 1, buffer); int bytesRead; if(BLOCK_SIZE - bytes < length){ bytesRead = BLOCK_SIZE - bytes; } else{ bytesRead = length; } memcpy(&buf[offset], &buffer[bytes], bytesRead); length -= (bytesRead); offset += (bytesRead); bytes = 0; if(length > 0){ block++; if(endOfBlock < block){ return -1; } if(block > 139){ printf("ERROR: Cannot read. File exceeds maximum size\n"); return -1; } else if(block > 11){ unsigned int *nextBuffer = malloc(BLOCK_SIZE); read_blocks(19 + temp_inode->ref_ptr, 1, nextBuffer); readLocation = nextBuffer[block - 12]; free(nextBuffer); } else{ readLocation = temp_inode->data_ptrs[block]; } } } free(buffer); read->rd_write_ptr += readLength; return readLength; }
int sfs_fread(int fileID, char *buf, int length){ int num_bytes = 0; int num_pointers = 0; int inode_index = dir_table[fileID].inode_number; if(file_des_t[fileID].open==0){ //check if file is opened return -1; } if(length>inodes[inode_index].size){ length=inodes[inode_index].size; //attempt to read more data than the file has } num_pointers = get_num_pointers_inode(inode_index); if(num_pointers>INODE_POINTERS-1){ num_pointers--; } int array_blockptr[num_pointers]; get_pointers(inode_index,array_blockptr,num_pointers);//get pointers in inode into array_blockptr //find the number of blocks to read int rw_offset = file_des_t[fileID].rw_pointer % BLOCKSIZE; int rw_index = file_des_t[fileID].rw_pointer / BLOCKSIZE + 1; int num_blocks; if(length<(BLOCKSIZE-rw_offset)){ //read within one block char read_buf[BLOCKSIZE]; memset(read_buf,0,BLOCKSIZE); read_blocks(array_blockptr[rw_index-1],1,read_buf); memcpy(buf,read_buf+rw_offset,length); file_des_t[fileID].rw_pointer+=length; return length; } else{ num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first and last partial block } int k; char read_buf[BLOCKSIZE]; for(k=rw_index-1;k<rw_index+num_blocks-1;k++){ memset(read_buf,0,BLOCKSIZE); read_blocks(array_blockptr[k],1,read_buf); if(k==rw_index-1){ //first is partial block memcpy(buf,read_buf+rw_offset,BLOCKSIZE-rw_offset); //read only the remaining data num_bytes = num_bytes + (BLOCKSIZE-rw_offset); } else if(k==rw_index+num_blocks-2){ //last block is partial block memcpy(buf+num_bytes, read_buf, (length-(BLOCKSIZE-rw_offset))%BLOCKSIZE); num_bytes = num_bytes + (length-(BLOCKSIZE-rw_offset))%BLOCKSIZE; } else{ //full block memcpy(buf+num_bytes, read_buf, BLOCKSIZE); num_bytes = num_bytes + BLOCKSIZE; } } file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + num_bytes; return num_bytes; }
int sfs_fwrite(int fileID, const char *buf, int length){ //Implement sfs_fwrite here // error check if(fd_table[fileID] == NULL || length < 0 || fileID > fileCount || buf == NULL){ printf("Error reading file\n"); return -1; } fd_table_t *write = fd_table[fileID]; inode_t *temp_inode = &(inode_table[write->inode_idx]); // check fd table entry if(write->inode_idx == LIMIT){ printf("Inode error"); return -1; } char *buffer = malloc(BLOCK_SIZE); int writeLength = length, offset = 0; int block = (write->rd_write_ptr)/BLOCK_SIZE; int bytes = (write->rd_write_ptr)%BLOCK_SIZE; int endOfBlock = (temp_inode->size)/BLOCK_SIZE; int bytesToWrite; unsigned int writeLocation; // max file size error check if(block > 139){ printf("ERROR: Cannot write. File exceeds maximum size\n"); return -1; } // retrieves block location using ref_ptr else if(block > 11){ unsigned int *tempBuf = malloc(BLOCK_SIZE); read_blocks(19 + temp_inode->ref_ptr, 1, tempBuf); writeLocation = tempBuf[block - 12]; free(tempBuf); } // uses data pointers if ref_ptr search fails else{ writeLocation = temp_inode->data_ptrs[block]; } if(writeLocation != -1){ while(length > 0){ read_blocks((19 + writeLocation), 1, buffer); if(BLOCK_SIZE - bytes < length){ bytesToWrite = BLOCK_SIZE - bytes; } else{ bytesToWrite = length; } memcpy(&buffer[bytes], &buf[offset], bytesToWrite); write_blocks(19 + writeLocation, 1, buffer); length -= (bytesToWrite); offset += (bytesToWrite); bytes = 0; block++; if(length > 0){ if(block > 139){ printf("ERROR: Cannot write. File exceeds maximum size\n"); return -1; } else if(endOfBlock < block){ if(block == 12 && temp_inode->ref_ptr == LIMIT){ int searchPtr = search(); allocate(searchPtr); temp_inode->ref_ptr = searchPtr; } int nextLocation = search(); allocate(nextLocation); if(nextLocation == -1){ return -1; } writeLocation = nextLocation; if(block > 11){ unsigned int *nextBuffer = malloc(BLOCK_SIZE); read_blocks(19+ temp_inode->ref_ptr, 1, nextBuffer); nextBuffer[block - 12] = writeLocation; write_blocks(19+ temp_inode->ref_ptr, 1, nextBuffer); free(nextBuffer); } else{ temp_inode->data_ptrs[block] = writeLocation; } temp_inode->link_cnt++; // updates link count. Not sure if necessary } else{ if(block > 11){ unsigned int *nextBuffer = malloc(BLOCK_SIZE); read_blocks(19+ temp_inode->ref_ptr, 1, nextBuffer); writeLocation = nextBuffer[block - 12]; free(nextBuffer); } else{ writeLocation = temp_inode->data_ptrs[block]; } } } } } // update filesize in inode table if(write->rd_write_ptr + writeLength > temp_inode->size){ temp_inode->size = write->rd_write_ptr + writeLength; } // update read/write pointer write->rd_write_ptr += writeLength; // update inode table write_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode_table); free(buffer); // returns length of written data return writeLength; }
//Creates the file system int mksfs(int fresh){ char buf[BLOCKSIZE]; memset(buf,0, BLOCKSIZE); //sets a block-size buffer and set it to zero if(fresh){ init_fresh_disk(DISK_FILE, BLOCKSIZE, TOTAL_NUM_BLOCKS); //initialize super block super_block superblock; superblock.magic=0xAABB0005; superblock.block_size=BLOCKSIZE; superblock.file_system_size=TOTAL_NUM_BLOCKS; superblock.inode_table_length=NUMBER_INODES; superblock.root_dir_inode_number=0; //set root directory at the first inode //copy super block to buffer memcpy((void *)buf,(const void *) &superblock, sizeof(super_block)); //write the superblock to the first block in the disk write_blocks(0,1, buf); //initialize inode table memset(inodes, 0, sizeof(inodes)); //Set first inode to root directory inode INODE root_dir_inode={ .mode=0777, .link_cnt=1, .uid=0, .gid=0, .size=0, .pointers={14,15,16,17,18,0,0,0,0,0,0,0,0} //pointer to the first data block starting at 14 }; inodes[0]=root_dir_inode; //write inode into disk int inode_number = 0; int block_of_inode=inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); //initialize the bitmap memset(free_bitmap, 0, sizeof(free_bitmap)); free_bitmap[0]=255; //superblock and first part of inodes to occupied. free_bitmap[1]=255; //inodes table to occupied. free_bitmap[2]=224; //directory entry table to occupied. free_bitmap[BLOCKSIZE-1]=1; //last block for the bitmap write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);//write the bitmap into disk //initialize directory table into memory memset(dir_table, 0, sizeof(dir_table)); //Initialize all file's RW pointers to 0 and open to 0 memset(file_des_t, 0, sizeof(file_des_t)); cur_pos=-1; return 0; } else{ //file system already exists init_disk(DISK_FILE, BLOCKSIZE, TOTAL_NUM_BLOCKS); // set free_bitmap to zeros memset(free_bitmap,0, sizeof(free_bitmap)); //load existing bitmap read_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); //load existing superblock super_block superblock; read_blocks(0,1,&superblock); //load existing inode table char inodes_buffer[BLOCKS_INODES_TABLE*BLOCKSIZE]; memset(inodes_buffer,0,sizeof(inodes_buffer)); read_blocks(1,BLOCKS_INODES_TABLE,inodes_buffer); int n; for(n=0;n<NUMBER_INODES;n++){ memcpy((void *)&(inodes[n]),(const void *)(inodes_buffer+n*(BLOCKSIZE/8)), BLOCKSIZE/8); } //load existing directory table INODE root_directory=inodes[superblock.root_dir_inode_number]; int i; char root_dir_buffer[BLOCKSIZE]; memset(root_dir_buffer,0,BLOCKSIZE); for(i=0;i<INODE_POINTERS;i++){ if(root_directory.pointers[i]!=0){ read_blocks(root_directory.pointers[i],1, root_dir_buffer); int j; for(j=0;j<NUM_ENTRIES_PERBLOCK;j++){ if((j+NUM_ENTRIES_PERBLOCK*i) >= TOTAL_NUM_FILES){ break; } memcpy((void *)&(dir_table[j]), (const void *)(root_dir_buffer+j*(sizeof(dir_entry))), sizeof(dir_entry)); } memset(root_dir_buffer,0,BLOCKSIZE); } } //initialize all rw pointers to 0 and open to 0 memset(file_des_t, 0, sizeof(file_des_t)); cur_pos=-1; return 0; } }
int sfs_fwrite(int fileID, const char *buf, int length) { inode_struct* inode; int filled, rw_pointer, blknum, blk_pointer; int last_block_bytes, last_full_blknum; char block[BLKSIZ]; // If file is not open or write exceeds maximum file size return error if( (fd_table[fileID].status == FREE) || (fd_table[fileID].rw_pointer + length > MAXFILESIZ) ) return -1; inode = fd_table[fileID].inode; rw_pointer = fd_table[fileID].rw_pointer; blknum = rw_pointer/BLKSIZ; filled = rw_pointer % BLKSIZ; // If we do not need to go to another data block if( (filled + length) <= BLKSIZ) { blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum); if(blk_pointer == -1) return -1; read_blocks(blk_pointer, 1, block); memcpy(&block[filled], buf, length); write_blocks(blk_pointer, 1, block); inode->size = max(rw_pointer + length, inode->size); fd_table[fileID].rw_pointer = rw_pointer + length; return length; } last_full_blknum = ((filled + length) / BLKSIZ) + blknum; last_block_bytes = (filled + length) % BLKSIZ; blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum); if(blk_pointer == -1) return -1; read_blocks(blk_pointer, 1, block); memcpy(&block[filled], buf, BLKSIZ - filled); write_blocks(blk_pointer, 1, block); buf += BLKSIZ - filled; blknum++; while(blknum < last_full_blknum) { blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum); if(blk_pointer == -1) return -1; memcpy(block, buf, BLKSIZ); write_blocks(blk_pointer, 1, block); buf += BLKSIZ; blknum++; } blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum); if(blk_pointer == -1) return -1; read_blocks(blk_pointer, 1, block); memcpy(block, buf, last_block_bytes); write_blocks(blk_pointer, 1, block); inode->size = max(rw_pointer + length, inode->size); fd_table[fileID].rw_pointer = rw_pointer + length; return length; }
/* given logical block number, allocate a new physical block, if it does not * exist already, and return the physical block number that is allocated. * returns negative value on error. */ static int testfs_allocate_block(struct inode *in, int log_block_nr, char *block) { if (log_block_nr>4196361) return -EFBIG; // //printf("log_block_nr:%d\n",log_block_nr); // } int phy_block_nr; char indirect[BLOCK_SIZE]; char dindirect[BLOCK_SIZE]; char dindirect2[BLOCK_SIZE]; int indirect_allocated = 0; //int dindirect_allocated = 0; assert(log_block_nr >= 0); phy_block_nr = testfs_read_block(in, log_block_nr, block); /* phy_block_nr > 0: block exists, so we don't need to allocate it, phy_block_nr < 0: some error */ if (phy_block_nr != 0) return phy_block_nr; /* allocate a direct block */ if (log_block_nr < NR_DIRECT_BLOCKS) { assert(in->in.i_block_nr[log_block_nr] == 0); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr >= 0) { in->in.i_block_nr[log_block_nr] = phy_block_nr; } return phy_block_nr; } log_block_nr -= NR_DIRECT_BLOCKS; if (log_block_nr >= NR_INDIRECT_BLOCKS) { log_block_nr -= NR_INDIRECT_BLOCKS; //log block ranges from 0 ~ 4194303 int level1_block = DIVROUNDUP(log_block_nr+1,2048) - 1; // ranges 0~2047 int level2_block= log_block_nr % 2048; /* allocate an dindirect block */ if (in->in.i_dindirect == 0) { bzero(dindirect, BLOCK_SIZE); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr < 0) return phy_block_nr; //dindirect_allocated = 1; in->in.i_dindirect = phy_block_nr; //printf("dindirect block #:%d\n",phy_block_nr); } else /* read dindirect block */ { read_blocks(in->sb, dindirect, in->in.i_dindirect, 1); } // Allocate 2nd level indirect block if (((int *)dindirect)[level1_block] == 0) { bzero(dindirect2, BLOCK_SIZE); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr < 0) return phy_block_nr; ((int*)dindirect)[level1_block]=phy_block_nr; //printf("2nd dindirect block #:%d\n", ((int*)dindirect)[level1_block]); write_blocks(in->sb, dindirect, in->in.i_dindirect,1); } // error here.... // Read 2nd level indirect block else { read_blocks(in->sb, dindirect2, ((int*)dindirect)[level1_block], 1); } // allocate direct block */ phy_block_nr=testfs_alloc_block_for_inode(in); if (phy_block_nr >=0) // update 2nd level indirect block { ((int*)dindirect2)[level2_block]=phy_block_nr; //printf("Last direct block #:%d\n", ((int*)dindirect2)[level2_block]); write_blocks(in->sb, dindirect2, ((int*)dindirect)[level1_block], 1); } return phy_block_nr; // Allocate 2nd-level indirect block } /**** Allocating in 1st level indirect blocks ****/ if (in->in.i_indirect == 0) /* allocate an indirect block */ { bzero(indirect, BLOCK_SIZE); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr < 0) return phy_block_nr; indirect_allocated = 1; in->in.i_indirect = phy_block_nr; } else { /* read indirect block */ read_blocks(in->sb, indirect, in->in.i_indirect, 1); } /* allocate direct block */ assert(((int *)indirect)[log_block_nr] == 0); phy_block_nr = testfs_alloc_block_for_inode(in); if (phy_block_nr >= 0) { /* update indirect block */ ((int *)indirect)[log_block_nr] = phy_block_nr; write_blocks(in->sb, indirect, in->in.i_indirect, 1); } else if (indirect_allocated) { /* free the indirect block that was allocated */ testfs_free_block_from_inode(in, in->in.i_indirect); } return phy_block_nr; }
void mksfs(int fresh){ int freeSpace; int FATSize; int dirSize; int i; int j; char *buffer1; blockSize = BLOCK_SIZE; numBlocks = NUM_BLOCKS; maximummyfiles = MAX_myfileS; buffer1 = (char *) malloc(1024); if(fresh != 0){//create a new sfs init_disk("s2.dsk", blockSize, numBlocks); init_cache(0); for(i=0; i<maximummyfiles; i++){ strcpy(directory[i].name, "empty_myfile"); directory[i].size = 0; directory[i].date = 0; directory[i].indFAT = -1; } for(i=0; i<numBlocks; i++){ for(j=0; j<2; j++) FAT[i][j] = -2; } for(i=0; i<numBlocks; i++){ free_list[i] = '0'; } free_list[0] = '1'; free_list[1] = '1'; free_list[numBlocks - 1] = '1'; //set FDT settings for(i=0; i<maximummyfiles; i++){ FDT[i].dirIndex = -1; } dirSize = sizeof(entry) * maximummyfiles; FATSize = sizeof(int) * numBlocks * 2; freeSpace = sizeof(char) * numBlocks; while(dirSize>0){ if(dirSize>1024){ memcpy(buffer1, directory, 1024); } else { memcpy(buffer1, directory, dirSize); } write_blocks(0, 1, buffer1); dirSize -= 1024; } while(FATSize>0){ if(FATSize>1024){ memcpy(buffer1, FAT, 1024); } else { memcpy(buffer1, FAT, FATSize); } write_blocks(1, 1, buffer1); FATSize -= 1024; } while(freeSpace>0){ if(freeSpace>1024){ memcpy(buffer1, free_list, 1024); } else { memcpy(buffer1, free_list, freeSpace); } write_blocks(1023, 1, buffer1); freeSpace -= 1024; } printf("SFS created successfully\n"); } else{ // load existing sfs for(i=0; i<maximummyfiles; i++){ FDT[i].dirIndex = -1; } read_blocks(0, 1, buffer1); memcpy(directory,buffer1, 1024); read_blocks(1, 1, buffer1); memcpy(FAT,buffer1, 1024); read_blocks(1023, 1, buffer1); memcpy(free_list,buffer1, 1024); printf("SFS loading successfull\n"); } read_blocks(0, 1, buffer1); memcpy(directory,buffer1, 1024); read_blocks(1, 1, buffer1); memcpy(FAT,buffer1, 1024); read_blocks(1023, 1, buffer1); memcpy(free_list,buffer1, 1024); }