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文件系统上误删除 ...
随机推荐
- 【git】把本地项目和远程git仓库相连通
1. 打开在你的项目文件夹,输入下面的命令 git init 输完上面的命令,文件夹中会出现一个.git文件夹,如下图所示,其他的的文件也会出现蓝色小问号的标志 2. 添加所有文件 git add . ...
- 【Visual Studio】以管理员的身份运行软件
- token in c and cpp (C preprocessor)
C tokens are of six types, They are, keyword identifier constant string-literal punctuator preproces ...
- python 生成式和生成器
#!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/10/17 21:46 # @Author : lijunjiang # @Fi ...
- 洛谷——P1098 字符串的展开
P1098 字符串的展开 题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或者“4-8”的字串,我们就把它当作一种简写,输 ...
- Best Cow Fences
题目描述 Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field cont ...
- ES6十大特性
本文主要针对ES6做一个简要介绍. 主要译自: http://webapplog.com/ES6/comment-page-1/.也许你还不知道ES6是什么, 实际上, 它是一种新的javascri ...
- apache url rewrite问题
apache RewriteEngine Your browser sent a request that this server could not understand http://www.ra ...
- Spring中使用集成MongoDB Client启动时报错:rc: 48
一定是所在的服务器也装了MongoDB导致端口冲突,解决方法:kill掉全部MongoDB的进程. ps aux | grep mongod PID 参考: http://blog.csdn.net/ ...
- 怎么把一个整数转化为3个十六进制字节 delphi
如何把一个整数转化为3个十六进制字节 delphi比如把整数149259(都是6位数据整型数) 转换为十六进制为2470B然后再分开为三个字节02 47 0B,求实现代码示例var ID: Integ ...