fix bugs, simplify free directory record search

This commit is contained in:
ІО-23 Шмуляр Олег 2025-04-26 16:05:40 +03:00
parent 4de89d57f1
commit 4f610340f5
1 changed files with 34 additions and 44 deletions

View File

@ -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