在diy的文件系统上创建文件的流程
【0】README
0.1) source code are from orange’s implemention of a os , and for complete code , please visit https://github.com/pacosonTang/Orange-s-OS/tree/master/fs_create_file_p366 ;
0.2)本文总结的内容是干货, 而且 创建文件所涉及的代码调用太复杂,整理了出来,生怕它含在嘴里化了,所以发表上来;
0.3) 本创建文件的代码or steps 仅仅针对 orange‘s diy 的文件系统,如何建立diy的文件系统, refering to http://blog.csdn.net/pacosonswjtu/article/details/48919489
【1】引入文件描述符(file descriptor)
1)每当一个进程打开一个文件——无论是打开一个已存在 的还是创建一个新的,该进程的进程表的filp 数组中就会分配一个位置, 用于存放 打开文件的fd指针;
2)文件描述符fd 的真正含义:它其实是一个数组的下标,循着这个下标,系统可以找到用以描述文件的inode 数据结构;
【2】 open()函数——创建一个文件
2.1)我们先看看创建文件的代码大致调用流程:
2.2) 创建文件的主要过程,其中最核心的函数是 do_open()函数调用的 create_file() 函数,我们看一下它们的调用过程;
函数性能Analysis)
- A0)int do_open():打开一个文件,返回文件描述符,文件名由 用户进程(如TestA)通过消息传递过来;
- A1)int search_file(char *path):查找该路径path 所标识的文件,并返回其对应的inode编号;
- A2)struct inode * create_file(char * path, int flags):转换带路径的文件名path 为纯文件名,并以纯文件名创建文件,并返回该文件的inode 指针(数据结构);
- A2.1)int strip_path(char * filename, const char * pathname, struct inode ppinode):**返回带路径的文件名pathname 对应的纯文件名filename, 以及该文件所在文件夹的inode编号;
- A2.2)int alloc_imap_bit(int dev):在dev标识分区的inode-map 中为 即将被分配的inode 置为使用中(bit位=1), 返回该inode 编号;
- A2.3)int alloc_smap_bit(int dev, int nr_sects_to_alloc):在dev标识分区的sector-map 中为 即将被分配的sector 置为使用中(bit位=1),返回该sector编号;
- A2.4)struct inode * new_inode(int dev, int inode_nr, int start_sect):在dev标识分区中找到编号为inode_nr 的inode数据结构,并吧start_sect 写入该inode数据结构中, 最后返回找出的inode数据结构 (指针);(因为,每个分区都有一个文件系统,他们所有的扇区都是以各自分区的第一个扇区为起始扇区,都是从0开始起算,故需要传入dev设备号以示选中具体的分区)
- A2.4.1)struct inode * get_inode(int dev, int num):参见 A4);
- A2.4.2)void sync_inode(struct inode * p):一旦内存中的inode 数据结构发生改变, 则立即写入磁盘(同步更新到磁盘)。这一项工作就是通过 sync_inode() 将inode 数据结构 p 写入 硬盘的相应扇区来实现的;
- A2.5)void new_dir_entry(struct inode *dir_inode,int inode_nr,char *filename):创建以inode_nr、filename 为根目录文件项的inode数据结构、文件名称, 最后还要把 根目录inode的数据结构 dir_inode 同步更新到硬盘上;
- A3)int strip_path(char * filename, const char * pathname, struct inode ppinode):**返回带路径的文件名pathname 对应的纯文件名filename, 以及该文件所在文件夹的inode编号;
- A4)struct inode * get_inode(int dev, int num):从设备号dev 所标识的硬盘分区中,查找出编号为num 的inode数据结构(指针);
【3】向 init_fs()添加新内容
函数性能Analysis):
- A0)init_fs():初始化文件系统;
- A1)void read_super_block(int dev):将dev标识的硬盘分区中的超级块读入内存缓冲区fsbuf , 然后再copy到 super_block 数组;
- A2)struct super_block * get_super_block(int dev):返回dev标识的硬盘分区中的超级块指针(数据结构);
【4】还有两个读写数据的宏(WR_SECT + RD_SECT),你可能需要了解:
Analysis):
- A1)WR_SECT(ROOT_DEV, sb.n_1st_sect) :调用 WR_SECT宏,传入参数并接着调用 rw_sector(int io_type, int dev, u64 pos, int bytes, int proc_nr,
void* buf) 后,该宏表达的意思是(是文件系统进程 fs 向 驱动程序hd 发送消息,消息类型是读取扇区内容到 内容缓冲区fsbuf 中):从硬盘or驱动器(ROOT_DEV的主设备号对应的驱动器) 的 分区中(ROOT_DEV的次设备号对应的分区)的第 sb.n_1st_sect扇区中读取 SECTOR_SIZE (==一个扇区的字节大小)字节到 内存缓冲区fsbuf中; - A2)#define MAJOR(x) ((x >> MAJOR_SHIFT) & 0xFF) 和 #define MINOR(x) (x & 0xFF) : 分别表示计算 x 的主设备号 和 次设备号, 前者选择驱动程序(如选择硬盘驱动还是软盘驱动), 后者表示选择某个硬盘(软盘)的分区;
Conclusion):
- C1) 你可以看到,创建一个文件, 首先是用户进程如Test_A 发送消息DEV_OPEN, 交给进程调度程序send_recv 处理; 然后进程调度程序调用 文件系统进程task_fs; 然后文件系统进程task_fs在读写硬盘数据的时候,该读写工作 是 文件系统进程task_fs 通过进程调度程序send_recv 调用 硬盘驱动程序task_hd 来实现的;然后 硬盘驱动程序task_hd 读写完数据后,返回相应消息, 以表示工作完成;(读写文件类似)
- C2) 从上述创建文件的过程叙述可知, 该过程涉及到 进程间通信IPC, 进程调度;
版权声明:本文为博主原创文章,未经博主允许不得转载。
在diy的文件系统上创建文件的流程的更多相关文章
- diy文件系统上创建文件的流程
[0]README 0.1) source code are from orange's implemention of a os , and for complete code , please v ...
- 错误提示:通过 Web 服务器的身份验证的用户无权打开文件系统上的文件
//win7中iis配置好了可是网页打不开,为什么.? //错误提示:通过 Web 服务器的身份验证的用户无权打开文件系统上的文件 //解决办法1.右键单击你的网站根目录文件夹,如wwwroot文件夹 ...
- python在windows系统上创建文件
正确方法为:open("test1.txt",'wb')或open("test1.txt",'w') 以下是网上的方法创建遇到的问题 使用Python2.7在w ...
- Android中在sdcard上创建文件夹
//在SD卡上创建一个文件夹 public void createSDCardDir(){ if(Environment.MEDIA_MOUNTED.equals(Environment ...
- 解决从linux本地文件系统上传文件到HDFS时的权限问题
当使用 hadoop fs -put localfile /user/xxx 时提示: put: Permission denied: user=root, access=WRITE, inode=& ...
- HDFS上创建文件、写入内容
1.创建文件 hdfs dfs -touchz /aaa/aa.txt 2.写入内容 echo "<Text to append>" | hdfs dfs -appen ...
- Java 在给定路径上创建文件,所在文件夹不存在时,如何正确创建。
String strPath = "E:\\a\\aa\\aaa.txt"; File file = new File(strPath); if(!file.exists())){ ...
- 关于ajax上传文件的流程 和选择图片立即显示
关键点: 1.制作一个表单..然后把上传字段附加到该表单中 2.制作一个框架..把表单的_target的属性指向该框架. 3.提交表单.. jQuery.extend({ createUploadIf ...
- 在CentOS6或RHEL6恢复上ext4文件系统误删除的文件
首先说明: [root@CentOS6 ~]# rm -rf / //这条命令不可以执行 [root@CentOS6 ~]# rm -rf /* //这条命令可以执行,别去试 ext4文件系统上误删除 ...
随机推荐
- mysql中PDO参数化引号引起的Warning: PDOStatement::execute(): SQLSTATE[HY093]:报错
sql语句之前是这样写的:INSERT INTO tablename SET a = ':a',b = ':b',c = ':c',d = :d,e = :e $data = array ( [':a ...
- TDictionary字典 记录 的赋值。
type TRen = record age: Integer; //把name定义成结构的属性. private Fname: string; procedure Setname(const Val ...
- react 使用antd导航组件实现事件传递并局部刷新DOM
我们要实现一个通过点击顶部导航来查询左侧菜单的一个功能 在这个功能中,我们要应用到onClick={this.headNavMenuList.bind(this)}方法来传递点击 不同按钮来传递不同的 ...
- Web测试框架SeleniumBase
前几天逛GitHub发现一个基于Selenium和unittest单元测试框架的一个测试框架SeleniumBase. Github地址:https://github.com/seleniumbase ...
- 聊聊、Zookeeper API
今天我们来说说 Zookeeper 客户端启动,整个文章分三个部分:第一部分是 Zookeeper 原生 API 客户端,第二部分是开源客户端 ZkClient,第三部分是开源客户端 Curator. ...
- mac安装apache的mod_wsgi模块
第一次用pip安装 ,最终不能使用,原因是系统自带的apache,python和新安装的冲突, 所以需要安装时需要指定apache,python路径 所以用make makeinstall方式 参考链 ...
- sublimetext3打造pythonIDE
虽然pycharm是非常好用的pythonIDE,用来开发项目很方便,但是修改调整单个或几个小程序就显得很笨重,这时候我们可以选择使用sublime. 一般来说要开发项目我都用pycharm,开发简单 ...
- Linux装mysqli.so
php 5.2.3+mysqli 安装与常见错误 总结 php 5.2.3+mysqli 安装与常见错误 总结 记得原来在编译php的已经已经加上参数--with-mysql=/usr/local ...
- 可软件定义的存储逻辑——Efficient and agile storage management in software defined environments
note:写这个或许算是翻译,又或算是对这个论文[1]的理解,又或者仅仅是我的看法. 这篇论文和IOFlow相比較,更加注重软件定义存储的框架(利用已有的框架来创建新的 ...
- 环信ONE SDK架构介绍
环信ONE SDK架构介绍 摘要 环信即时通讯SDK自2014年6月正式公布2.0版本号至今已走过一个年头.从主要的单聊功能,到群聊功能,再到聊天室的实现.SDK无论是功能.稳定性,还是易集成性都在一 ...