在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的文件系统上创建文件的流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查电脑使用记录的软件是什么软件(查询电脑
- 下一篇: 四绝日是什么意思(四绝日指一年四季的末端