Today I implemented open() function in vfs. Basically, when the file is existing in the "cache tree", the file from the cache is returned. When the file does not exist in the tree, the physical search using the file system driver is proceed.
file_info *vfs::open(const general_file_name file_path , int option) {
char **file_list;
VirtualFileSystemCache *vfs_cache = GLOBAL_OBJECT(VirtualFileSystemCache);
int level_count = vfs_cache->auto_parse_dir_count(file_path.file_name);
// parse the file name into an array of directory names
file_list = (char **)memory::pmem_alloc(level_count*sizeof(char*));
vfs_cache->auto_parse_name(file_path.file_name , file_list);
// search for cache
int last_hit_loc = 0;
file_info *file = vfs_cache->search_object_last(level_count , file_path.root_directory , file_list , last_hit_loc);
if(file == 0x00) return 0x00; // give up
if(file != 0x00 && strcmp(file->file_name , file_list[level_count-1]) == 0) { // cash hit
return file;
}
debug::out::printf("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; i++) {
physical_file_location *pfileloc = &tree_file->file_loc_info;
if(tree_file->is_mounted == true) pfileloc = &tree_file->mount_loc_info;
debug::out::printf("file to open : %s\n" , file_list[i]);
debug::out::printf("root directory : %s(0x%lx)\n" , tree_file->file_name , tree_file);
file_info *new_file_handle = pfileloc->fs_driver->get_file_handle({file_list[i] , tree_file});
if(new_file_handle == 0x00) return 0x00;
vfs_cache->add_object(new_file_handle , tree_file);
tree_file = new_file_handle;
}
debug::out::printf(DEBUG_SPECIAL , "tree_file : 0x%X(%s,%d)\n" , tree_file , tree_file->file_name , tree_file->file_loc_info.block_location);
// hmmm
return tree_file;
}
vfs_cache->search_obj_last searches the file_info object from the tree. Particular thing about this function is that it returns last available file from the cache when the file does not exist in cache, not just returning nothing. Because logically, returning the last location available in the cache will reduce the time searching the tree again.
When cache does not exist and needs to be created, the file system driver is used for searching for the file. The vfs uses get_file_handle function for searching the physical location and information of the file (as you can see above.)
While making and testing the system, I found some weird bug that presents when reading and writing on the ramdisk. Somehow some parts of ramdisk was corrupted and overwritten to other values. Initially I thought it was the problem of driver, but the problem was the image itsel.
See, there are some spaces in memory that is occupied by other parts of system. Because the ramdisk image is so large, the image encompassed the already-occupied memory areas, making the image partially corrupted and unusable.
The memory area is suppose to be like the image on the right..
How should we fix this? Well, reducing the size of the ramdisk is a solution by compressing the image using algorithms such as xz and gzip. I will try to understand the xz compression method and implement it to my kernel...