diff --git a/src/fs.c b/src/fs.c index 0219f3d..6e0a7a1 100644 --- a/src/fs.c +++ b/src/fs.c @@ -313,54 +313,43 @@ int fs_prohibit_write(void *d) return 0; } -static struct fs_directory_record *fs_read_dir(unsigned int fs_inode_ptr) -{ - unsigned int inode_block_no = read_inode_ptr(fs_inode_ptr); - struct fs_inode dir_inode; - read_block(inode_block_no, &dir_inode); - - if (dir_inode.size == 0) { - pr("directory is empty\n"); - return NULL; - } - - struct fs_header fsh; - read_block(0, (void *) &fsh); - - struct fs_directory_record *recs = malloc(fsh.max_inode_count * sizeof(struct fs_directory_record)); - memset(recs, 0, fsh.max_inode_count * sizeof(struct fs_directory_record)); - - // read block portion from dir_inode - for (int i = 0; (i*DIRECTORY_RECORDS_PER_BLOCK < dir_inode.size) && (i < BLOCK_ADDRESSES_PER_INODE); i++) { - if (dir_inode.blocks[i]) { - read_block(dir_inode.blocks[i], &(recs[i*DIRECTORY_RECORDS_PER_BLOCK])); - } - } - - // read block portions from inode extensions - // TODO - - return recs; -} - static int fs_find_free_directory_record(unsigned int dir_inode_ptr) { - struct fs_directory_record *recs = fs_read_dir(dir_inode_ptr); - if (!recs) { - return 0; - } - struct fs_header fsh; read_block(0, (void *) &fsh); - for (unsigned int i = 0; i < fsh.max_inode_count; i++) { - if (!recs[i].inode_no) { - free(recs); - return i; + struct fs_inode dir; + read_block(read_inode_ptr(dir_inode_ptr), (void *) &dir); + + int found_block_no = 0; + + // search in base inode + for (unsigned int i = 0; i < BLOCK_ADDRESSES_PER_INODE; i++) { + struct fs_directory_record r[DIRECTORY_RECORDS_PER_BLOCK]; + + if (!dir.blocks[i]) { + if (found_block_no < fsh.max_inode_count) + return (found_block_no); + else + return -1; + } + + read_block(dir.blocks[i], (void *) &r); + + for (int j = 0; j < DIRECTORY_RECORDS_PER_BLOCK; j++, found_block_no++) { + if (r[j].inode_no) + continue; + + if (found_block_no >= fsh.max_inode_count) + return -1; + + return found_block_no; } } - free(recs); + // search in inode extensions + // TODO + return -1; } @@ -494,6 +483,7 @@ static int fs_remove_fname_from_directory(unsigned int dir_inode_ptr, char *fnam pr("Directory record for '%s' found in block=%d, record=%d, removing\n", fname, i, k); + unsigned int inode_ptr_cache = recs[k].inode_no; unsigned int inode_location_cache = read_inode_ptr(recs[k].inode_no); // decrement ref_count @@ -511,7 +501,7 @@ static int fs_remove_fname_from_directory(unsigned int dir_inode_ptr, char *fnam goto fs_remove_fname_from_directory_finish; pr("ref_count=0, clearing inode_ptr\n"); - write_inode_ptr(recs[k].inode_no, 0); + write_inode_ptr(inode_ptr_cache, 0); // if no fd reference this inode, clean it up altogether int i; @@ -780,7 +770,7 @@ int fs_ln(void *d) // list entries from inode extensions // TODO - pr_err("no such file '%d'\n", existing_fname); + pr_err("no such file '%s'\n", existing_fname); return 0; original_inode_ptr_found: @@ -788,10 +778,10 @@ original_inode_ptr_found: // register new filename with the same inode_ptr if (fs_add_fname_to_directory(fs_cwd_inode_ptr, original_inode_ptr, new_fname) < 0) { - pr_err("failed to register filename in directory '%s'\n", fs_cwd_inode_ptr); + pr_err("failed to register filename in directory '%s'\n", fs_cwd); return 0; } else { - pr("Registered new filename in directory '%s'\n", fs_cwd_inode_ptr); + pr("Registered new filename in directory '%s'\n", fs_cwd); } // update ref_count in file inode