Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • P proj5-FAT32onMaQueOS
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Terraform modules
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • CrewUnionProblemKill
  • proj5-FAT32onMaQueOS
  • Wiki
  • 系统调用文档
  • sys_destroy 函数介绍

sys_destroy 函数介绍 · Changes

Page history
Create 系统调用文档/sys_destroy 函数介绍 authored Jun 15, 2024 by Little Leaf's avatar Little Leaf
Hide whitespace changes
Inline Side-by-side
系统调用文档/sys_destroy-函数介绍.md 0 → 100644
View page @ 37177d95
# 源代码
```c
int fat32_destroy(struct block_device *device, const char *filename) {
struct fat32_dir_entry entry
uint32_t cluster
int i
// 查找文件目录项
if (find_directory_entry(device, filename, &entry) != 0) {
return -1 // 文件不存在
}
// 检查文件是否被任何进程使用
for (i = 0 i < NR_PROCESS i++) {
if (process[i] == 0)
continue
if (process[i]->executable == &entry)
panic("panic: can not destroy opened executable!\n")
for (int j = 0 j < NR_FILE j++) {
if (process[i]->file_table[j].inode == &entry)
panic("panic: can not destroy opened file!\n")
}
}
// 释放文件占用的簇
cluster = ((uint32_t)entry.fst_clus_hi << 16) | entry.fst_clus_lo
while (cluster < 0x0FFFFFF8) {
uint32_t next_cluster = read_fat_entry(device, cluster)
free_cluster(device, cluster)
cluster = next_cluster
}
// 删除文件目录项
if (delete_directory_entry(device, filename) != 0) {
return -1
}
return 0
}
uint32_t read_fat_entry(struct block_device *device, uint32_t cluster) {
// 实现读取FAT表条目的逻辑
}
void free_cluster(struct block_device *device, uint32_t cluster) {
// 实现释放簇的逻辑
}
int delete_directory_entry(struct block_device *device, const char *filename) {
// 实现删除目录项的逻辑
}
```
## 1
```c
if (find_directory_entry(device, filename, &entry) != 0) {
return -1 // 文件不存在
}
```
检查函数`find_directory_entry`的返回值是否不等于0。具体解释如下:
- `find_directory_entry(device, filename, &entry)`: 这是一个函数调用,其中`device`、`filename`是传入的参数,`&entry`是传入的指向`entry`变量的指针,通常用来接收函数的输出结果。
- `!= 0`: 这是一个比较操作符,表示“不等于0”。
整个条件语句 `find_directory_entry(device, filename, &entry) != 0` 的意思是:如果函数 `find_directory_entry` 返回的值不等于0,那么条件成立。
一般情况下,返回值为0表示函数执行成功,非0表示执行失败。所以这句话可以理解为:如果 `find_directory_entry` 函数执行失败(即返回值不为0),那么条件成立。常见的用法是用于错误检查或异常处理。
在这个例子中,如果 `find_directory_entry` 函数返回一个非0值(表示错误),程序将执行`printf`函数,输出错误信息。
## 2
```c
// 检查文件是否被任何进程使用
for (i = 0 i < NR_PROCESS i++) {
if (process[i] == 0)
continue
if (process[i]->executable == &entry)
panic("panic: can not destroy opened executable!\n")
for (int j = 0 j < NR_FILE j++) {
if (process[i]->file_table[j].inode == &entry)
panic("panic: can not destroy opened file!\n")
}
}
```
### 关键术语解释
1. **process[]**:
- `process` 数组,表示系统中的所有进程。数组的每个元素都是一个指向进程控制块(PCB)的指针。PCB 是一个结构体,包含了进程的所有信息。
- `process[i]` 代表数组中的第 `i` 个进程的 PCB 指针。如果 `process[i]` 为 `0`,则表示该位置没有进程(可能是一个空闲位置或进程已终止)。
2. **process[i]->executable**:
- `process[i]` 是指向第 `i` 个进程控制块的指针。
- `process[i]->executable` 表示该进程当前正在执行的可执行文件的指针。
- 代码中 `if (process[i]->executable == &entry)` 的意思是检查当前进程是否正在执行的可执行文件是我们试图销毁的文件 `entry`。如果是,则调用 `panic` 函数,输出错误信息并终止操作。
3. **process[i]->file_table**:
- `process[i]->file_table` 数组,表示该进程打开的文件表。每个元素都是一个文件描述符,包含了关于打开文件的信息。
- `process[i]->file_table[j].inode` 表示该进程第 `j` 个打开文件的 inode(索引节点),inode 是文件系统中的数据结构,包含了文件的元数据和数据块指针。
- 代码中 `if (process[i]->file_table[j].inode == &entry)` 的意思是检查该进程的第 `j` 个打开文件是否是我们试图销毁的文件 `entry`。如果是,则调用 `panic` 函数,输出错误信息并终止操作。
### 代码解释
1. 外层 `for` 循环遍历系统中的每个进程(`NR_PROCESS` 是系统中的最大进程数量)。
2. `if (process[i] == 0)` 检查当前数组位置是否有进程,如果没有则继续下一个位置。
3. `if (process[i]->executable == &entry)` 检查当前进程是否正在执行我们想要销毁的可执行文件,如果是则调用 `panic`,终止操作并输出错误信息。
4. 内层 `for` 循环遍历当前进程的文件表(`NR_FILE` 是每个进程可以打开的最大文件数量)。
5. `if (process[i]->file_table[j].inode == &entry)` 检查当前进程是否打开了我们想要销毁的文件,如果是则调用 `panic`,终止操作并输出错误信息。
这个检查机制确保了文件在被销毁前没有被任何进程使用,从而避免系统错误或进程崩溃。
## 3
```c
// 释放文件占用的簇
cluster = ((uint32_t)entry.fst_clus_hi << 16) | entry.fst_clus_lo
while (cluster < 0x0FFFFFF8) {
uint32_t next_cluster = read_fat_entry(device, cluster)
free_cluster(device, cluster)
cluster = next_cluster
}
cluster = ((uint32_t)entry.fst_clus_hi << 16) | entry.fst_clus_lo
```
计算一个文件的起始簇号(cluster number)具体解释如下:
```c
cluster = ((uint32_t)entry.fst_clus_hi << 16) | entry.fst_clus_lo
```
### 关键术语解释
1. **entry.fst_clus_hi** 和 **entry.fst_clus_lo**:
- 表示文件起始簇号的高16位和低16位。
- `entry.fst_clus_hi` 是文件起始簇号的高16位。
- `entry.fst_clus_lo` 是文件起始簇号的低16位。
2. **(uint32_t)**:
- 这是一个类型转换,将`entry.fst_clus_hi`强制转换为32位无符号整数(`uint32_t`),确保在位操作时不会发生溢出。
3. **<< 16**:
- 这是一个左移操作,将高16位的起始簇号左移16位,从而腾出低16位的位置。
4. **|**:
- 这是一个按位或操作符,用于将高16位和低16位组合成一个32位的起始簇号。
### 代码解释
1. **(uint32_t)entry.fst_clus_hi << 16**:
- 首先,将 `entry.fst_clus_hi` 转换为 `uint32_t` 类型,然后左移16位。这一步将高16位移动到一个32位整数的高16位位置。
2. **entry.fst_clus_lo**:
- 直接使用低16位的起始簇号。
3. **按位或操作 |**:
- 将高16位和低16位组合成一个32位的起始簇号。
### 总结
这句话的意思是:
- 将 `entry.fst_clus_hi`(文件起始簇号的高16位)左移16位,并将结果与 `entry.fst_clus_lo`(文件起始簇号的低16位)进行按位或操作,最终得到文件的完整起始簇号,并将其赋值给变量 `cluster`。
完整的计算过程如下:
- `entry.fst_clus_hi` 是文件起始簇号的高16位,左移16位后得到一个32位的整数,其中高16位是原来的高16位,低16位是0。
- `entry.fst_clus_lo` 是文件起始簇号的低16位,直接使用。
- 将上述两个结果按位或操作,得到完整的32位文件起始簇号。
## 4
```c
while (cluster < 0x0FFFFFF8) {
uint32_t next_cluster = read_fat_entry(device, cluster)
free_cluster(device, cluster)
cluster = next_cluster
}
```
### 关键术语解释
1. **cluster**:
- 当前正在处理的簇号。
2. **0x0FFFFFF8**:
- FAT32文件系统中用于表示簇链结束的标记。簇号小于 `0x0FFFFFF8` 表示还有下一个簇,大于或等于这个值表示簇链结束。
3. **read_fat_entry(device, cluster)**:
- 这个函数读取FAT表中的条目,获取当前簇号 `cluster` 的下一个簇号 `next_cluster`。
4. **free_cluster(device, cluster)**:
- 这个函数释放当前簇号 `cluster`,将其标记为未使用。
### 代码解释
1. **while (cluster < 0x0FFFFFF8)**:
- 这个循环持续执行,直到遇到FAT表中表示簇链结束的簇号(即 `cluster` >= `0x0FFFFFF8`)。
2. **uint32_t next_cluster = read_fat_entry(device, cluster)**:
- 调用 `read_fat_entry` 函数,读取当前簇号 `cluster` 的下一个簇号,并将其存储在 `next_cluster` 变量中。
3. **free_cluster(device, cluster)**:
- 调用 `free_cluster` 函数,释放当前簇号 `cluster`,将其标记为未使用。这一步是删除文件或目录时实际释放磁盘空间的操作。
4. **cluster = next_cluster**:
- 将 `next_cluster` 赋值给 `cluster`,以便在下一次循环中处理下一个簇。
### 总结
这段代码的作用是遍历文件的簇链,并逐一释放每个簇。具体步骤如下:
1. 检查当前簇号是否小于 `0x0FFFFFF8`,如果是,则继续循环。
2. 读取当前簇号的下一个簇号。
3. 释放当前簇号,使其标记为未使用。
4. 更新当前簇号为下一个簇号,并重复上述步骤,直到簇号达到或超过 `0x0FFFFFF8`,表示簇链结束。
这样可以确保文件或目录占用的所有簇都被正确释放。
## 5
```c
// 删除文件目录项
if (delete_directory_entry(device, filename) != 0) {
return -1
}
return 0
```
删除文件目录项
```c
if (delete_directory_entry(device, filename) != 0) {
return -1
}
```
delete_directory_entry: 删除目录项。
如果删除失败,则返回-1。
返回成功
```c
return 0
```
返回0: 表示文件删除成功。
Clone repository
  • Home
  • uploads
    • 0bc768dbb7fc0582616552f906240a99
      • Readme
  • 云端开发环境
  • 文档规范
  • 比赛题目分析和相关资料调研
  • 系统测试
  • 系统调用文档
    • sys_create函数
    • sys_destroy 函数介绍
      • find_directory_entry 函数介绍
        • read_custor 函数介绍
    • sys_mount 函数介绍