This entry is bit in a haze. The problem of ramdisk image being too big is solved. I just shrinked image size to 2MB and used FAT12 file system. (Surprisingly, fat12 file system works just identical to fat16..)
Implemented vfs::create() function. Whilst implementing, I just integrated iterated operation into just one function - functions such as searching the file_info handler and automatically creating new handle to the tree.
// @brief Get the file_info handle by using cache.
/// If there is no file on the cache tree, function physically searches for the file.
/// The files opened for directory searching is stored into cache tree.
/// @param file_path General file path
/// @param levels_to_exclude Number of directory levels to exclude from searching
/// @return file_info handle, if failed searching(file does not exist), return 0x00
static file_info *get_file_by_cache_and_phys(const general_file_name file_path , int levels_to_exclude) {
vfs::VirtualFileSystemManager *vfs_mgr = GLOBAL_OBJECT(vfs::VirtualFileSystemManager);
char **file_list;
int level_count;
int last_hit_loc = 0;
// failed to initialize the vfs manager
if(!vfs_mgr->is_initialized_properly) return 0x00;
level_count = get_file_name_list(file_path , file_list);
file_info *file = vfs_mgr->search_object_last(level_count , file_path.root_directory , file_list , last_hit_loc);
if(file != 0x00 && strcmp(file->file_name , file_list[level_count-1]) == 0) { // cash hit
memory::pmem_free(file_list);
return file;
}
debug::out::printf_function(DEBUG_TEXT , "get_file_by_cache" , "last cash hit : %s(file=0x%lx), hit_loc : %d\n" , file->file_name , file , last_hit_loc);
file_info *tree_file = file;
for(int i = last_hit_loc; i < level_count-levels_to_exclude; i++) {
physical_file_location *pfileloc = &tree_file->file_loc_info;
if(tree_file->is_mounted == true) pfileloc = &tree_file->mount_loc_info;
file_info *new_file_handle = pfileloc->fs_driver->get_file_handle({file_list[i] , tree_file});
if(new_file_handle == 0x00) {
memory::pmem_free(file_list);
return 0x00;
}
vfs_mgr->add_object(new_file_handle , tree_file);
tree_file = new_file_handle;
}
memory::pmem_free(file_list);
return tree_file;
}
I just separated (very most of) operation searching cache from open() function and created a new function out of it.
Thanks to that, create() and open() functions are very very compact.
bool vfs::create(const general_file_name file_path , word file_type) {
file_info *directory;
physical_file_location *physical_loc;
char top_name[strlen(file_path.file_name)];
directory = get_file_by_cache_and_phys(file_path , 1);
if(directory == 0x00) return false;
physical_loc = fsdev::get_physical_loc_info(directory);
get_highest_level_file_name(file_path.file_name , top_name);
debug::out::printf("top_name : %s\n" , top_name);
if(physical_loc->fs_driver == 0x00) return false;
return physical_loc->fs_driver->create({top_name , directory} , file_type);
}
file_info *vfs::open(const general_file_name file_path , int option) {
file_info *file = get_file_by_cache_and_phys(file_path , 0);
return file;
}
get_highest_level_file_name() function is a function that parses the top name from the full file name. Basically it's the function that removes the directory path from the file. (Gosh, I should really name these functions more comprehensively...)
Now I'm planning on making open/close system and buffer caching system. I want file to be opened by multiple processors, each synchronized and cached. I really should learn how to do something fancy like linux..