From 051a04ea7586d8f603a6693f78ae5d25bf11f4b1 Mon Sep 17 00:00:00 2001 From: Victor Date: Sun, 19 Nov 2023 21:22:53 -0800 Subject: [PATCH] add dir_API to demo direntry API --- include/direntry.h | 9 ++++- lib/direntry.cpp | 39 +++++++++++++++++++ test/CMakeLists.txt | 8 +++- test/dir_API.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 test/dir_API.cpp diff --git a/include/direntry.h b/include/direntry.h index 6b1c945..ff4792d 100644 --- a/include/direntry.h +++ b/include/direntry.h @@ -11,13 +11,13 @@ typedef struct fileNode { buffer[j] = t & (((u_int64_t)1<<(8))-1); t >>= 8; } - strcpy(buffer+8, file_name); + strcpy(buffer+8, name); } void deserialize(char* buffer) { inode_number = 0; for (int j = 0; j < 8; j++) inode_number = inode_number | (((u_int64_t)(unsigned char)buffer[j])<<(8*j)); - strcpy(file_name, buffer+8); + strcpy(name, buffer+8); } } FileNode; @@ -39,3 +39,8 @@ int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileNam //e.g. FileNode *Dirnode = fischl_find_entry(); can see file inside with Dirnode->subdirectory //e.g. go to the current Dirnode parent directory, use TreeNode *get_Dir_parent = Dirnode->subdirectory->parent; FileNode *fischl_find_entry(TreeNode *root, const char *path); + +void freeTree(TreeNode *node); +/*for debug use*/ +TreeNode *createDirectory(const char *dirName, TreeNode *parent, int hashSize); +TreeNode *find_parentPath(TreeNode *root, const char *path); \ No newline at end of file diff --git a/lib/direntry.cpp b/lib/direntry.cpp index 85f0a69..12eb1c9 100644 --- a/lib/direntry.cpp +++ b/lib/direntry.cpp @@ -1,3 +1,10 @@ +#include +#include +#include +#include +#include +#include "fs.h" +#include "direntry.h" /*********************************Hash operation******************************************** ********************************************************************************************/ @@ -36,6 +43,38 @@ FileNode *lookupHash(HashTable *h, char *key) { return NULL; // Not found } +TreeNode *createDirectory(const char *dirName, TreeNode *parent, int hashSize) { + TreeNode *newDir = (TreeNode *)malloc(sizeof(TreeNode)); + newDir->dirName = strdup(dirName); + newDir->contents = createHashTable(hashSize); + newDir->parent = parent; + if (parent) { + newDir->self_info = insertHash(parent->contents, newDir->dirName, newDir); + } + return newDir; +} + +TreeNode *find_parentPath(TreeNode *root, const char *path) { + char *pathCopy = strdup(path); + char *segment = strtok(pathCopy, "/"); + TreeNode *current = root; + FileNode *file = NULL; + + while (segment != NULL && current != NULL) { + file = lookupHash(current->contents, segment); + if (file != NULL && file->subdirectory == NULL) { + free(pathCopy); + printf("status current directory %s\n",current->dirName); + return current; //File found + } + current = file ? file->subdirectory : NULL; + segment = strtok(NULL, "/"); + } + + free(pathCopy); + return current; // NULL if not found +} + void freeHashTable(HashTable *table) { if (table == NULL) return; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 09bdc38..82ccfd4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,7 @@ set(TARGET_LAYER0 test_layer0) set(TARGET_LAYER1_API test_layer1_API) set(TARGET_LAYER2_API test_layer2_API) +set(TARGET_DIR_API test_dir_API) set(DIR_PLACE /dev/vdb) # add test sources here ... @@ -16,6 +17,10 @@ add_executable(${TARGET_LAYER2_API} ../lib/files.cpp layer2_API.cpp ) +add_executable(${TARGET_DIR_API} + ../lib/direntry.cpp + dir_API.cpp +) # Link Google Test to your test executables target_link_libraries(${TARGET_LAYER0} gtest gtest_main) @@ -24,4 +29,5 @@ target_link_libraries(${TARGET_LAYER1_API} gtest gtest_main) # add test to activate ctest -VV add_test(NAME ${TARGET_LAYER0} COMMAND sudo ./${TARGET_LAYER0} ${DIR_PLACE}) add_test(NAME ${TARGET_LAYER1_API} COMMAND sudo ./${TARGET_LAYER1_API} ${DIR_PLACE}) -add_test(NAME ${TARGET_LAYER2_API} COMMAND sudo ./${TARGET_LAYER2_API} ${DIR_PLACE}) \ No newline at end of file +add_test(NAME ${TARGET_LAYER2_API} COMMAND sudo ./${TARGET_LAYER2_API} ${DIR_PLACE}) +add_test(NAME ${TARGET_DIR_API} COMMAND sudo ./${TARGET_DIR_API} ${DIR_PLACE}) \ No newline at end of file diff --git a/test/dir_API.cpp b/test/dir_API.cpp new file mode 100644 index 0000000..fb93b31 --- /dev/null +++ b/test/dir_API.cpp @@ -0,0 +1,91 @@ +/*********************************************************** + Directory owns treeNode and FileNode structure, detect S_IFDIR to make treeNode or not (see add_entry Function) + File owns FileNode structure only, detect !S_IFDIR + +*/ +#include +#include +#include +#include +#include +#include "fs.h" +#include "direntry.h" + +int main() { + TreeNode *root = createDirectory("/", NULL, 20); + INode inode_file1; + fischl_add_entry(root, 2, "file1",&inode_file1); + //I will put this function in create_new_inode function, there will inode number(2) when inode_allocate + INode inode_dir1; + //permission is necessary there to create treeNode or not + u_int64_t ddd_permissions = 0; + inode_dir1.permissions = ddd_permissions | S_IFDIR; + fischl_add_entry(root, 3, "dir1",&inode_dir1); + //find dir file (from root directory view, root contains dir1/ subdirectory) + FileNode *get_dir1 = fischl_find_entry(root,"/dir1/"); + if(get_dir1 == NULL){ + printf("No dir1 under %s\n",root->dirName); + return -1; + }else{ + fprintf(stderr,"[%s ,%d]",__func__,__LINE__); + printf(" %s under %s\n",get_dir1->name,root->dirName); + } + //add file2 under dir1 + INode inode_file2; + if(get_dir1->subdirectory != NULL){ + //Treenode dir(you cannot find here), you only can get Filenode dir based on fischl_find_entry Function + //So use Filenode->subdirectory will point to the treenode dir, then can add files + fischl_add_entry(get_dir1->subdirectory, 4, "file2",&inode_file2); + printf("add file2 in dir1\n"); + } + /**********************************************************/ + //This is for debugging, and demonstate to you + TreeNode *get_dir1_tree = find_parentPath(root,"/dir1/file2"); + if(get_dir1_tree == get_dir1->subdirectory){ + fprintf(stderr,"[%s ,%d]",__func__,__LINE__); + printf(" [Treenode]get_dir1_tree->dirName (%s) same [Filenode]get_dir1->name (%s)\n",get_dir1_tree->dirName,get_dir1->name); + }else{ + printf("not same\n"); + } + /**********************************************************/ + //two Ways to get File(include dir itself) information + FileNode *get_file2 =NULL; + //1. absolute path, the root(treeNode) will always exist when initialize + get_file2 = fischl_find_entry(root,"/dir1/file2"); + if(get_file2 == NULL){ + printf("No dir1 under dir1\n"); + return -1; + }else{ + fprintf(stderr,"[%s ,%d]",__func__,__LINE__); + printf(" %s under %sdir1/\n",get_file2->name,root->dirName); + } + //2. relative path, the get_dir1(FileNode)->subdirectory(treeNode), use treeNode(dir) to find + get_file2 = fischl_find_entry(get_dir1->subdirectory,"/file2"); + if(get_file2 == NULL){ + printf("No dir1 under %s\n",get_dir1->subdirectory->dirName); + return -1; + }else{ + fprintf(stderr,"[%s ,%d]",__func__,__LINE__); + printf(" %s under %s\n",get_file2->name,get_dir1->subdirectory->dirName); + } + /**********************************************************/ + //add one more file under dir1 + INode inode_file3; + if(get_dir1->subdirectory != NULL){ + fischl_add_entry(get_dir1_tree, 5, "file3",&inode_file3); + printf("add file3 in dir1\n"); + } + FileNode *get_file3 =NULL; + //fischl_find_entry(get_dir1->subdirectory,"/file3"); are equivalent + get_file3 = fischl_find_entry(get_dir1_tree,"/file3"); + if(get_file3 == NULL){ + printf("No dir1 under %s\n",get_dir1_tree->dirName); + return -1; + }else{ + printf(" %s under %s\n",get_file3->name,get_dir1_tree->dirName); + } + // Cleanup + freeTree(root); + + return 0; +} \ No newline at end of file