当前位置: 首页 > news >正文

设备驱动与文件系统:05 文件使用磁盘的实现

从文件使用磁盘的实现逻辑分享

我们现在讲第30讲,内容是文件使用磁盘的具体实现,也就是相关代码是如何编写的。上一节我们探讨了如何从字符流位置算出盘块号,这是文件操作磁盘的核心。而这节课,我们将深入研究实现这一核心功能的实际代码。

一、文件读写磁盘的接口与流程在这里插入图片描述

通过文件来使用磁盘,最常用的操作就是读写,以write操作为例。我们知道,write的格式需要传递三个参数:第一个是文件描述符fd,用于指定操作的文件;第二个是内存缓冲区,用于存储要写入文件的数据或读取文件数据的存储区域;第三个是读写字符的个数。从这个接口可以看出,用户在使用时接触到的是字符流相关的概念,并没有直接涉及盘块号,但在系统内部,必然会将这些字符流信息换算成盘块号,因为磁盘实际读写操作关注的是扇区,需要根据盘块号进一步算出扇区。
在这里插入图片描述

在实际操作中,write到了内核中就变成sys_write,这是系统调用的基本知识。sys_write首先要获取inodeinode本质上就是FCB(文件控制块),获取它就相当于掌握了文件的关键信息。接下来,要根据FCB以及读写的字符流位置,算出对应的盘块号,得到盘块号后,就可以进行读写操作了。

进一步跟踪代码,file_write函数在这个过程中发挥重要作用,它需要接收inodefile、内存缓冲区以及读写长度等参数。这里需要注意的是,字符流中的读写位置信息其实存储在file中。

二、字符流读写位置的确定在这里插入图片描述

file中有一个f_pos指针,它就是我们所说的读写指针。如果大家编写过较多的C程序并操作过文件,就会对文件读写指针比较熟悉,常用的fseek函数就是用来调整这个指针的。在文件刚打开时,读写指针指向第0个位置,随着不断读写,指针会向后移动,这也就形成了我们所说的字符流。

如果是追加写入,pos会被设置为inode中的i_size,也就是文件的大小,这样就相当于把写入位置放在了文件末尾;如果不是追加写入,pos则会取出上一次读写的位置,继续往后读写。这样,我们就得到了字符流中的读写位置,再结合count参数,就能确定具体的读写范围。

三、根据读写位置计算盘块号在这里插入图片描述

得到字符流中的读写位置后,接下来关键的一步就是根据读写位置找到盘块号,这是文件抽象的核心,inode在其中发挥着重要作用。计算盘块号时,需要用读写位置除以盘块的尺寸,得到对应的逻辑块号。

在Linux 0.11系统中,文件存储采用了直接块和索引块的方式。如果f_block小于7,说明是直接块,此时可以直接从inodei_block中获取对应的盘块号,因为要写入新内容,所以还需要先申请一个空闲块,并将其记录在i_block;如果f_block大于等于7且小于512,则进入一阶索引阶段,需要先将一阶索引块读进来,再从索引块中找到对应的盘块号;如果涉及更复杂的情况,还可能会有二阶索引等。

四、向磁盘发出读写请求

一旦确定了盘块号,就可以通过bread函数(如果是写操作则类似流程)进一步处理。bread函数会根据盘块号算出扇区号(由于一个盘块对应两个扇区,所以盘块号左移一位得到扇区号),然后结合内存缓冲区信息,形成一个请求,并将其放入电梯队列。放入电梯队列后,当前操作会阻塞等待,直到磁盘中断发生,从中取出请求,算出CHS(柱面号、磁头号、扇区号),再通过out指令发送到磁盘控制器,从而完成磁盘的读写操作。

在读写完成后,pos指针需要根据实际读写的字符数进行增加,以保证下次读写能够从正确的位置开始,这部分操作和计算盘块号的过程共同构成了文件读写的核心逻辑。

五、inode的双重角色与文件视图在这里插入图片描述

讲到这里,关于从文件到盘块的映射故事基本讲完了。但需要强调的是,inode除了作为从文件对应到盘块号的映射表之外,它还是文件抽象的关键。我们之前讲过文件视图,在系统中,不仅普通的数据文件是文件,设备文件同样也是文件。对于普通文件,inode中的映射表用于实现字符流位置到盘块号的映射;而对于设备文件,inode则用来存放主设备号、次设备号等信息
在这里插入图片描述

通过inode的这种设计,系统形成了统一的文件视图。无论是读写普通磁盘文件,还是操作其他设备文件,用户看到的都是一个连续的字符流,而底层复杂的映射和处理过程都由操作系统完成。这也引出了我们下一节要讲的内容——打开文件,其实质就是从文件名到inode的映射,这是整个文件系统操作的重要环节。

六、课程总结与实验任务

我们最终使用磁盘的基本流程是通过open函数获取文件描述符fd,然后使用readwrite等函数基于fd进行操作。今天我们详细讲解了在有了fd之后,如何找到读写位置,并根据inode找到盘块号来实现磁盘读写,整个过程涵盖了从文件名到inode,再到盘块号,最后到磁盘实际操作的完整链条。
在这里插入图片描述
在这里插入图片描述

最后,给大家布置一个重要的实验任务,这也是操作系统课程八个实验中的最后一个。在Linux 0.11系统中原本没有proc文件,我们需要通过实验创建类似功能,以深入体会文件视图的概念。proc文件通常用于展示进程信息,这些信息存储在内核的task_struct全局数组中。我们要做的就是将这些信息按照文件的方式提取并返回给用户,具体实现过程是当系统发现inode表示的是proc设备时,调用proc_read函数,从task_struct中取出信息存入buffer,再传递给用户端内存,同时不要忘记修改pos指针,以保证数据以统一的字符流形式呈现。再次强调,操作系统的学习离不开实践,只有动手编写代码、完成实验,才能真正掌握操作系统的原理和实现方法

http://www.xdnf.cn/news/939331.html

相关文章:

  • 2025-05-01-决策树算法及应用
  • Kotlin REPL初探
  • 单片机 传感器知识讲解 (一)红外避障模块,声控模块,人体红外模块
  • 9.贪心算法(随想录)
  • 电子学会Python考前英语单词
  • art-template模板引擎
  • SpringCloudAlibaba和SpringBoot版本问题
  • 【差分】详解二维前缀和和差分问题
  • [mdm9607] Qualcomm mdm9607新增nand flash支持修改方法
  • Docker部署MySQL
  • Elasticsearch 常用操作命令整合 (cURL 版本)
  • C++.OpenGL (17/64)模型(Model)
  • 堆排序code
  • 第三章 AI应用开发
  • 探秘Transformer系列之(36)--- 大模型量化方案
  • OpenEuler 系统中 WordPress 部署深度指南
  • Pandas中常用函数
  • 2025年- H78-Lc186--763.划分字符串区间(贪心)--Java版
  • 分类数据集 - 场景分类数据集下载
  • Langchian - 实现文本分类实际应用
  • 【Java学习笔记】System类
  • vite ts 配置使用@ 允许js
  • 基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
  • 「Java基本语法」标识符、关键字与常量
  • Java编程之组合模式
  • Python项目的构建和部署方案推荐
  • remote display server is not supported (e.g. Wayland)
  • CentOS-7 通过 NFS 实现服务器之间的文件共享
  • 深入了解NIO的优化实现原理
  • 二叉树-226.翻转链表-力扣(LeetCode)