SimpleKernel 1.17.0
Loading...
Searching...
No Matches
unlink.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 Unlink(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 file_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(file_name, path[0] == '/' ? path + 1 : path, sizeof(file_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(file_name, last_slash + 1, sizeof(file_name));
36 }
37 file_name[sizeof(file_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, file_name);
52 if (target_dentry == nullptr) {
53 return std::unexpected(Error(ErrorCode::kFsFileNotFound));
54 }
55
56 if (target_dentry->inode == nullptr) {
57 return std::unexpected(Error(ErrorCode::kFsCorrupted));
58 }
59
60 // 不能删除目录
61 if (target_dentry->inode->type == FileType::kDirectory) {
62 return std::unexpected(Error(ErrorCode::kFsIsADirectory));
63 }
64
65 // 删除文件
66 if (parent_dentry->inode->ops == nullptr) {
67 return std::unexpected(Error(ErrorCode::kDeviceNotSupported));
68 }
69
70 auto result =
71 parent_dentry->inode->ops->Unlink(parent_dentry->inode, file_name);
72 if (!result.has_value()) {
73 return std::unexpected(result.error());
74 }
75
76 // 从父目录中移除 dentry
77 RemoveChild(parent_dentry, target_dentry);
78
79 if (target_dentry->ref_count > 0) {
80 target_dentry->deleted = true;
81 target_dentry->inode = nullptr;
82 } else {
83 etl::unique_ptr<Dentry> dentry_guard(target_dentry);
84 }
85
86 klog::Debug("VFS: unlinked '{}'", path);
87 return {};
88}
89
90} // namespace vfs
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
virtual auto Unlink(Inode *dir, const char *name) -> Expected< void >=0
删除文件(解除链接)
@ kInvalidArgument
@ kDeviceNotSupported
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 Unlink(const char *path) -> Expected< void >
删除文件
Definition unlink.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
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