| 106 | } |
| 107 | |
| 108 | auto MountTable::Unmount(const char* path) -> Expected<void> { |
| 109 | if (path == nullptr) { |
| 110 | return std::unexpected(Error(ErrorCode::kInvalidArgument)); |
| 111 | } |
| 112 | |
| 113 | // 查找挂载点 |
| 114 | MountPoint* mp = nullptr; |
| 115 | size_t mp_index = 0; |
| 116 | for (size_t i = 0; i < kMaxMounts; ++i) { |
| 117 | if (mounts_[i].active && strcmp(mounts_[i].mount_path, path) == 0) { |
| 118 | mp = &mounts_[i]; |
| 119 | mp_index = i; |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | if (mp == nullptr) { |
| 125 | return std::unexpected(Error(ErrorCode::kFsNotMounted)); |
| 126 | } |
| 127 | |
| 128 | // 卸载文件系统 |
| 129 | auto result = mp->filesystem->Unmount(); |
| 130 | if (!result.has_value()) { |
| 131 | return std::unexpected(result.error()); |
| 132 | } |
| 133 | |
| 134 | // 清理挂载点(RAII) |
| 135 | etl::unique_ptr<Dentry> root_guard(mp->root_dentry); |
| 136 | |
| 137 | mp->active = false; |
| 138 | mp->mount_path = nullptr; |
| 139 | mp->mount_dentry = nullptr; |
| 140 | mp->filesystem = nullptr; |
| 141 | mp->device = nullptr; |
| 142 | mp->root_inode = nullptr; |
| 143 | mp->root_dentry = nullptr; |
| 144 | |
| 145 | --mount_count_; |
| 146 | |
| 147 | // 如果是根挂载,清除 root_mount_ |
| 148 | if (root_mount_ == &mounts_[mp_index]) { |
| 149 | root_mount_ = nullptr; |
| 150 | extern void SetRootDentry(Dentry*); |
| 151 | SetRootDentry(nullptr); |
| 152 | } |
| 153 | |
| 154 | klog::Info("MountTable: unmounted '{}'", path); |
| 155 | return {}; |
| 156 | } |
| 157 | |
| 158 | auto MountTable::Lookup(const char* path) -> MountPoint* { |
| 159 | if (path == nullptr || path[0] != '/') { |
no test coverage detected