SimpleKernel 1.17.0
Loading...
Searching...
No Matches
rmdir.cpp
Go to the documentation of this file.
1
5#include <etl/memory.h>
6
7#include "filesystem.hpp"
8#include "kernel_log.hpp"
9#include "kstd_cstring"
10#include "spinlock.hpp"
11#include "vfs_internal.hpp"
12
13namespace vfs {
14
15auto RmDir(const char* path) -> Expected<void> {
16 if (path == nullptr) {
17 return std::unexpected(Error(ErrorCode::kInvalidArgument));
18 }
19
20 LockGuard<SpinLock> guard(GetVfsState().vfs_lock_);
21 // 解析父目录路径和目录名
22 char parent_path[512];
23 char dir_name[256];
24 const char* last_slash = strrchr(path, '/');
25 if (last_slash == nullptr || last_slash == path) {
26 strncpy(parent_path, "/", sizeof(parent_path));
27 strncpy(dir_name, path[0] == '/' ? path + 1 : path, sizeof(dir_name));
28 } else {
29 size_t parent_len = last_slash - path;
30 if (parent_len >= sizeof(parent_path)) {
31 parent_len = sizeof(parent_path) - 1;
32 }
33 strncpy(parent_path, path, parent_len);
34 parent_path[parent_len] = '\0';
35 strncpy(dir_name, last_slash + 1, sizeof(dir_name));
36 }
37 dir_name[sizeof(dir_name) - 1] = '\0';
38
39 // 查找父目录
40 auto parent_result = Lookup(parent_path);
41 if (!parent_result.has_value()) {
42 return std::unexpected(parent_result.error());
43 }
44
45 Dentry* parent_dentry = parent_result.value();
46 if (parent_dentry->inode == nullptr) {
47 return std::unexpected(Error(ErrorCode::kFsCorrupted));
48 }
49
50 // 查找目标目录
51 Dentry* target_dentry = FindChild(parent_dentry, dir_name);
52 if (target_dentry == nullptr) {
53 return std::unexpected(Error(ErrorCode::kFsFileNotFound));
54 }
55
56 if (target_dentry->inode == nullptr ||
57 target_dentry->inode->type != FileType::kDirectory) {
58 return std::unexpected(Error(ErrorCode::kFsNotADirectory));
59 }
60
61 // 检查目录是否为空
62 if (target_dentry->children != nullptr) {
63 return std::unexpected(Error(ErrorCode::kFsNotEmpty));
64 }
65
66 // 删除目录
67 if (parent_dentry->inode->ops == nullptr) {
68 return std::unexpected(Error(ErrorCode::kDeviceNotSupported));
69 }
70
71 auto result =
72 parent_dentry->inode->ops->Rmdir(parent_dentry->inode, dir_name);
73 if (!result.has_value()) {
74 return std::unexpected(result.error());
75 }
76
77 // 从父目录中移除 dentry
78 RemoveChild(parent_dentry, target_dentry);
79
80 if (target_dentry->ref_count > 0) {
81 target_dentry->deleted = true;
82 target_dentry->inode = nullptr;
83 } else {
84 etl::unique_ptr<Dentry> dentry_guard(target_dentry);
85 }
86
87 klog::Debug("VFS: removed directory '{}'", path);
88 return {};
89}
90
91} // namespace vfs
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
virtual auto Rmdir(Inode *dir, const char *name) -> Expected< void >=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 RemoveChild(Dentry *parent, Dentry *child) -> void
从父 dentry 中移除子 dentry
Definition vfs.cpp:63
auto FindChild(Dentry *parent, const char *name) -> Dentry *
在 dentry 的子节点中查找指定名称
Definition vfs.cpp:38
@ kDirectory
目录
auto RmDir(const char *path) -> Expected< void >
删除目录
Definition rmdir.cpp:15
auto GetVfsState() -> VfsState &
Definition vfs.cpp:17
auto Lookup(const char *path) -> Expected< Dentry * >
路径解析,查找 dentry
Definition lookup.cpp:14
#define strncpy
#define strrchr
错误类型,用于 std::expected
Definition expected.hpp:343
Dentry — 目录项缓存(路径名 ↔ Inode 的映射)
Definition vfs.hpp:41
bool deleted
标记为已删除(unlink/rmdir 时 ref_count > 0)
Definition vfs.hpp:57
Dentry * children
子目录项链表头
Definition vfs.hpp:49
uint32_t ref_count
引用计数(打开的 File 数量)
Definition vfs.hpp:55
Inode * inode
关联的 inode
Definition vfs.hpp:45
FileType type
文件类型
Definition vfs.hpp:20
InodeOps * ops
文件操作接口
Definition vfs.hpp:33