nsfs支持(未适配)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.31.5)
|
||||
cmake_minimum_required(VERSION 3.29.0)
|
||||
project(nsfs VERSION 0.1.0 LANGUAGES C)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
add_executable(nsfs ns.c nsfs.c main.c)
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "ns.h"
|
||||
#include "nsfs.h"
|
||||
#include <assert.h>
|
||||
|
||||
int nsfs_test(void)
|
||||
int nsfs_mkdir_test(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -18,12 +25,177 @@ int nsfs_test(void)
|
||||
ret = fs_ns_remove("/bin/tst");
|
||||
assert(ret < 0);
|
||||
ret = fs_ns_rmdir("/bin/tst");
|
||||
assert(ret >= 0 );
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int nsfs_scan_dir_test(void)
|
||||
{
|
||||
nsfs_test();
|
||||
#define TEST_CN 10
|
||||
int ret;
|
||||
ret = fs_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
|
||||
for (int i = 0; i < TEST_CN; i++)
|
||||
{
|
||||
char dir_name[32];
|
||||
|
||||
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
|
||||
ret = fs_ns_mkdir(dir_name);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
int fd;
|
||||
|
||||
fd = fs_ns_open("/bin/", O_RDWR, 0777);
|
||||
assert(fd >= 0);
|
||||
struct dirent dir_info;
|
||||
for (int i = 0; i < (TEST_CN + 1); i++)
|
||||
{
|
||||
ret = fs_ns_readdir(fd, &dir_info);
|
||||
if (i < TEST_CN)
|
||||
{
|
||||
assert(ret >= 0);
|
||||
printf("readdir info :%s\n", dir_info.d_name);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(ret < 0);
|
||||
}
|
||||
}
|
||||
ret = fs_ns_lseek(fd, 2, SEEK_SET);
|
||||
printf("old seek: %d\n", ret);
|
||||
assert(ret >= 0);
|
||||
for (int i = 0; i < (TEST_CN - 2 + 1); i++)
|
||||
{
|
||||
ret = fs_ns_readdir(fd, &dir_info);
|
||||
if (i < TEST_CN - 2)
|
||||
{
|
||||
assert(ret >= 0);
|
||||
printf("readdir info :%s\n", dir_info.d_name);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(ret < 0);
|
||||
}
|
||||
}
|
||||
|
||||
ret = fs_ns_close(fd);
|
||||
assert(ret >= 0);
|
||||
ret = fs_ns_readdir(fd, &dir_info);
|
||||
assert(ret < 0);
|
||||
|
||||
for (int i = 0; i < TEST_CN; i++)
|
||||
{
|
||||
char dir_name[32];
|
||||
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
|
||||
ret = fs_ns_rmdir(dir_name);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
ret = fs_ns_rmdir("/bin");
|
||||
assert(ret >= 0);
|
||||
#undef TEST_CN
|
||||
return 0;
|
||||
}
|
||||
int nsfs_mksvr_node(void)
|
||||
{
|
||||
int ret;
|
||||
struct dirent dir;
|
||||
|
||||
ret = fs_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
ret = ns_mknode("/bin/tst1", 10, NODE_TYPE_SVR);
|
||||
assert(ret >= 0);
|
||||
int fd;
|
||||
|
||||
fd = fs_ns_open("/bin/tst1", O_RDWR, 0777);
|
||||
assert(fd < 0);
|
||||
fd = fs_ns_open("/bin/", O_RDWR, 0777);
|
||||
assert(fd >= 0);
|
||||
ret = fs_ns_readdir(fd, &dir);
|
||||
assert(ret >= 0);
|
||||
printf("readdir info :%s\n", dir.d_name);
|
||||
ret = fs_ns_close(fd);
|
||||
assert(ret >= 0);
|
||||
|
||||
ret = fs_ns_remove("/bin/tst1/");
|
||||
assert(ret >= 0);
|
||||
ret = fs_ns_rmdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
int nsfs_query_svr_node(void)
|
||||
{
|
||||
int ret;
|
||||
ret = fs_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
ns_node_t *node;
|
||||
ns_node_t *pnode;
|
||||
int cur_inx;
|
||||
int p_inx;
|
||||
|
||||
node = ns_node_find_full_file("/bin/", &ret, &cur_inx);
|
||||
assert(node == NULL && ret < 0);
|
||||
|
||||
#define SVR_NODE "/svr_tst"
|
||||
ret = ns_mknode(SVR_NODE, 10, NODE_TYPE_SVR);
|
||||
assert(ret >= 0);
|
||||
|
||||
node = ns_node_find_full_file(SVR_NODE, &ret, &cur_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE));
|
||||
|
||||
node = ns_node_find(&pnode, SVR_NODE "/1/2/3", &ret, &cur_inx, &p_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE) + 1);
|
||||
|
||||
ret = fs_ns_mkdir(SVR_NODE "/1");
|
||||
assert(ret < 0);
|
||||
#undef SVR_NODE
|
||||
ret = fs_ns_remove("/svr_tst");
|
||||
assert(ret >= 0);
|
||||
#define SVR_NODE "/bin/svr_tst"
|
||||
ret = ns_mknode(SVR_NODE, 10, NODE_TYPE_SVR);
|
||||
assert(ret >= 0);
|
||||
node = ns_node_find_full_file(SVR_NODE, &ret, &cur_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE));
|
||||
node = ns_node_find_svr_file(SVR_NODE "/1/2/3", &ret, &cur_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE) + 1);
|
||||
|
||||
ret = fs_ns_rmdir("/bin/");
|
||||
assert(ret < 0);
|
||||
|
||||
ret = fs_ns_remove(SVR_NODE);
|
||||
assert(ret >= 0);
|
||||
ret = fs_ns_rmdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
int nsfs_stat_test(void)
|
||||
{
|
||||
int ret;
|
||||
struct stat fst;
|
||||
int fd;
|
||||
|
||||
ret = fs_ns_mkdir("/tstdir/");
|
||||
assert(ret >= 0);
|
||||
fd = fs_ns_open("/tstdir/", O_RDWR, 0777);
|
||||
assert(fd >= 0);
|
||||
ret = fs_ns_stat(fd, &fst);
|
||||
assert(ret >= 0);
|
||||
ret = fs_ns_close(fd);
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
nsfs_mkdir_test();
|
||||
nsfs_scan_dir_test();
|
||||
nsfs_stat_test();
|
||||
nsfs_mksvr_node();
|
||||
nsfs_query_svr_node();
|
||||
return 0;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ns.h"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
static ns_node_t root_node = {
|
||||
.type = NODE_TYPE_DUMMY,
|
||||
.svr_hd = HANDLER_INVALID, //!< 根节点是虚拟节点
|
||||
};
|
||||
/**
|
||||
* 从路径中copy名字
|
||||
@@ -42,7 +41,7 @@ static ns_node_t *ns_node_find_sub(ns_node_t *tree, const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
ns_node_t *cur = tree->next;
|
||||
ns_node_t *cur = tree->sub;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
@@ -71,7 +70,7 @@ int ns_nodes_count(ns_node_t *tree)
|
||||
}
|
||||
static int ns_node_del(ns_node_t *tree, ns_node_t *del_node)
|
||||
{
|
||||
ns_node_t *tmp = tree->next;
|
||||
ns_node_t *tmp = tree->sub;
|
||||
ns_node_t *pre = NULL;
|
||||
|
||||
while (tmp)
|
||||
@@ -81,7 +80,8 @@ static int ns_node_del(ns_node_t *tree, ns_node_t *del_node)
|
||||
if (pre == NULL)
|
||||
{
|
||||
// 删除第一个节点
|
||||
tree->next = tmp->next;
|
||||
tree->sub = tmp->next;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -113,7 +113,7 @@ ns_node_t *ns_node_get_inx(ns_node_t *tree, int inx)
|
||||
assert(tree);
|
||||
assert(tree->type == NODE_TYPE_DUMMY);
|
||||
int nr = 0;
|
||||
ns_node_t *cur = tree->next;
|
||||
ns_node_t *cur = tree->sub;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
@@ -130,7 +130,7 @@ ns_node_t *ns_node_get_inx(ns_node_t *tree, int inx)
|
||||
* 查找节点,如果是dummy节点,则一直循环查找。
|
||||
* 如果是svr节点,则立刻终止查找,然后返回当前节点,以及截断的位置
|
||||
*/
|
||||
ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *cur_inx)
|
||||
ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *svr_inx, int *p_inx)
|
||||
{
|
||||
assert(ret);
|
||||
assert(path);
|
||||
@@ -179,7 +179,11 @@ ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *cur_
|
||||
}
|
||||
else if (t_node->type == NODE_TYPE_SVR)
|
||||
{
|
||||
find_node_cut_inx = i;
|
||||
find_node_cut_inx = i + len + 1;
|
||||
if (path[find_node_cut_inx] == '/')
|
||||
{
|
||||
find_node_cut_inx++;
|
||||
}
|
||||
// 找到服务节点,那直接返回,服务节点不会有子节点。
|
||||
cur_node = t_node;
|
||||
goto end;
|
||||
@@ -193,6 +197,10 @@ ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *cur_
|
||||
}
|
||||
cur_node = NULL;
|
||||
}
|
||||
if (p_inx)
|
||||
{
|
||||
*p_inx = i;
|
||||
}
|
||||
if (path[i] == '/')
|
||||
{
|
||||
i++;
|
||||
@@ -200,7 +208,7 @@ ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *cur_
|
||||
i += len;
|
||||
}
|
||||
end:
|
||||
*cur_inx = find_node_cut_inx;
|
||||
*svr_inx = find_node_cut_inx;
|
||||
*ret = 0;
|
||||
return cur_node;
|
||||
}
|
||||
@@ -214,13 +222,13 @@ int ns_delnode(const char *path)
|
||||
int ret;
|
||||
int cur_inx;
|
||||
|
||||
cur_node = ns_node_find(NULL, path, &ret, &cur_inx);
|
||||
cur_node = ns_node_find(NULL, path, &ret, &cur_inx, NULL);
|
||||
if (cur_node == NULL)
|
||||
{
|
||||
printf("ns node not find.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
if (cur_node == NULL || path[cur_inx + 1] != '\0')
|
||||
if (cur_node == NULL)
|
||||
{
|
||||
printf("ns path is error.\n");
|
||||
// 未找到,节点不是dummy节点,路径不是结尾处 则直接退出
|
||||
@@ -254,8 +262,8 @@ ns_node_t *ns_node_find_full_dir(const char *path, int *ret, int *cur_inx)
|
||||
assert(cur_inx);
|
||||
ns_node_t *dir_node;
|
||||
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_DUMMY || cur_inx != 0)
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_DUMMY || *cur_inx != 0)
|
||||
{
|
||||
printf("ns node not find or path error.\n");
|
||||
// 未找到,节点不是dummy节点,路径不是结尾处 则直接退出
|
||||
@@ -275,8 +283,26 @@ ns_node_t *ns_node_find_full_file(const char *path, int *ret, int *cur_inx)
|
||||
assert(cur_inx);
|
||||
ns_node_t *dir_node;
|
||||
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_SVR || path[*cur_inx + 1] != '\0')
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_SVR || path[*cur_inx] != '\0')
|
||||
{
|
||||
printf("ns node not find or path error.\n");
|
||||
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dir_node;
|
||||
}
|
||||
ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx)
|
||||
{
|
||||
assert(path);
|
||||
assert(ret);
|
||||
assert(cur_inx);
|
||||
ns_node_t *dir_node;
|
||||
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_SVR)
|
||||
{
|
||||
printf("ns node not find or path error.\n");
|
||||
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
|
||||
@@ -297,15 +323,16 @@ int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type)
|
||||
ns_node_t *cur_node;
|
||||
int ret;
|
||||
int cur_inx;
|
||||
int p_inx;
|
||||
char name[NS_NODE_NAME_LEN];
|
||||
|
||||
cur_node = ns_node_find(&dir_node, path, &ret, &cur_inx);
|
||||
if (dir_node == NULL)
|
||||
cur_node = ns_node_find(&dir_node, path, &ret, &cur_inx, &p_inx);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_DUMMY || (cur_node != NULL && cur_node->type == NODE_TYPE_SVR))
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
// 获得节点的名字
|
||||
int name_len = ns_node_strcpy(name, path + cur_inx + 1, NS_NODE_NAME_LEN);
|
||||
int name_len = ns_node_strcpy(name, path + p_inx + 1, NS_NODE_NAME_LEN);
|
||||
|
||||
new_node = node_create(name, NODE_TYPE_DUMMY);
|
||||
if (new_node == NULL)
|
||||
@@ -313,8 +340,8 @@ int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type)
|
||||
return -ENOMEM;
|
||||
}
|
||||
// 加到目录的链表中
|
||||
new_node->next = dir_node->next;
|
||||
dir_node->next = new_node;
|
||||
new_node->next = dir_node->sub;
|
||||
dir_node->sub = new_node;
|
||||
new_node->type = type;
|
||||
new_node->parent = dir_node;
|
||||
if (type == NODE_TYPE_SVR)
|
||||
|
||||
@@ -33,9 +33,10 @@ typedef struct ns_node
|
||||
int ref; //!< 引用计数
|
||||
} ns_node_t;
|
||||
|
||||
ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *cur_inx);
|
||||
ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *svr_inx, int *p_inx);
|
||||
ns_node_t *ns_node_find_full_dir(const char *path, int *ret, int *cur_inx);
|
||||
ns_node_t *ns_node_find_full_file(const char *path, int *ret, int *cur_inx);
|
||||
ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx);
|
||||
int ns_nodes_count(ns_node_t *tree);
|
||||
ns_node_t *ns_node_get_inx(ns_node_t *tree, int inx);
|
||||
int ns_delnode(const char *path);
|
||||
@@ -48,5 +49,5 @@ static inline ns_node_t *ns_node_get_next(ns_node_t *tree_node, ns_node_t *cur_n
|
||||
static inline ns_node_t *ns_node_get_first(ns_node_t *tree_node)
|
||||
{
|
||||
assert(tree_node);
|
||||
return tree_node->next;
|
||||
return tree_node->sub;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include "ns.h"
|
||||
|
||||
#define DIR_INFO_CACHE_NR 32
|
||||
|
||||
typedef struct dir_info_cache
|
||||
@@ -20,6 +21,10 @@ typedef struct dir_info_cache
|
||||
static dir_info_cache_t dir_info_cache_list[DIR_INFO_CACHE_NR];
|
||||
static int dir_info_cache_get(ns_node_t *info)
|
||||
{
|
||||
if (info == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
|
||||
{
|
||||
if (dir_info_cache_list[i].info == NULL)
|
||||
@@ -136,7 +141,7 @@ int fs_ns_open(const char *name, int flags, int mode)
|
||||
enum fs_ns_type type;
|
||||
|
||||
// 路径必须'/'卡头
|
||||
if (name[0] == '\0' || name[1] != '/')
|
||||
if (name[0] == '\0' || name[0] != '/')
|
||||
{
|
||||
printf("nsfs path is error.\n");
|
||||
return -EINVAL;
|
||||
@@ -223,11 +228,11 @@ int fs_ns_lseek(int fd, int offset, unsigned long whence)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->tmp_fd != -1)
|
||||
if (file->tmp_fd >= 0)
|
||||
{
|
||||
dir_info_cache_put(dir_info_cache_list[file->tmp_fd].info);
|
||||
}
|
||||
dir_info_cache_get(new_dir_info);
|
||||
file->tmp_fd = dir_info_cache_get(new_dir_info);
|
||||
}
|
||||
file->offset = new_offs;
|
||||
|
||||
@@ -245,12 +250,9 @@ int fs_ns_stat(int fd, struct stat *st)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->type != FS_NS_FILE_TYPE)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->st_size = 0;
|
||||
st->st_mode = S_IFREG;
|
||||
st->st_mode = file->type == FS_NS_FILE_TYPE ? S_IFREG : S_IFDIR;
|
||||
st->st_nlink = dir_info_cache_list[file->dir_info_fd].info->ref;
|
||||
return 0;
|
||||
}
|
||||
@@ -261,7 +263,7 @@ int fs_ns_close(int fd)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->tmp_fd != -1)
|
||||
if (file->tmp_fd >= 0)
|
||||
{
|
||||
dir_info_cache_put(dir_info_cache_list[file->tmp_fd].info);
|
||||
}
|
||||
@@ -293,6 +295,7 @@ int fs_ns_rmdir(const char *name)
|
||||
ret = ns_delnode(name);
|
||||
if (ret < 0)
|
||||
{
|
||||
dir_info_cache_put(file);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -353,6 +356,10 @@ int fs_ns_readdir(int fd, struct dirent *_dir)
|
||||
}
|
||||
file->tmp_fd = ret;
|
||||
}
|
||||
else if (file->tmp_fd == -2)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
ns_node_t *node_info;
|
||||
|
||||
node_info = dir_info_cache_list[file->tmp_fd].info;
|
||||
@@ -362,19 +369,17 @@ int fs_ns_readdir(int fd, struct dirent *_dir)
|
||||
_dir->d_name[sizeof(_dir->d_name) - 1] = 0;
|
||||
|
||||
ns_node_t *next_dir_info = ns_node_get_next(dir_info_cache_list[file->dir_info_fd].info, node_info);
|
||||
if (next_dir_info == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
dir_info_cache_put(node_info);
|
||||
ret = dir_info_cache_get(next_dir_info);
|
||||
if (ret < 0)
|
||||
if (ret >= 0)
|
||||
{
|
||||
return ret;
|
||||
file->tmp_fd = ret;
|
||||
file->offset++;
|
||||
}
|
||||
else
|
||||
{
|
||||
file->tmp_fd = -2; // -2代表结束遍历
|
||||
}
|
||||
|
||||
file->tmp_fd = ret;
|
||||
file->offset++;
|
||||
return sizeof(*_dir);
|
||||
}
|
||||
int fs_ns_mkdir(char *path)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include "ns.h"
|
||||
int fs_ns_open(const char *name, int flags, int mode);
|
||||
int fs_ns_write(int fd, void *data, int len);
|
||||
int fs_ns_read(int fd, void *data, int len);
|
||||
|
||||
Reference in New Issue
Block a user