fix bugs, simplify free directory record search
This commit is contained in:
		
							parent
							
								
									4de89d57f1
								
							
						
					
					
						commit
						4f610340f5
					
				
							
								
								
									
										78
									
								
								src/fs.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/fs.c
									
									
									
									
									
								
							@ -313,54 +313,43 @@ int fs_prohibit_write(void *d)
 | 
				
			|||||||
	return 0;
 | 
						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)
 | 
					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;
 | 
						struct fs_header fsh;
 | 
				
			||||||
	read_block(0, (void *) &fsh);
 | 
						read_block(0, (void *) &fsh);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (unsigned int i = 0; i < fsh.max_inode_count; i++) {
 | 
						struct fs_inode dir;
 | 
				
			||||||
		if (!recs[i].inode_no) {
 | 
						read_block(read_inode_ptr(dir_inode_ptr), (void *) &dir);
 | 
				
			||||||
			free(recs);
 | 
					
 | 
				
			||||||
			return i;
 | 
						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;
 | 
						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);
 | 
								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);
 | 
								unsigned int inode_location_cache = read_inode_ptr(recs[k].inode_no);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// decrement ref_count
 | 
								// 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;
 | 
									goto fs_remove_fname_from_directory_finish;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pr("ref_count=0, clearing inode_ptr\n");
 | 
								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
 | 
								// if no fd reference this inode, clean it up altogether
 | 
				
			||||||
			int i;
 | 
								int i;
 | 
				
			||||||
@ -780,7 +770,7 @@ int fs_ln(void *d)
 | 
				
			|||||||
	// list entries from inode extensions
 | 
						// list entries from inode extensions
 | 
				
			||||||
	// TODO
 | 
						// TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_err("no such file '%d'\n", existing_fname);
 | 
						pr_err("no such file '%s'\n", existing_fname);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
original_inode_ptr_found:
 | 
					original_inode_ptr_found:
 | 
				
			||||||
@ -788,10 +778,10 @@ original_inode_ptr_found:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// register new filename with the same inode_ptr
 | 
						// register new filename with the same inode_ptr
 | 
				
			||||||
	if (fs_add_fname_to_directory(fs_cwd_inode_ptr, original_inode_ptr, new_fname) < 0) {
 | 
						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;
 | 
							return 0;
 | 
				
			||||||
	} else {
 | 
						} 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
 | 
						// update ref_count in file inode
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user