int main(int argc, char *argv[]) { if (argc != 3) invocation_error(argv[0], "[output file] [size]"); char *output_file = argv[1]; size_t records = atol(argv[2]); size_t i, part_number, noun_count, adj_count; char *nouns[NOUN_MAX], noun_file_content[NOUN_BYTES]; char *adjectives[ADJ_MAX], adj_file_content[ADJ_BYTES]; int rc; Part p; Parts db = new_db(CHUNK_SIZE); noun_count = get_word_pointers(nouns, NOUN_FILE, noun_file_content, NOUN_BYTES); adj_count = get_word_pointers(adjectives, ADJ_FILE, adj_file_content, ADJ_BYTES); init_locale(); srand((unsigned int) time(NULL)); remove(output_file); for (part_number = 0, i = 0; i < records; i++) { part_number = jagged_sequence(part_number); p = set_part(part_number, random_part_name(nouns, noun_count, adjectives, adj_count), random_int(), random_int()); printf("%9ld: ", i + 1); print_part(p); if ((rc = insert_part(db, p))) { fprintf(stderr, "%s: %d insert_part() failed: return code %d on iteration %ld\n", __FILE__, __LINE__, rc, i); destroy_db(db); exit(EXIT_FAILURE); } if (i % CHUNK_SIZE == 0) { if (flush_to_disk(output_file, db) != 0) { destroy_db(db); exit_error(argv[0], output_file); } } } if (flush_to_disk(output_file, db) != 0) { destroy_db(db); exit_error(argv[0], output_file); } destroy_db(db); return 0; }
int sfs_fopen(char *name){ int index = -1; int fd_index; for (int i = 0; i < MAX_FD; i++){ if (strcmp(name, root[i].fname) == 0){ index = i; //matching file with index i } } if (index >= 0) { //we found a file with matching name in the root_directory at index "index" for (int i = 0; i < MAX_FD; i++){ //Let's check if we have a file already open linked to the same inode if (root[index].inode == fd_table[i].inode) { //if we find an open file with same inode as the matched file printf("Note: file was already opened\n"); return index; //Then the file is already open, still return the file descriptor index } } fd_index = find_first_free_fd(); //file isn't open, so we open it at first empty spot in fd_table if (fd_index < 0){ return -1; } else { //Set flag to 0, inode number, rptr to 0 (bginning of file) and wptr to the size of the file fd_table[fd_index] = (fd){0,root[index].inode,0,inode_table[(root[index].inode)].size}; return fd_index; } } else { //No file has this name so create a new file and open it fd_index = find_first_free_fd(); if (fd_index<0) { return -1; } else { //Found an empty index in which we can create new file //We assume the file name given is composed only of letters and has at most 1 '.' if (strlen(name) > 20){ printf("File name too large, can be maximum 20 characters\n"); return -1; } char *extension = strchr(name, '.'); int extension_length = strlen(extension); if ((extension == NULL) || (extension_length <= 4)) { int dir_index = find_first_free_dir(); if (dir_index < 0) return -1; //========UPDATING ROOT DIRECTORY, LINKING FILE TO NEW INODE, LINKING FILE TO FD_TABLE=========== strcpy(root[dir_index].fname,name); root[dir_index].inode = dir_index+1; //first inode is taken by root directory inode_table[dir_index+1] = (inode){777, 1, 1, 0, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -1}; fd_table[fd_index] = (fd){0, dir_index+1, 0, 0}; flush_to_disk(root[dir_index].inode, 1); return fd_index; } return -1; } } }
int sfs_remove(char *file){ int index = -1; for (int i = 0; i < MAX_FD; i++){ if (strcmp(file, root[i].fname) == 0){ index = i; //matching file with index i } } //If there is no file with that name if (index < 0){ printf("No file to remove\n"); return 0; //If there is a file with that name } else { int inode_indx = root[index].inode; int block_location; if (inode_table[inode_indx].size > 0){ //if there are some blocks to free //Number of blocks the file spans across: int nmb_of_blocks = (inode_table[inode_indx].size / BLOCK_SIZE) + 1; for (int i = 0; i<nmb_of_blocks; i++){ block_location = fetch_block(inode_indx,i); free_bitmap(block_location); } } //CLOSE IF FILE IS OPEN for (int i = 0; i < MAX_FD; i++){ //check if we have a file opened linked to the same inode if (inode_indx == fd_table[i].inode) { //if we find an open file with same inode as the matched file sfs_fclose(i); } } //REMOVE FROM ROOT DIRECTORY root[index] = (dir){"", -1}; //REINITIALIZE INODE inode_table[inode_indx] = (inode){0, 1, 1, 0, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -1}; //FLUSH flush_to_disk(inode_indx, 0); return 0; } }
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; }