diy文件系统上创建文件的流程

【0】README

0.1) source code are from orange’s implemention of a os , and for complete code , please visithttps://github.com/pacosonTang/Orange-s-OS/tree/master/fs_create_file_p366 ;
0.2)本文总结的内容是干货, 而且 创建文件所涉及的代码调用太复杂,整理了出来,生怕它含在嘴里化了,所以发表上来;
0.3) 本创建文件的代码or steps 仅仅针对 orange‘s diy 的文件系统,如何建立diy的文件系统, refering tohttp://blog.youkuaiyun.com/pacosonswjtu/article/details/48919489


黄色别墅http://www.326dy.com/

【1】引入文件描述符(file descriptor)

这里写图片描述
这里写图片描述
1)每当一个进程打开一个文件——无论是打开一个已存在 的还是创建一个新的,该进程的进程表的filp 数组中就会分配一个位置, 用于存放 打开文件的fd指针;
2)文件描述符fd 的真正含义:它其实是一个数组的下标,循着这个下标,系统可以找到用以描述文件的inode 数据结构;


【2】 open()函数——创建一个文件

2.1) 我们先看看创建文件的代码大致调用流程:
这里写图片描述

2.2) 创建文件的主要过程,其中最核心的函数是 do_open()函数调用的 create_file() 函数,我们看一下它们的调用过程;
这里写图片描述
函数性能Analysis)

函数性能Analysis):

326电影网http://www.326dy.com/
  • 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 的主设备号 和 次设备号, 前者选择驱动程序(如选择硬盘驱动还是软盘驱动), 后者表示选择某个硬盘(软盘)的分区;

    性喜剧http://www.326ys.com/

Conclusion):

  • C1) 你可以看到,创建一个文件, 首先是用户进程如Test_A 发送消息DEV_OPEN, 交给进程调度程序send_recv 处理; 然后进程调度程序调用 文件系统进程task_fs; 然后文件系统进程task_fs在读写硬盘数据的时候,该读写工作 是 文件系统进程task_fs 通过进程调度程序send_recv 调用 硬盘驱动程序task_hd 来实现的;然后 硬盘驱动程序task_hd 读写完数据后,返回相应消息, 以表示工作完成;(读写文件类似)
  • C2) 从上述创建文件的过程叙述可知, 该过程涉及到 进程间通信IPC, 进程调度;
  • 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.5)void new_dir_entry(struct inode dir_inode,int inode_nr,char filename):创建以inode_nr、filename 为根目录文件项的inode数据结构、文件名称, 最后还要把 根目录inode的数据结构 dir_inode 同步更新到硬盘上;
      326影视http://www.326ys.com/
  • 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()添加新内容

    这里写图片描述

在NTFS文件系统中,每一个文件或目录都拥有一个MFT记录,MFT记录中记录了文件或目录的基本信息,对于普通文件来说,一般拥有文件序号,文件名,创建时间,文件大小,文件属性,文件数据地址索引等基本文件信息,而一个目录除了拥有基本文件信息,还拥有其目录下的文件索引项信息,文件与其父目录之间通过该文件的MFT记录中的父目录信息和目录中的索引项来建立隶属关系,这两种信息唯一地确定了文件与父目录之间的对应关系,由此可知,要在一个指定目录下生成一个文件,除了要创建目标文件本身的MFT记录,还需在其父目录的MFT记录或者其索引分配中建立目标文件的索引。在NTFS系统中,文件索引是一个比较复杂的内容,文件的索引采用了树型结构,这给NTFS系统带来了查找文件速度快的优点,但却给当索引结点增加或减少时,如何维护树的平衡带来了难题。在NTFS系统中,小目录的索引直接存放在目录本身MFT记录的90H属性中,而大目录的索引则需另外开辟新的索引分配区来存放相关的索引。原程序中只考虑了小目录的情况,即将文件的索引直接存放在90H属性中,并不考虑大目录的索引情况。除此之外,NTFS系统对于每一个文件操作都会写入日志文件中,以便一致性检查,但由于这方面的内容尚未研究清楚,本程序中也未涉及这方面的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值