SimpleKernel 1.17.0
Loading...
Searching...
No Matches
mkdir.cpp
Go to the documentation of this file.
1
5#include "filesystem.hpp"
6#include "kernel_log.hpp"
7#include "kstd_cstring"
8#include "kstd_memory"
9#include "spinlock.hpp"
10#include "vfs_internal.hpp"
11
12namespace vfs {
13
14auto MkDir(const char* path) -> Expected<void> {
15 if (path == nullptr) {
16 return std::unexpected(Error(ErrorCode::kInvalidArgument));
17 }
18
19 LockGuard<SpinLock> guard(GetVfsState().vfs_lock_);
20 // 解析父目录路径和目录名
21 char parent_path[512];
22 char dir_name[256];
23 const char* last_slash = strrchr(path, '/');
24 if (last_slash == nullptr || last_slash == path) {
25 strncpy(parent_path, "/", sizeof(parent_path));
26 const char* name_start = path[0] == '/' ? path + 1 : path;
27 if (strlen(name_start) >= sizeof(dir_name)) {
28 return std::unexpected(Error(ErrorCode::kFsInvalidPath));
29 }
30 strncpy(dir_name, name_start, sizeof(dir_name));
31 } else {
32 size_t parent_len = last_slash - path;
33 if (parent_len >= sizeof(parent_path)) {
34 return std::unexpected(Error(ErrorCode::kFsInvalidPath));
35 }
36 strncpy(parent_path, path, parent_len);
37 parent_path[parent_len] = '\0';
38 if (strlen(last_slash + 1) >= sizeof(dir_name)) {
39 return std::unexpected(Error(ErrorCode::kFsInvalidPath));
40 }
41 strncpy(dir_name, last_slash + 1, sizeof(dir_name));
42 }
43 dir_name[sizeof(dir_name) - 1] = '\0';
44
45 // 查找父目录
46 auto parent_result = Lookup(parent_path);
47 if (!parent_result.has_value()) {
48 return std::unexpected(parent_result.error());
49 }
50
51 Dentry* parent_dentry = parent_result.value();
52 if (parent_dentry->inode == nullptr ||
53 parent_dentry->inode->type != FileType::kDirectory) {
54 return std::unexpected(Error(ErrorCode::kFsNotADirectory));
55 }
56
57 // 检查目录是否已存在
58 if (FindChild(parent_dentry, dir_name) != nullptr) {
59 return std::unexpected(Error(ErrorCode::kFsFileExists));
60 }
61
62 // 创建目录
63 if (parent_dentry->inode->ops == nullptr) {
64 return std::unexpected(Error(ErrorCode::kDeviceNotSupported));
65 }
66
67 auto result =
68 parent_dentry->inode->ops->Mkdir(parent_dentry->inode, dir_name);
69 if (!result.has_value()) {
70 return std::unexpected(result.error());
71 }
72
73 // 创建 dentry
74 auto new_dentry = kstd::make_unique<Dentry>();
75 if (!new_dentry) {
76 return std::unexpected(Error(ErrorCode::kOutOfMemory));
77 }
78
79 strncpy(new_dentry->name, dir_name, sizeof(new_dentry->name) - 1);
80 new_dentry->name[sizeof(new_dentry->name) - 1] = '\0';
81 new_dentry->inode = result.value();
82 AddChild(parent_dentry, new_dentry.release());
83
84 klog::Debug("VFS: created directory '{}'", path);
85 return {};
86}
87
88} // namespace vfs
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
virtual auto Mkdir(Inode *dir, const char *name) -> Expected< Inode * >=0
创建目录
@ kInvalidArgument
@ kDeviceNotSupported
@ kFsNotADirectory
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
auto AddChild(Dentry *parent, Dentry *child) -> void
添加子 dentry
Definition vfs.cpp:53
auto FindChild(Dentry *parent, const char *name) -> Dentry *
在 dentry 的子节点中查找指定名称
Definition vfs.cpp:38
@ kDirectory
目录
auto MkDir(const char *path) -> Expected< void >
创建目录
Definition mkdir.cpp:14
auto GetVfsState() -> VfsState &
Definition vfs.cpp:17
auto Lookup(const char *path) -> Expected< Dentry * >
路径解析,查找 dentry
Definition lookup.cpp:14
#define strlen
#define strncpy
#define strrchr
错误类型,用于 std::expected
Definition expected.hpp:343
Dentry — 目录项缓存(路径名 ↔ Inode 的映射)
Definition vfs.hpp:41
Inode * inode
关联的 inode
Definition vfs.hpp:45
FileType type
文件类型
Definition vfs.hpp:20
InodeOps * ops
文件操作接口
Definition vfs.hpp:33