文件系统open操作流程

本文详细解析了Linux系统中文件操作的过程,从sys_open到open_namei,再到path_walk及vfs_create等关键步骤。特别关注了目录打开时的错误处理机制及后续的dentry_open流程,包括get_empty_filp、get_write_access、file_move等环节。

sys_open-->open_namei-->path_walk

                                    -->(vfs_create)

                                    -->( error = -EISDIR; if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)))    

 

 

             -->dentry_open-->get_empty_filp

                                   -->(get_write_access)

                                   -->file_move

                                   -->(f_op->open)  

 

 

 

opendir 也是调用sys_open

<think> 我们正在讨论操作系统中打开文件的流程。根据之前的引用,用户询问的是操作系统打开文件的流程,而引用中提到了open系统调用的过程。因此,我们将根据引用[1]和引用[2]来整理打开文件的流程。 根据引用[1]: 1. 根据文件存放路径找到相应的目录文件,从目录中找到文件名对应的目录项,并检查该用户是否有指定的操作权限。 2. 将目录项复制到内存中的“打开文件表”中。并将对应表目的编号返回给用户。 根据引用[2]: 1. 用户提供路径和文件名,操作系统根据路径和文件名找到FCB(文件控制块)并调入内存。注意,调入内存的是FCB,而不是整个文件。 2. 在打开文件表中添加表项,然后open系统调用返回一个文件描述符(即打开文件表表项的索引值)。 因此,我们可以将打开文件的流程总结如下: 1. **解析路径和文件名**:用户通过open系统调用提供文件的路径和文件名。 2. **查找目录项**:操作系统根据路径遍历目录结构,找到目标文件对应的目录项(在UNIX-like系统中是inode,在FAT文件系统中可能是FAT表项等)。目录项中包含了文件的元数据(如文件大小、权限、物理位置等)。 3. **权限检查**:操作系统检查当前用户是否有打开该文件的权限(读、写等)。 4. **将文件控制块调入内存**:将找到的目录项(即文件控制块FCB)复制到内存中(因为FCB通常存储在磁盘上)。 5. **更新打开文件表**: - 系统维护一个全局的打开文件表(整个系统一张表,或者每个进程一张表,但通常有一个系统级的打开文件表)。如果该文件已经被其他进程打开,则可能直接引用已有的表项(比如增加打开计数)。 - 在打开文件表中添加一个表项,该表项指向内存中的FCB(或inode等结构)。 6. **返回文件描述符**:操作系统将打开文件表项的索引(即文件描述符)返回给用户程序。此后,用户程序使用该文件描述符进行后续的文件操作(如read、write等)。 另外,在引用[2]中提到,read系统调用时不需要再提供路径和文件名,而是使用文件描述符。因此,打开文件的主要目的之一就是建立用户程序与文件之间的连接,避免每次操作都进行路径查找。 注意事项: - 打开文件表通常分为进程级的打开文件表和系统级的打开文件表。进程级的打开文件表中每个表项可能指向系统级打开文件表的一个表项,而系统级打开文件表则指向内存中的文件控制块(如inode)。这样设计可以支持多个进程共享同一个文件。 - 在打开文件时,可能会涉及到文件锁(如果其他进程已经以独占方式打开)或者共享权限的检查。 因此,我们可以将上述流程整理为以下步骤: ### 操作系统打开文件的流程 1. **路径解析** 操作系统根据用户提供的路径字符串,从根目录或当前工作目录开始逐级解析,直到找到目标文件所在的目录。 [^1][^2] 2. **查找目录项** 在目录文件中查找目标文件的文件名,获取对应的目录项(即文件控制块FCB,包含文件元数据和磁盘位置)。 [^1][^2] 3. **权限验证** 检查用户是否有权限以指定方式(读、写等)打开该文件。 [^1] 4. **载入文件控制块** 将目录项(FCB)从磁盘复制到内存中(如果尚未在内存中)。 [^2] 5. **更新打开文件表** - 在系统级打开文件表中查找或创建表项,指向内存中的FCB,并更新打开计数。 - 在进程的打开文件表中添加一个表项,指向系统级打开文件表的对应表项。 [^1][^2] 6. **返回文件描述符** 将进程打开文件表项的索引(即文件描述符)返回给用户程序,作为后续文件操作的句柄。 [^2] > 注意:文件描述符(fd)是一个非负整数,在Unix/Linux系统中,0、1、2分别代表标准输入、标准输出、标准错误。 §§相关问题§§ 1. 打开文件时如何解析绝对路径和相对路径? 2. 多个进程同时打开同一文件时,打开文件表如何管理? 3. 打开文件后,操作系统如何提高后续文件读写的效率? [^1]: 操作系统在open系统调用中根据路径查找目录项并验证权限 [^2]: 文件控制块被载入内存并创建打开文件表项,返回文件描述符 </think>### 操作系统打开文件的流程 操作系统通过 `open` 系统调用打开文件的流程如下(以 Linux 为例): 1. **路径解析与权限检查** - 用户程序调用 `open("/path/to/file", flags)` 后,操作系统解析文件路径,从根目录或当前目录逐级查找子目录[^1]。 - 在目录项中定位目标文件名,并检查用户权限(如读/写权限)[^1]。 2. **加载文件控制块(FCB)** - 从磁盘读取文件的 **文件控制块(FCB)** 到内存。FCB 包含文件元数据(大小、权限、物理存储位置等),但**不会加载文件内容本身**[^2]。 3. **更新打开文件表** - 在内存的**系统级打开文件表**中添加表项,指向 FCB 的内存副本[^1][^2]。 - 在**进程级打开文件表**中创建条目,映射到系统级表项。 4. **返回文件描述符** - 操作系统将进程级表项的索引作为**文件描述符(fd)** 返回给用户程序(如 `fd=3`)[^2]。 5. **后续操作(如 `read`)** - 用户通过 `read(fd, ...)` 操作文件时,仅需提供文件描述符: - 系统通过 `fd` 定位 FCB - 若文件内容未加载,触发缺页中断调入内存 - 从磁盘读取数据到用户缓冲区[^2]。 ```c // 用户程序示例 int fd = open("data.txt", O_RDONLY); // 步骤1-4 char buffer[100]; read(fd, buffer, 100); // 步骤5 close(fd); // 关闭文件释放表项 ``` ### 关键机制说明 | 组件 | 作用 | |---------------------|----------------------------------------------------------------------| | **文件控制块 (FCB)** | 存储磁盘文件的元数据(如 inode) | | **系统级打开文件表** | 全局表,维护所有打开文件的 FCB 内存副本 | | **进程级打开文件表** | 进程私有,通过 fd 映射到系统级表项 | | **文件描述符 (fd)** | 整数句柄,屏蔽底层路径解析(后续操作只需 fd)[^2] | > 💡 **设计意义**: > 1. **减少磁盘访问**:目录项和 FCB 缓存避免重复路径解析[^1] > 2. **权限隔离**:每次 `open` 独立检查权限 > 3. **资源管理**:`close()` 释放表项,引用计数归零时清除 FCB[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值