nsfs集成,完善posix文件系统接口支持
This commit is contained in:
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -195,10 +195,14 @@
|
||||
"socket.h": "c",
|
||||
"net_svr.h": "c",
|
||||
"inet.h": "c",
|
||||
"u_malloc.h": "c"
|
||||
"u_malloc.h": "c",
|
||||
"nsfs.h": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": true,
|
||||
"C_Cpp.default.systemIncludePath": [""],
|
||||
"C_Cpp.default.forcedInclude": ["${workspaceFolder}/build/autoconf.h"]
|
||||
"C_Cpp.default.forcedInclude": [
|
||||
"${workspaceFolder}/build/autoconf.h"
|
||||
],
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
}
|
||||
@@ -15,7 +15,10 @@ umword_t sys_tick_cnt_get(void)
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
// 进行上下文切换
|
||||
thread_sched(TRUE);
|
||||
if (!thread_sched(TRUE))
|
||||
{
|
||||
atomic_inc(&thread_get_current()->time_count);
|
||||
}
|
||||
sys_tick_cnt++;
|
||||
#if 0
|
||||
thread_timeout_check(1);
|
||||
|
||||
@@ -13,28 +13,55 @@
|
||||
#include <errno.h>
|
||||
#include "u_sys.h"
|
||||
#include "unistd.h"
|
||||
#include "u_malloc.h"
|
||||
int ls(int argc, char *agrv[])
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *ptr;
|
||||
int i;
|
||||
char *path;
|
||||
char *in_path;
|
||||
int ret;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
return -1;
|
||||
in_path = ".";
|
||||
}
|
||||
else
|
||||
{
|
||||
in_path = agrv[1];
|
||||
}
|
||||
|
||||
dir = opendir(agrv[1]);
|
||||
path = u_malloc(PAGE_SIZE);
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
strcpy(path, in_path);
|
||||
dir = opendir(in_path);
|
||||
if (!dir)
|
||||
{
|
||||
u_free(path);
|
||||
return 0;
|
||||
}
|
||||
while ((ptr = readdir(dir)) != NULL)
|
||||
{
|
||||
struct stat st = {0};
|
||||
stat(ptr->d_name, &st);
|
||||
printf("%s\t\t\t%dB\n", ptr->d_name, st.st_size);
|
||||
strcat(path, "/");
|
||||
strcat(path, ptr->d_name);
|
||||
ret = stat(path, &st);
|
||||
// if (ret >= 0)
|
||||
// {
|
||||
printf("%s\t\t\t%dB\n", path, st.st_size);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// printf("error:%d\n", ret);
|
||||
// }
|
||||
strcpy(path, in_path);
|
||||
}
|
||||
closedir(dir);
|
||||
u_free(path);
|
||||
return 0;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), ls, ls, ls command);
|
||||
@@ -51,6 +78,18 @@ int rm(int argc, char *agrv[])
|
||||
return ret;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), rm, rm, rm command);
|
||||
int cd(int argc, char *agrv[])
|
||||
{
|
||||
int ret;
|
||||
if (argc < 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = chdir(agrv[1]);
|
||||
return ret;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), cd, cd, cd command);
|
||||
int cat(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
|
||||
@@ -103,7 +103,8 @@ umword_t be_mmap(void *start,
|
||||
long flags,
|
||||
long fd,
|
||||
long _offset);
|
||||
int be_fcntl(int fd, int cmd, void* arg);
|
||||
int be_fcntl(int fd, int cmd, void *arg);
|
||||
long be_chdir(const char *path);
|
||||
int be_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
// net api
|
||||
int be_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <u_task.h>
|
||||
#include <u_util.h>
|
||||
#include <poll.h>
|
||||
#include <u_path.h>
|
||||
#include "kstat.h"
|
||||
AUTO_CALL(101)
|
||||
void fs_backend_init(void)
|
||||
{
|
||||
@@ -27,14 +29,20 @@ void fs_backend_init(void)
|
||||
assert(fd_map_alloc(0, 1, FD_TTY) >= 0);
|
||||
assert(fd_map_alloc(0, 2, FD_TTY) >= 0);
|
||||
}
|
||||
#define FS_PATH_LEN 64
|
||||
static char cur_path[FS_PATH_LEN] = "/";
|
||||
int be_open(const char *path, int flags, mode_t mode)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
int fd = fs_open(path, flags, mode);
|
||||
char new_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
u_rel_path_to_abs(cur_path, path, new_path);
|
||||
|
||||
fd = fs_open(new_path, flags, mode);
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
@@ -129,7 +137,7 @@ static int be_tty_read(char *buf, long size)
|
||||
}
|
||||
else if (len == 0)
|
||||
{
|
||||
u_sema_down(SEMA_PROT, 0/*TODO:*/, NULL);
|
||||
u_sema_down(SEMA_PROT, 0 /*TODO:*/, NULL);
|
||||
continue;
|
||||
}
|
||||
r_len += len;
|
||||
@@ -411,11 +419,17 @@ long sys_be_lseek(va_list ap)
|
||||
}
|
||||
long be_mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
return fs_mkdir((char *)path);
|
||||
char new_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
u_rel_path_to_abs(cur_path, path, new_path);
|
||||
return fs_mkdir((char *)new_path);
|
||||
}
|
||||
long be_symlink(const char *src, const char *dst)
|
||||
{
|
||||
return fs_symlink(src, dst);
|
||||
char new_src_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
char new_dst_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
u_rel_path_to_abs(cur_path, src, new_src_path);
|
||||
u_rel_path_to_abs(cur_path, dst, new_dst_path);
|
||||
return fs_symlink(new_src_path, new_dst_path);
|
||||
}
|
||||
long be_getdents(long fd, char *buf, size_t size)
|
||||
{
|
||||
@@ -448,7 +462,9 @@ long be_getdents(long fd, char *buf, size_t size)
|
||||
long be_stat(const char *path, void *_buf)
|
||||
{
|
||||
struct kstat *buf = _buf;
|
||||
return fs_stat((char *)path, buf);
|
||||
char new_src_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
u_rel_path_to_abs(cur_path, path, new_src_path);
|
||||
return fs_stat((char *)new_src_path, buf);
|
||||
}
|
||||
long be_fstat(int fd, void *_buf)
|
||||
{
|
||||
@@ -464,7 +480,9 @@ long be_fstat(int fd, void *_buf)
|
||||
}
|
||||
long be_unlink(const char *path)
|
||||
{
|
||||
return fs_unlink(path);
|
||||
char new_src_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
u_rel_path_to_abs(cur_path, path, new_src_path);
|
||||
return fs_unlink(new_src_path);
|
||||
}
|
||||
long be_poll(struct pollfd *fds, nfds_t n, int timeout)
|
||||
{
|
||||
@@ -547,5 +565,27 @@ int be_fcntl(int fd, int cmd, void *arg)
|
||||
}
|
||||
int be_access(const char *filename, int amode)
|
||||
{
|
||||
// char new_src_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
// u_rel_path_to_abs(cur_path, path, new_src_path);
|
||||
return -ENOSYS;
|
||||
}
|
||||
long be_chdir(const char *path)
|
||||
{
|
||||
int ret;
|
||||
struct kstat buf;
|
||||
char new_src_path[FS_PATH_LEN]; // FIXME:动态申请
|
||||
u_rel_path_to_abs(cur_path, path, new_src_path);
|
||||
|
||||
ret = fs_stat((char *)new_src_path, &buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (!S_ISDIR(buf.st_mode))
|
||||
{
|
||||
return -ENOTDIR;
|
||||
}
|
||||
strncpy(cur_path, new_src_path, FS_PATH_LEN);
|
||||
cur_path[FS_PATH_LEN - 1] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
struct kstat {
|
||||
long st_dev;
|
||||
int __st_dev_padding;
|
||||
|
||||
@@ -117,12 +117,16 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric
|
||||
if (ret) return ret;
|
||||
|
||||
*st = (struct stat){
|
||||
#ifndef MKRTOS
|
||||
.st_dev = kst.st_dev,
|
||||
#endif
|
||||
.st_ino = kst.st_ino,
|
||||
.st_mode = kst.st_mode,
|
||||
.st_nlink = kst.st_nlink,
|
||||
#ifndef MKRTOS
|
||||
.st_uid = kst.st_uid,
|
||||
.st_gid = kst.st_gid,
|
||||
#endif
|
||||
.st_rdev = kst.st_rdev,
|
||||
.st_size = kst.st_size,
|
||||
.st_blksize = kst.st_blksize,
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#include <unistd.h>
|
||||
#include "syscall.h"
|
||||
|
||||
#ifndef NO_LITTLE_MODE
|
||||
#include "syscall_backend.h"
|
||||
#endif
|
||||
int chdir(const char *path)
|
||||
{
|
||||
#ifdef NO_LITTLE_MODE
|
||||
return syscall(SYS_chdir, path);
|
||||
#else
|
||||
return be_chdir(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
#include "u_types.h"
|
||||
#include "ns_types.h"
|
||||
|
||||
int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type);
|
||||
int ns_register(const char *path, obj_handler_t svr_hd, int flags);
|
||||
int ns_query(const char *path, obj_handler_t *svr_hd, int flags);
|
||||
|
||||
@@ -2,35 +2,29 @@
|
||||
#include "u_types.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_slist.h"
|
||||
#define NAMESPACE_PATH_LEN 32
|
||||
#define NAMESAPCE_NR 8
|
||||
|
||||
enum node_type
|
||||
#define NS_NODE_NAME_LEN 32
|
||||
|
||||
typedef enum node_type
|
||||
{
|
||||
MOUNT_NODE, //!< 挂载节点
|
||||
FILE_NODE, //!< 文件节点
|
||||
DIR_NODE, //!< 存在子目录
|
||||
SYM_NODE, //!< 一个软链接节点
|
||||
};
|
||||
NODE_TYPE_DUMMY, //!< 虚拟节点,可以有子节点
|
||||
NODE_TYPE_SVR, //!< 服务节点,不能有子节点
|
||||
NODE_TYPE_ROOT, //!< ROOT节点
|
||||
} node_type_t;
|
||||
|
||||
typedef struct ns_node
|
||||
{
|
||||
char name[NS_NODE_NAME_LEN]; //!< 节点名字
|
||||
node_type_t type; //!< 节点类型
|
||||
struct ns_node *parent; //!< 父节点
|
||||
char node_name[NAMESPACE_PATH_LEN]; //!< 节点的类型
|
||||
enum node_type type; //!< 节点的类型
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
obj_handler_t node_hd; //!< 存储设备ipc的hd号码
|
||||
pid_t pid; //!< 哪一个task注册的?
|
||||
}; //!< FILE_NODE &MOUNT_NODE使用该结构
|
||||
slist_head_t sub_dir; //!< 只有DIR_NODE才有子目录
|
||||
char sym_path[NAMESPACE_PATH_LEN]; //!< SYM_NODE的软链接路径
|
||||
};
|
||||
slist_head_t node; //!< 当前节点作为子节点使用
|
||||
struct ns_node *next; //!< 下一个
|
||||
// union
|
||||
// {
|
||||
struct ns_node *sub; //!< 子树
|
||||
obj_handler_t svr_hd; //!< 服务节点
|
||||
// };
|
||||
int ref; //!< 引用计数
|
||||
} ns_node_t;
|
||||
|
||||
typedef struct ns
|
||||
{
|
||||
rpc_svr_obj_t svr;
|
||||
|
||||
@@ -26,14 +26,10 @@ sd_t fs_open(const char *path, int flags, int mode)
|
||||
obj_handler_t hd;
|
||||
int ret = ns_query(path, &hd, 0x1);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = ns_query(path, &hd, 0x0);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
rpc_ref_file_array_t rpc_path = {
|
||||
.data = (uint8_t *)(&path[ret]),
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "u_env.h"
|
||||
#include "u_prot.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_path.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -12,7 +13,7 @@
|
||||
#define NS_CLI_CACHE_NR 8 //!< 一个客户端最多可以请求8个服务
|
||||
typedef struct ns_cli_entry
|
||||
{
|
||||
char path[NAMESPACE_PATH_LEN];
|
||||
char path[NS_NODE_NAME_LEN];
|
||||
obj_handler_t hd;
|
||||
} ns_cli_entry_t;
|
||||
|
||||
@@ -77,7 +78,7 @@ RPC_GENERATION_CALL2(ns_t, NS_PROT, NS_QUERY_OP, query,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)
|
||||
|
||||
int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type)
|
||||
int ns_register(const char *path, obj_handler_t svr_hd, int flags)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
@@ -89,7 +90,7 @@ int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type)
|
||||
.data = svr_hd,
|
||||
};
|
||||
rpc_int_t rpc_type = {
|
||||
.data = type,
|
||||
.data = flags,
|
||||
};
|
||||
|
||||
msg_tag_t tag = ns_t_register_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd, &rpc_type);
|
||||
@@ -102,6 +103,12 @@ int ns_query(const char *path, obj_handler_t *svr_hd, int flags)
|
||||
assert(path);
|
||||
assert(svr_hd);
|
||||
|
||||
if (u_is_root_path(path))
|
||||
{
|
||||
// 根路径直接返回服务路径就行了
|
||||
*svr_hd = u_get_global_env()->ns_hd;
|
||||
return 0;
|
||||
}
|
||||
obj_handler_t newfd;
|
||||
|
||||
newfd = find_hd(path, &inx);
|
||||
@@ -134,6 +141,7 @@ int ns_query(const char *path, obj_handler_t *svr_hd, int flags)
|
||||
handler_free(newfd);
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
#if 0
|
||||
if (flags & 0x1)
|
||||
{
|
||||
if (msg_tag_get_val(tag) != strlen(path))
|
||||
@@ -143,6 +151,7 @@ int ns_query(const char *path, obj_handler_t *svr_hd, int flags)
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (reg_hd(path, newfd, msg_tag_get_val(tag)) == FALSE)
|
||||
{
|
||||
printf("The client service cache is full.\n");
|
||||
|
||||
@@ -38,6 +38,7 @@ RPC_GENERATION_OP2(ns_t, NS_PROT, NS_QUERY_OP, query,
|
||||
path->data[path->len - 1] = 0;
|
||||
|
||||
int ret = namespace_query((char *)(path->data), &cli_hd->data);
|
||||
#if 0
|
||||
if (ret >= 0)
|
||||
{
|
||||
printf("The request service [%s] was successful, hd is %d.\n", (char *)(path->data), cli_hd->data);
|
||||
@@ -46,6 +47,7 @@ RPC_GENERATION_OP2(ns_t, NS_PROT, NS_QUERY_OP, query,
|
||||
{
|
||||
printf("Failed to request service [%s]\n", (char *)(path->data));
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,9 @@ static msg_tag_t rpc_meta_t_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag,
|
||||
|
||||
if (msg_tag_get_prot(in_tag) == META_PROT)
|
||||
{
|
||||
cons_write_str("unknow prot.\n");
|
||||
#if 0
|
||||
cons_write_str("unknow prot.\n"); //FIXME:
|
||||
#endif
|
||||
return msg_tag_init4(0, 0, 0, -EPROTO);
|
||||
}
|
||||
else
|
||||
@@ -112,8 +114,9 @@ static msg_tag_t rpc_meta_t_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag,
|
||||
|
||||
if (svr_obj == NULL)
|
||||
{
|
||||
cons_write_str("unknow prot.\n");
|
||||
|
||||
#if 0
|
||||
cons_write_str("unknow prot.\n"); //FIXME:
|
||||
#endif
|
||||
return msg_tag_init4(0, 0, 0, -EPROTO);
|
||||
}
|
||||
if (svr_obj->dispatch == NULL)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
void u_rel_path_to_abs(const char *cur_path, const char *path, char *new_path);
|
||||
static inline bool_t u_is_root_path(const char *path)
|
||||
{
|
||||
return path[0] == '/' && path[1] == '\0';
|
||||
}
|
||||
@@ -60,6 +60,7 @@ static int path_name_cp(char *dst, const char *src, int src_inx, int *cp_len, in
|
||||
}
|
||||
/**
|
||||
* 相对路径转绝对路径
|
||||
* TODO: new_path可能溢出,增加长度限制
|
||||
* @param cur_path 基路径
|
||||
* @param path 相对路径
|
||||
* @param new_path 输出的路径
|
||||
|
||||
@@ -69,6 +69,7 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
@@ -99,6 +100,8 @@ add_custom_target(
|
||||
mkdir -p ${CMAKE_SOURCE_DIR}/build/output/cpio
|
||||
COMMAND
|
||||
cp appfs.bin ${CMAKE_SOURCE_DIR}/build/output/cpio/appfs
|
||||
COMMAND
|
||||
cp appfs.elf ${CMAKE_SOURCE_DIR}/build/output/
|
||||
)
|
||||
|
||||
add_dependencies(appfs_dump appfs.elf)
|
||||
|
||||
@@ -67,7 +67,7 @@ int fs_svr_fstat(int fd, void *_stat)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = appfs_stat(fd, _stat);
|
||||
ret = appfs_fstat(fd, _stat);
|
||||
return ret;
|
||||
}
|
||||
int fs_svr_ioctl(int fd, int req, void *arg)
|
||||
@@ -106,7 +106,7 @@ int fs_svr_rename(char *oldname, char *newname)
|
||||
}
|
||||
int fs_svr_stat(const char *path, void *_buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return appfs_stat(path, _buf);
|
||||
}
|
||||
ssize_t fs_svr_readlink(const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
|
||||
@@ -80,7 +80,7 @@ int main(int argc, char *argv[])
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
ns_register(mount_path, hd, MOUNT_NODE);
|
||||
ns_register(mount_path, hd, 0);
|
||||
cons_write_str("appfs mount success\n");
|
||||
#if 0
|
||||
fs_svr_loop();
|
||||
|
||||
@@ -228,6 +228,7 @@ int appfs_read(int fd, void *data, int len)
|
||||
#include <u_task.h>
|
||||
#include <u_thread.h>
|
||||
#include <mk_access.h>
|
||||
#include "kstat.h"
|
||||
#endif
|
||||
int appfs_ioctl(int fd, unsigned long cmd, unsigned long arg)
|
||||
{
|
||||
@@ -269,7 +270,7 @@ int appfs_ioctl(int fd, unsigned long cmd, unsigned long arg)
|
||||
fs_arg->size = appfs_get_file_size(dir_info_cache_list[file->dir_info_fd].info);
|
||||
#ifdef MKRTOS
|
||||
ret = mk_copy_mem_to_task(cur_pid, fs_arg, src_pid,
|
||||
(void*)arg, sizeof(appfs_ioctl_arg_t));
|
||||
(void *)arg, sizeof(appfs_ioctl_arg_t));
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
@@ -381,7 +382,7 @@ int appfs_truncate(int fd, off_t length)
|
||||
ret = appfs_file_resize_raw(fs, dir_info_cache_list[file->dir_info_fd].info, length);
|
||||
return ret;
|
||||
}
|
||||
int appfs_stat(int fd, struct stat *st)
|
||||
int appfs_fstat(int fd, struct stat *st)
|
||||
{
|
||||
appfs_file_t *file = appfs_get_file(fd);
|
||||
|
||||
@@ -398,6 +399,28 @@ int appfs_stat(int fd, struct stat *st)
|
||||
st->st_nlink = dir_info_cache_list[file->dir_info_fd].info->ref;
|
||||
return 0;
|
||||
}
|
||||
int appfs_stat(const char *path, struct kstat *st)
|
||||
{
|
||||
const dir_info_t *file;
|
||||
|
||||
if (path[0] == '\0' || (path[0] == '/' && path[1] == '\0'))
|
||||
{
|
||||
st->st_size = 0;
|
||||
st->st_mode = S_IFDIR;
|
||||
st->st_nlink = 0;
|
||||
return 0;
|
||||
}
|
||||
file = appfs_find_file_by_name(fs, path);
|
||||
if (file == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
st->st_size = file->size;
|
||||
st->st_mode = S_IFREG;
|
||||
st->st_nlink = file->ref;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int appfs_close(int fd)
|
||||
{
|
||||
appfs_file_t *file = appfs_get_file(fd);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include "appfs.h"
|
||||
#include "kstat.h"
|
||||
enum appfs_ioctl_cmd_op
|
||||
{
|
||||
APPFS_IOCTOL_GET_ACCESS_ADDR,
|
||||
@@ -17,7 +18,8 @@ int appfs_write(int fd, void *data, int len);
|
||||
int appfs_read(int fd, void *data, int len);
|
||||
int appfs_ioctl(int fd, unsigned long cmd, unsigned long arg);
|
||||
int appfs_lseek(int fd, int offset, unsigned long whence);
|
||||
int appfs_stat(int fd, struct stat *st);
|
||||
int appfs_fstat(int fd, struct stat *st);
|
||||
int appfs_stat(const char *path, struct kstat *st);
|
||||
int appfs_close(int fd);
|
||||
int appfs_remove(const char *name);
|
||||
int appfs_truncate(int fd, off_t length);
|
||||
|
||||
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
ns_register(mount_path, hd, MOUNT_NODE);
|
||||
ns_register(mount_path, hd, 0);
|
||||
cons_write_str("cpiofs mount success\n");
|
||||
|
||||
fs_svr_loop();
|
||||
|
||||
@@ -38,7 +38,7 @@ int main(int args, char *argv[])
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
ns_register("/mnt", hd, MOUNT_NODE);
|
||||
ns_register("/mnt", hd, 0);
|
||||
|
||||
FRESULT res = f_mount(&fs, "0:", 1);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ int main(int argv, char *args[])
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
ns_register("/vfs_test", hd, MOUNT_NODE);
|
||||
ns_register("/vfs_test", hd, 0);
|
||||
printf("cpiofs mount success\n");
|
||||
|
||||
fs_svr_loop();
|
||||
|
||||
@@ -40,6 +40,7 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cutest
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/init/src
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/init/src/nsfs
|
||||
)
|
||||
set_target_properties(init.elf PROPERTIES LINK_FLAGS
|
||||
"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker "
|
||||
|
||||
@@ -28,379 +28,40 @@
|
||||
#include "u_ipc.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_slist.h"
|
||||
#include "nsfs.h"
|
||||
static ns_t ns;
|
||||
static fs_t ns_fs;
|
||||
static pthread_spinlock_t lock;
|
||||
int ns_reg(const char *path, obj_handler_t hd, enum node_type type);
|
||||
int ns_node_free(ns_node_t *node);
|
||||
static int find_path(const char *name);
|
||||
|
||||
static obj_handler_t ns_hd;
|
||||
|
||||
static void ns_lock(void) { pthread_spin_lock(&lock); }
|
||||
static void ns_unlock(void) { pthread_spin_unlock(&lock); }
|
||||
/**
|
||||
* @brief 查找每一个节点,并进行删除
|
||||
*
|
||||
* @param head
|
||||
* @param pid
|
||||
* @param to_del
|
||||
*/
|
||||
static void _ns_node_del_by_pid(slist_head_t *head, pid_t pid, int to_del)
|
||||
{
|
||||
ns_node_t *pos;
|
||||
|
||||
slist_foreach_not_next(pos, head, node)
|
||||
{
|
||||
ns_node_t *next = slist_next_entry(pos, head, node);
|
||||
|
||||
if (pos->type != DIR_NODE) {
|
||||
if (pid == pos->pid) {
|
||||
if (ns_node_free(pos) == 0) {
|
||||
if (to_del) {
|
||||
// task_unmap(TASK_THIS,
|
||||
// vpage_create_raw3(KOBJ_DELETE_RIGHT, 0,
|
||||
// pos->node_hd));
|
||||
handler_del_umap(pos->node_hd);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_ns_node_del_by_pid(&pos->sub_dir, pid, to_del);
|
||||
}
|
||||
|
||||
pos = next;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 从ns删除某个task注册的所有节点
|
||||
*
|
||||
* @param pid
|
||||
* @param to_del
|
||||
*/
|
||||
void ns_node_del_by_pid(pid_t pid, int to_del)
|
||||
{
|
||||
ns_lock();
|
||||
_ns_node_del_by_pid(&ns.root_node.sub_dir, pid, to_del);
|
||||
ns_unlock();
|
||||
}
|
||||
/**
|
||||
* @brief 初始化一个节点
|
||||
*
|
||||
* @param new_node
|
||||
* @param parent
|
||||
* @param name
|
||||
* @param hd
|
||||
* @param type
|
||||
* @return ns_node_t*
|
||||
*/
|
||||
static ns_node_t *node_init(ns_node_t *new_node, ns_node_t *parent,
|
||||
const char *name, obj_handler_t hd,
|
||||
enum node_type type)
|
||||
{
|
||||
strncpy(new_node->node_name, name, sizeof(new_node->node_name));
|
||||
new_node->node_name[sizeof(new_node->node_name) - 1] = 0;
|
||||
new_node->ref = 1;
|
||||
new_node->type = type;
|
||||
new_node->parent = parent;
|
||||
new_node->pid = thread_get_src_pid();
|
||||
if (parent) {
|
||||
parent->ref++; //! 父目录的引用计数+1
|
||||
}
|
||||
slist_init(&new_node->node);
|
||||
switch (type) {
|
||||
case DIR_NODE:
|
||||
slist_init(&new_node->sub_dir);
|
||||
break;
|
||||
case FILE_NODE:
|
||||
case MOUNT_NODE:
|
||||
new_node->node_hd = hd;
|
||||
break;
|
||||
case SYM_NODE:
|
||||
new_node->sym_path[0] = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return new_node;
|
||||
}
|
||||
/**
|
||||
* @brief Create a node object
|
||||
*
|
||||
* @param dir
|
||||
* @param name
|
||||
* @param hd
|
||||
* @param typef
|
||||
* @return ns_node_t*
|
||||
*/
|
||||
static ns_node_t *create_node(ns_node_t *parent, const char *name,
|
||||
obj_handler_t hd, enum node_type type)
|
||||
{
|
||||
ns_node_t *new_node = malloc(sizeof(*new_node));
|
||||
|
||||
if (new_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
node_init(new_node, parent, name, hd, type);
|
||||
return new_node;
|
||||
}
|
||||
/**
|
||||
* @brief 路径分割
|
||||
*
|
||||
* @param name
|
||||
* @return int
|
||||
*/
|
||||
static int path_split(const char *name)
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
for (i = 0; name[i]; i++) {
|
||||
if (name[i] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
* @brief 找到某个节点
|
||||
*
|
||||
* @param dir
|
||||
* @param name
|
||||
* @param ret_inx
|
||||
* @return ns_node_t*
|
||||
*/
|
||||
static ns_node_t *node_lookup(ns_node_t *dir, const char *name,
|
||||
size_t *ret_inx)
|
||||
{
|
||||
int inx = -1;
|
||||
int find_inx = 0;
|
||||
int r_inx = 0;
|
||||
ns_node_t *node = NULL;
|
||||
bool_t find = FALSE;
|
||||
|
||||
if (dir->type != DIR_NODE) {
|
||||
return NULL;
|
||||
}
|
||||
if (name[0] == 0) {
|
||||
*ret_inx = 0;
|
||||
return dir;
|
||||
}
|
||||
node = dir;
|
||||
if (name[0] == '/') {
|
||||
find_inx++;
|
||||
r_inx++;
|
||||
}
|
||||
find = TRUE;
|
||||
|
||||
while (1) {
|
||||
ns_node_t *pos;
|
||||
|
||||
inx = path_split(name + find_inx);
|
||||
if (inx <= 0) {
|
||||
break;
|
||||
}
|
||||
slist_foreach(pos, &(node->sub_dir), node)
|
||||
{
|
||||
if (strncmp(name + find_inx, pos->node_name, inx) != 0) {
|
||||
continue;
|
||||
}
|
||||
switch (pos->type) {
|
||||
case DIR_NODE: {
|
||||
// dir
|
||||
node = pos;
|
||||
r_inx += inx;
|
||||
find = TRUE;
|
||||
} break;
|
||||
case FILE_NODE:
|
||||
case MOUNT_NODE: {
|
||||
find = TRUE;
|
||||
r_inx += inx;
|
||||
node = pos;
|
||||
goto end;
|
||||
} break;
|
||||
case SYM_NODE: {
|
||||
size_t ret_inx;
|
||||
ns_node_t *sym_node =
|
||||
node_lookup(&ns.root_node, pos->sym_path, &ret_inx);
|
||||
|
||||
if (sym_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
node = sym_node;
|
||||
r_inx += inx;
|
||||
find = TRUE;
|
||||
} break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
find_inx += inx;
|
||||
}
|
||||
end:
|
||||
if (!find) {
|
||||
return NULL;
|
||||
}
|
||||
if (ret_inx) {
|
||||
if (name[r_inx] == '/') {
|
||||
r_inx++;
|
||||
}
|
||||
*ret_inx = r_inx;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* @brief 释放一个节点
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
int ns_node_free(ns_node_t *node)
|
||||
{
|
||||
int ref = 0;
|
||||
if (!node) {
|
||||
return 0;
|
||||
}
|
||||
if (node->ref == 1) {
|
||||
//!< 父级目录的引用计数-1
|
||||
ns_node_free(node->parent);
|
||||
}
|
||||
node->ref--;
|
||||
ref = node->ref;
|
||||
if (node->ref <= 0) {
|
||||
switch (node->type) {
|
||||
case DIR_NODE:
|
||||
assert(slist_is_empty(&node->sub_dir));
|
||||
break;
|
||||
case FILE_NODE:
|
||||
case MOUNT_NODE:
|
||||
handler_free_umap(node->node_hd);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
if (slist_in_list(&node->node)) {
|
||||
slist_del(&node->node);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
int fs_svr_open(const char *path, int flags, int mode)
|
||||
{
|
||||
ns_node_t *node;
|
||||
size_t ret_inx;
|
||||
int len;
|
||||
|
||||
// again:
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (!node) {
|
||||
return -ENOENT;
|
||||
}
|
||||
len = strlen(path);
|
||||
if (len != ret_inx) {
|
||||
/* 这里应该用mkdir创建
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
int ret = ns_reg(path, 0, DIR_NODE);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
*/
|
||||
return -ENOENT;
|
||||
}
|
||||
file_desc_t *fd_p = fd_alloc(node);
|
||||
|
||||
if (!fd_p) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
node->ref++;
|
||||
return 0;
|
||||
return fs_ns_open(path, flags, mode);
|
||||
}
|
||||
|
||||
int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
{
|
||||
bool_t is_dec_ref = 0;
|
||||
file_desc_t *fdp = fd_get(fd);
|
||||
|
||||
if (!fdp) {
|
||||
return -ENOENT;
|
||||
}
|
||||
if (fdp->node_iter == (void *)((umword_t)(-1))) {
|
||||
return -ENOENT;
|
||||
}
|
||||
if (fdp->node_iter == NULL) {
|
||||
// 首次迭代
|
||||
if (slist_is_empty(&fdp->node->sub_dir)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
// 获得第一个节点
|
||||
fdp->node_iter =
|
||||
container_of(slist_first(&fdp->node->sub_dir), ns_node_t, node);
|
||||
fdp->node_iter->ref++;
|
||||
}
|
||||
|
||||
// 拷贝数据
|
||||
dir->d_type = fdp->node_iter->type == FILE_NODE ? DT_CHR : DT_DIR;
|
||||
dir->d_reclen = sizeof(*dir);
|
||||
strncpy(dir->d_name, fdp->node_iter->node_name, sizeof(dir->d_name));
|
||||
dir->d_name[sizeof(dir->d_name) - 1] = 0;
|
||||
dir->d_ino = 0;
|
||||
slist_head_t *next = fdp->node_iter->node.next;
|
||||
|
||||
ns_node_free(fdp->node_iter);
|
||||
if (next == &fdp->node->sub_dir) {
|
||||
// 到达结尾
|
||||
fdp->node_iter = (void *)((umword_t)(-1));
|
||||
return sizeof(*dir);
|
||||
} else {
|
||||
ns_node_t *next_n = container_of(next, ns_node_t, node);
|
||||
|
||||
fdp->node_iter = next_n;
|
||||
next_n->ref++;
|
||||
}
|
||||
return sizeof(*dir);
|
||||
return fs_ns_readdir(fd, dir);
|
||||
}
|
||||
void fs_svr_close(int fd)
|
||||
{
|
||||
file_desc_t *fdp = fd_get(fd);
|
||||
|
||||
if (!fdp) {
|
||||
return;
|
||||
}
|
||||
if (fdp->node_iter && fdp->node_iter != (void *)(-1)) {
|
||||
// 最后一个迭代的节点需要删除
|
||||
ns_node_free(fdp->node_iter);
|
||||
}
|
||||
ns_node_free(fdp->node);
|
||||
fd_free(fd);
|
||||
fs_ns_close(fd);
|
||||
}
|
||||
int fs_svr_unlink(const char *path)
|
||||
{
|
||||
ns_node_t *node;
|
||||
size_t ret_inx;
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_svr_mkdir(char *path)
|
||||
{
|
||||
return fs_ns_mkdir(path);
|
||||
}
|
||||
int fs_svr_stat(const char *path, void *_buf)
|
||||
{
|
||||
struct kstat *buf = (struct kstat *)_buf;
|
||||
int ret;
|
||||
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (!node) {
|
||||
return -EEXIST;
|
||||
}
|
||||
if (node && ret_inx == strlen(path)) {
|
||||
if (node->ref == 1) {
|
||||
ns_node_free(node);
|
||||
} else {
|
||||
return -ENOTEMPTY;
|
||||
}
|
||||
} else {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = fs_ns_stat(path, buf);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief 创建一个软链接节点
|
||||
@@ -411,89 +72,7 @@ int fs_svr_unlink(const char *path)
|
||||
*/
|
||||
int fs_svr_symlink(const char *src, const char *dst)
|
||||
{
|
||||
ns_node_t *node;
|
||||
size_t ret_inx;
|
||||
int len;
|
||||
printf("%s:%d. %s --> %s\n", __func__, __LINE__, src, dst);
|
||||
|
||||
node = node_lookup(&ns.root_node, dst, &ret_inx);
|
||||
if (!node) {
|
||||
return -ENOENT;
|
||||
}
|
||||
len = strlen(dst);
|
||||
if (len == ret_inx) {
|
||||
// 已经存在
|
||||
return -EEXIST;
|
||||
}
|
||||
int inx = find_path(dst);
|
||||
|
||||
if (ret_inx != inx) {
|
||||
// 父级目录不存在
|
||||
return -ENOENT;
|
||||
}
|
||||
ns_node_t *new_node = create_node(&ns.root_node, dst + inx, 0, SYM_NODE);
|
||||
|
||||
if (!new_node) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
strncpy(new_node->sym_path, src, NAMESPACE_PATH_LEN);
|
||||
new_node->sym_path[NAMESPACE_PATH_LEN - 1] = 0;
|
||||
assert(node->type == DIR_NODE);
|
||||
slist_add_append(&node->sub_dir, &new_node->node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_path(const char *name)
|
||||
{
|
||||
int len = strlen(name);
|
||||
|
||||
for (int i = len; i >= 0; i--) {
|
||||
if (name[i] == '/') {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* @brief 注册一个节点
|
||||
*
|
||||
* @param path
|
||||
* @param hd
|
||||
* @return int
|
||||
*/
|
||||
int ns_reg(const char *path, obj_handler_t hd, enum node_type type)
|
||||
{
|
||||
size_t ret_inx;
|
||||
ns_node_t *new_node;
|
||||
ns_node_t *node;
|
||||
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (!node) {
|
||||
return -EEXIST;
|
||||
}
|
||||
if (node && ret_inx == strlen(path)) {
|
||||
handler_free_umap(hd);
|
||||
return -EEXIST;
|
||||
}
|
||||
int inx = find_path(path);
|
||||
|
||||
if (ret_inx != inx) {
|
||||
if (inx == -1) {
|
||||
inx = ret_inx;
|
||||
} else {
|
||||
handler_free_umap(hd);
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
new_node = create_node(node, path + inx, hd, type);
|
||||
if (!new_node) {
|
||||
handler_free_umap(hd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
slist_add_append(&node->sub_dir, &new_node->node);
|
||||
|
||||
return 0;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -505,14 +84,9 @@ int ns_reg(const char *path, obj_handler_t hd, enum node_type type)
|
||||
*/
|
||||
int namespace_register(const char *path, obj_handler_t hd, int type)
|
||||
{
|
||||
if (type == DIR_NODE) {
|
||||
handler_free_umap(hd);
|
||||
return -ECANCELED;
|
||||
}
|
||||
ns_lock();
|
||||
int ret = ns_reg(path, hd, type);
|
||||
ns_unlock();
|
||||
printf("register svr, name is %s, hd is %d\n", path, hd);
|
||||
int ret;
|
||||
|
||||
ret = ns_mknode(path, hd, NODE_TYPE_SVR);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
@@ -524,63 +98,21 @@ int namespace_register(const char *path, obj_handler_t hd, int type)
|
||||
*/
|
||||
int namespace_query(const char *path, obj_handler_t *hd)
|
||||
{
|
||||
assert(hd);
|
||||
size_t ret_inx;
|
||||
ns_node_t *new_node;
|
||||
ns_node_t *node;
|
||||
int ret;
|
||||
|
||||
if (path[0] == '/' && path[1] == 0) {
|
||||
*hd = ns_hd;
|
||||
return 1;
|
||||
}
|
||||
ns_lock();
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (!node) {
|
||||
ns_unlock();
|
||||
return -EEXIST;
|
||||
}
|
||||
// if (ret_inx == strlen(path))
|
||||
// {
|
||||
// ns_unlock();
|
||||
// return -EEXIST;
|
||||
// }
|
||||
if (node == &ns.root_node) {
|
||||
*hd = ns_hd;
|
||||
} else {
|
||||
if (node->type == DIR_NODE) {
|
||||
ns_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
*hd = node->node_hd;
|
||||
}
|
||||
ns_unlock();
|
||||
return ret_inx;
|
||||
}
|
||||
#if 0
|
||||
void namespace_loop(void)
|
||||
{
|
||||
rpc_loop();
|
||||
// rpc_mtd_loop();
|
||||
}
|
||||
#endif
|
||||
int fs_svr_mkdir(char *path)
|
||||
{
|
||||
int ret = ns_reg(path, 0, DIR_NODE);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("ns mkdir %s is faile : %d\n", path, ret);
|
||||
}
|
||||
ret = ns_find_svr_obj(path, hd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const fs_operations_t ops =
|
||||
{
|
||||
{
|
||||
.fs_svr_mkdir = fs_svr_mkdir,
|
||||
.fs_svr_symlink = fs_svr_symlink,
|
||||
.fs_svr_unlink = fs_svr_unlink,
|
||||
.fs_svr_close = fs_svr_close,
|
||||
.fs_svr_readdir = fs_svr_readdir,
|
||||
.fs_svr_open = fs_svr_open,
|
||||
.fs_svr_stat = fs_svr_stat,
|
||||
};
|
||||
void namespace_init(obj_handler_t ipc_hd)
|
||||
{
|
||||
@@ -589,7 +121,7 @@ void namespace_init(obj_handler_t ipc_hd)
|
||||
meta_reg_svr_obj(&ns.svr, NS_PROT);
|
||||
meta_reg_svr_obj(&ns_fs.svr, FS_PROT);
|
||||
thread_set_src_pid(0);
|
||||
node_init(&ns.root_node, NULL, "", 0, DIR_NODE);
|
||||
ns_hd = ipc_hd;
|
||||
ns_root_node_init(ipc_hd);
|
||||
// printf("ns svr init...\n");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
static ns_node_t root_node = {
|
||||
.type = NODE_TYPE_DUMMY,
|
||||
};
|
||||
|
||||
void ns_root_node_init(obj_handler_t hd)
|
||||
{
|
||||
root_node.svr_hd = hd;
|
||||
}
|
||||
/**
|
||||
* 从路径中copy名字
|
||||
*/
|
||||
@@ -169,6 +174,7 @@ ns_node_t *ns_node_find(ns_node_t **pnode, const char *path, int *ret, int *svr_
|
||||
name[MIN(NS_NODE_NAME_LEN - 1, len)] = 0;
|
||||
if (len == 0)
|
||||
{
|
||||
// find_node_cut_inx++;
|
||||
goto end;
|
||||
}
|
||||
// 查找子节点
|
||||
@@ -272,7 +278,9 @@ ns_node_t *ns_node_find_full_dir(const char *path, int *ret, int *cur_inx)
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_DUMMY || *cur_inx != 0)
|
||||
{
|
||||
#if 0
|
||||
printf("ns node not find or path error.\n");
|
||||
#endif
|
||||
// 未找到,节点不是dummy节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
@@ -293,7 +301,9 @@ ns_node_t *ns_node_find_full_file(const char *path, int *ret, int *cur_inx)
|
||||
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')
|
||||
{
|
||||
#if 0
|
||||
printf("ns node not find or path error.\n");
|
||||
#endif
|
||||
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
@@ -301,6 +311,10 @@ ns_node_t *ns_node_find_full_file(const char *path, int *ret, int *cur_inx)
|
||||
|
||||
return dir_node;
|
||||
}
|
||||
static inline int is_root_node(ns_node_t *node)
|
||||
{
|
||||
return node == &root_node;
|
||||
}
|
||||
ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx)
|
||||
{
|
||||
assert(path);
|
||||
@@ -309,9 +323,16 @@ ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx)
|
||||
ns_node_t *dir_node;
|
||||
|
||||
dir_node = ns_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (is_root_node(dir_node))
|
||||
{
|
||||
(*cur_inx)++;
|
||||
return dir_node;
|
||||
}
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_SVR)
|
||||
{
|
||||
#if 0
|
||||
printf("ns node not find or path error.\n");
|
||||
#endif
|
||||
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
@@ -319,6 +340,22 @@ ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx)
|
||||
|
||||
return dir_node;
|
||||
}
|
||||
int ns_find_svr_obj(const char *path, obj_handler_t *svr_hd)
|
||||
{
|
||||
assert(path);
|
||||
assert(svr_hd);
|
||||
ns_node_t *svr_node;
|
||||
int ret;
|
||||
int cur_inx;
|
||||
|
||||
svr_node = ns_node_find_svr_file(path, &ret, &cur_inx);
|
||||
if (svr_node == NULL || ret < 0)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
*svr_hd = svr_node->svr_hd;
|
||||
return cur_inx;
|
||||
}
|
||||
/**
|
||||
* 创建一个节点
|
||||
* 只能在前置节点全部为dummy的节点里面创建节点
|
||||
|
||||
@@ -2,22 +2,24 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef MKRTOS
|
||||
#include <ns_types.h>
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define NS_NODE_NAME_LEN 32
|
||||
#ifndef MKRTOS
|
||||
typedef unsigned long obj_handler_t;
|
||||
#define HANDLER_INVALID ((obj_handler_t)(-1))
|
||||
#else
|
||||
#include <u_types.h>
|
||||
#endif
|
||||
|
||||
#define NS_NODE_NAME_LEN 32
|
||||
|
||||
typedef enum node_type
|
||||
{
|
||||
NODE_TYPE_DUMMY, //!< 虚拟节点,可以有子节点
|
||||
NODE_TYPE_SVR, //!< 服务节点,不能有子节点
|
||||
NODE_TYPE_ROOT, //!< ROOT节点
|
||||
} node_type_t;
|
||||
|
||||
typedef struct ns_node
|
||||
@@ -26,14 +28,18 @@ typedef struct ns_node
|
||||
node_type_t type; //!< 节点类型
|
||||
struct ns_node *parent; //!< 父节点
|
||||
struct ns_node *next; //!< 下一个
|
||||
union
|
||||
{
|
||||
// union
|
||||
// {
|
||||
struct ns_node *sub; //!< 子树
|
||||
obj_handler_t svr_hd; //!< 服务节点
|
||||
};
|
||||
// };
|
||||
int ref; //!< 引用计数
|
||||
} ns_node_t;
|
||||
#else
|
||||
#include <u_types.h>
|
||||
#endif
|
||||
|
||||
void ns_root_node_init(obj_handler_t hd);
|
||||
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);
|
||||
@@ -52,3 +58,4 @@ static inline ns_node_t *ns_node_get_first(ns_node_t *tree_node)
|
||||
assert(tree_node);
|
||||
return tree_node->sub;
|
||||
}
|
||||
int ns_find_svr_obj(const char *path, obj_handler_t *svr_hd);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include "ns.h"
|
||||
|
||||
#include "kstat.h"
|
||||
#define DIR_INFO_CACHE_NR 32
|
||||
|
||||
typedef struct dir_info_cache
|
||||
@@ -242,7 +242,7 @@ int fs_ns_truncate(int fd, off_t length)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_ns_stat(int fd, struct stat *st)
|
||||
int fs_ns_fstat(int fd, struct kstat *st)
|
||||
{
|
||||
fs_ns_file_t *file = fs_ns_get_file(fd);
|
||||
|
||||
@@ -256,6 +256,29 @@ int fs_ns_stat(int fd, struct stat *st)
|
||||
st->st_nlink = dir_info_cache_list[file->dir_info_fd].info->ref;
|
||||
return 0;
|
||||
}
|
||||
int fs_ns_stat(const char *path, struct kstat *st)
|
||||
{
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
ns_node_t *file;
|
||||
int ret;
|
||||
int cur_inx;
|
||||
|
||||
file = ns_node_find_full_dir(path, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
file = ns_node_find_full_file(path, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
st->st_size = 0;
|
||||
st->st_mode = file->type != NODE_TYPE_DUMMY ? S_IFREG : S_IFDIR;
|
||||
st->st_nlink = file->ref;
|
||||
return 0;
|
||||
}
|
||||
int fs_ns_close(int fd)
|
||||
{
|
||||
fs_ns_file_t *file = fs_ns_get_file(fd);
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include "ns.h"
|
||||
#include "kstat.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);
|
||||
int fs_ns_ioctl(int fd, unsigned long cmd, unsigned long arg);
|
||||
int fs_ns_lseek(int fd, int offset, unsigned long whence);
|
||||
int fs_ns_truncate(int fd, off_t length);
|
||||
int fs_ns_stat(int fd, struct stat *st);
|
||||
int fs_ns_fstat(int fd, struct kstat *st);
|
||||
int fs_ns_stat(const char *path, struct kstat *st);
|
||||
int fs_ns_close(int fd);
|
||||
int fs_ns_remove(const char *name);
|
||||
int fs_ns_readdir(int fd, struct dirent *_dir);
|
||||
|
||||
@@ -195,7 +195,7 @@ int pm_rpc_kill_task(int pid, int flags)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ns_node_del_by_pid(pid, flags); //!< 从ns中删除
|
||||
// ns_node_del_by_pid(pid, flags); TODO: //!< 从ns中删除
|
||||
pm_del_watch_by_pid(&pm, pid); //!< 从watch中删除
|
||||
#if IS_ENABLED(CONFIG_USING_SIG)
|
||||
pm_send_sig_to_task(&pm, pid, KILL_SIG); //!< 给watch者发送sig
|
||||
|
||||
@@ -14,15 +14,15 @@ int ns_reg(const char *path, obj_handler_t hd, enum node_type type);
|
||||
void ns_test(void)
|
||||
{
|
||||
int ret;
|
||||
ret = ns_reg("/", 0, FILE_NODE);
|
||||
ret = ns_reg("/", 0, 0);
|
||||
assert(ret < 0);
|
||||
ret = ns_reg("/test", 0, FILE_NODE);
|
||||
ret = ns_reg("/test", 0, 0);
|
||||
assert(ret >= 0);
|
||||
ret = ns_reg("/test", 0, FILE_NODE);
|
||||
ret = ns_reg("/test", 0, 0);
|
||||
assert(ret < 0);
|
||||
ret = ns_reg("/test1", 0, DIR_NODE);
|
||||
ret = ns_reg("/test1", 0, 0);
|
||||
assert(ret >= 0);
|
||||
ret = ns_reg("/test2", 0, MOUNT_NODE);
|
||||
ret = ns_reg("/test2", 0, 0);
|
||||
assert(ret >= 0);
|
||||
|
||||
int fd;
|
||||
|
||||
@@ -23,7 +23,7 @@ static umword_t addr;
|
||||
static umword_t size;
|
||||
obj_handler_t net_drv_hd = HANDLER_INVALID;
|
||||
|
||||
#define STACK_COM_ITME_SIZE (2 * 1024/*sizeof(struct pthread) + TP_OFFSET*/)
|
||||
#define STACK_COM_ITME_SIZE (2 * 1024 /*sizeof(struct pthread) + TP_OFFSET*/)
|
||||
#define STACK_NUM 4
|
||||
ATTR_ALIGN(8)
|
||||
static uint8_t stack_coms[STACK_COM_ITME_SIZE * STACK_NUM];
|
||||
@@ -31,7 +31,8 @@ static uint8_t msg_buf_coms[MSG_BUG_LEN * STACK_NUM];
|
||||
static obj_handler_t com_th_obj[STACK_NUM];
|
||||
static void fast_ipc_init(void)
|
||||
{
|
||||
for (int i = 0; i < STACK_NUM; i++) {
|
||||
for (int i = 0; i < STACK_NUM; i++)
|
||||
{
|
||||
com_th_obj[i] = handler_alloc();
|
||||
assert(com_th_obj[i] != HANDLER_INVALID);
|
||||
}
|
||||
@@ -45,22 +46,25 @@ int main(int args, char *argv[])
|
||||
obj_handler_t hd;
|
||||
obj_handler_t sem_hd;
|
||||
obj_handler_t shm_hd;
|
||||
int count_net_link =0 ;
|
||||
int count_net_link = 0;
|
||||
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_net");
|
||||
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_net");
|
||||
printf("net startup..\n");
|
||||
fast_ipc_init();
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("rpc meta init failed\n");
|
||||
return -1;
|
||||
}
|
||||
again:
|
||||
ret = ns_query("/eth", &net_drv_hd, 0x1);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
u_sleep_ms(50);
|
||||
count_net_link++;
|
||||
if (count_net_link < 20) {
|
||||
if (count_net_link < 20)
|
||||
{
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
@@ -74,49 +78,63 @@ again:
|
||||
IP_ADDR4(&perf_server_ip, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
|
||||
lwiperf_start_tcp_server(&perf_server_ip, 9527, NULL, NULL);
|
||||
|
||||
if (net_drv_hd != HANDLER_INVALID) {
|
||||
if (blk_drv_cli_map(net_drv_hd, &sem_hd) < 0) {
|
||||
if (net_drv_hd != HANDLER_INVALID)
|
||||
{
|
||||
if (blk_drv_cli_map(net_drv_hd, &sem_hd) < 0)
|
||||
{
|
||||
printf("net drv sem map error.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
shm_hd = handler_alloc();
|
||||
if (shm_hd == HANDLER_INVALID) {
|
||||
if (shm_hd == HANDLER_INVALID)
|
||||
{
|
||||
printf("handler alloc failed.\n");
|
||||
return -1;
|
||||
}
|
||||
tag = facotry_create_share_mem(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, shm_hd),
|
||||
SHARE_MEM_CNT_BUDDY_CNT, 2048);
|
||||
if (msg_tag_get_val(tag) < 0) {
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
printf("share mem create failed.\n");
|
||||
return -1;
|
||||
}
|
||||
tag = share_mem_map(shm_hd, vma_addr_create(VPAGE_PROT_RW, VMA_ADDR_RESV, 0), &addr, &size);
|
||||
if (msg_tag_get_val(tag) < 0) {
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
printf("share mem map failed.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ns_register("/net", hd, MOUNT_NODE);
|
||||
if (ret < 0) {
|
||||
ret = ns_register("/net", hd, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("ns reg failed.\n");
|
||||
return -1;
|
||||
}
|
||||
cons_write_str("net mount success\n");
|
||||
// net_test();
|
||||
while (1) {
|
||||
while (1)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (net_drv_hd != HANDLER_INVALID) {
|
||||
if (msg_tag_get_prot(u_sema_down(sem_hd, 0, NULL)) < 0) {
|
||||
if (net_drv_hd != HANDLER_INVALID)
|
||||
{
|
||||
if (msg_tag_get_prot(u_sema_down(sem_hd, 0, NULL)) < 0)
|
||||
{
|
||||
printf("error.\n");
|
||||
}
|
||||
ret = blk_drv_cli_read(net_drv_hd, shm_hd, 0, 0);
|
||||
if (ret > 0) {
|
||||
if (ret > 0)
|
||||
{
|
||||
lwip_pkt_handle_raw((uint8_t *)addr, ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u_sleep_ms(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ int main(int argc, char *args[])
|
||||
assert(ret >= 0);
|
||||
meta_reg_svr_obj(&net_drv.svr, BLK_DRV_PROT);
|
||||
|
||||
assert(ns_register("/dm9000", hd, MOUNT_NODE) >= 0);
|
||||
assert(ns_register("/dm9000", hd, 0) >= 0);
|
||||
mk_printf("dm9000 reg success\n");
|
||||
|
||||
assert(DM9000_Init(1) == 0);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mr_api.h>
|
||||
int main(int argc, char *args[])
|
||||
{
|
||||
ns_register("/dev", drv_svr_init(), MOUNT_NODE);
|
||||
ns_register("/dev", drv_svr_init(), 0);
|
||||
mr_auto_init();
|
||||
printf("mr drv start success...\n");
|
||||
drv_svr_loop();
|
||||
|
||||
@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
|
||||
blk_drv_init(&blk_drv);
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
ns_register(argv[1], hd, FILE_NODE);
|
||||
ns_register(argv[1], hd, 0);
|
||||
meta_reg_svr_obj(&blk_drv.svr, BLK_DRV_PROT);
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
// mkdir("/dev", 0777);
|
||||
ns_register("/display", hd, FILE_NODE);
|
||||
ns_register("/display", hd, 0);
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(0);
|
||||
|
||||
@@ -98,7 +98,7 @@ int main(int argc, char *argv[])
|
||||
assert(ret >= 0);
|
||||
// fs_svr_init();
|
||||
// mkdir("/dev", 0777);
|
||||
ns_register("/eth", hd, FILE_NODE);
|
||||
ns_register("/eth", hd, 0);
|
||||
meta_reg_svr_obj(&net_drv.svr, BLK_DRV_PROT);
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
// mkdir("/dev", 0777);
|
||||
ns_register("/i2c2", hd, FILE_NODE);
|
||||
ns_register("/i2c2", hd, 0);
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(0);
|
||||
|
||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
// mkdir("/dev", 0777);
|
||||
ns_register("/pca9555", hd, FILE_NODE);
|
||||
ns_register("/pca9555", hd, 0);
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(0);
|
||||
|
||||
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
// mkdir("/dev", 0777);
|
||||
ns_register("/pin", hd, FILE_NODE);
|
||||
ns_register("/pin", hd, 0);
|
||||
while (1)
|
||||
{
|
||||
u_sleep_ms(0);
|
||||
|
||||
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
|
||||
blk_drv_init(&snd_drv);
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
ns_register("/snd", hd, FILE_NODE);
|
||||
ns_register("/snd", hd, 0);
|
||||
meta_reg_svr_obj(&snd_drv.svr, BLK_DRV_PROT);
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
|
||||
blk_drv_init(&blk_drv);
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
ns_register(argv[1], hd, FILE_NODE);
|
||||
ns_register(argv[1], hd, 0);
|
||||
meta_reg_svr_obj(&blk_drv.svr, BLK_DRV_PROT);
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include "u_hd_man.h"
|
||||
#include "u_vmam.h"
|
||||
#define STACK_COM_ITME_SIZE (1024 + 512)
|
||||
@@ -34,7 +35,7 @@ static void fast_ipc_init(void)
|
||||
static blk_drv_t blk_drv;
|
||||
static uint8_t *blk_data;
|
||||
static int blk_nr;
|
||||
static int blk_size;
|
||||
static size_t blk_size;
|
||||
|
||||
int blk_drv_write(obj_handler_t obj, int len, int inx)
|
||||
{
|
||||
@@ -98,7 +99,7 @@ int blk_drv_info(blk_drv_info_t *info)
|
||||
{
|
||||
info->blk_nr = blk_nr;
|
||||
info->blk_size = blk_size;
|
||||
info->blk_start_addr = blk_data;
|
||||
info->blk_start_addr = (umword_t)blk_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ int main(int argc, char *argv[])
|
||||
blk_drv_init(&blk_drv);
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
ns_register(dev_path, hd, FILE_NODE);
|
||||
ns_register(dev_path, hd, 0);
|
||||
meta_reg_svr_obj(&blk_drv.svr, BLK_DRV_PROT);
|
||||
|
||||
while (1)
|
||||
|
||||
Reference in New Issue
Block a user