nsfs支持(未适配)

This commit is contained in:
zhangzheng
2025-02-25 11:22:30 +08:00
parent f824ad3c53
commit ed4a69205e
6 changed files with 250 additions and 44 deletions

View File

@@ -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)

View File

@@ -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 nsfs_scan_dir_test(void)
{
#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_test();
nsfs_mkdir_test();
nsfs_scan_dir_test();
nsfs_stat_test();
nsfs_mksvr_node();
nsfs_query_svr_node();
return 0;
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);