LINUX下進程打開的文件怎麼和底層磁盤關聯的?

LINUX下進程打開的文件怎麼和底層磁盤關聯的?

一直有個疑惑,文件是放在磁盤中的,但是操作文件卻是在內存中,這兩者是怎麼關聯的呢,雖然至今還沒有找到更詳細的答案,但是對linux底層數據結構進行梳理後,發現了其中的一些線索,與大家分享。

一、相關的linux數據結構

1. fd

在編程語言裏面,打開一個文件一般的操作需要建立一個文件描述符fd:

int fd = open(...);

fd是一個int型,其實是一個數組的下標,前三個0,1,2被輸入,輸出,錯誤佔用了

新建新的fd的時候,首先分配一個file對象,然後放到數組裏面,返回這個數組的下標,就是fd了

2. file

struct file{
    file_operations *fop;
    path *f_path;
    loff_t f_pos;
}

file結構中有一個f_path指針,指向path結構,其中f_pos還保存了文件的位置

3. path

struct path{
    dentry *dentry
    ...
}

path連接着一個dentry結構

4. dentry

struct dentry{
    inode *d_inode;
    ...
}

dentry結構連接着inode結構

5. inode

struct inode{
    address_space *i_mapping;
    address_space *i_data;
}

inode結構連接着address_space結構

6. address_space

struct address_space{
    radix_tree_root page_tree;
}

page_tree是一個基樹,節點中存放着page節點,page就是系統中的頁,所以address_space連接着page結構。

7. page

struct page{
    void *private;
}

private指向buffer_head

8. buffer_head

struct buffer_head{
    sector_t block_nr; // 邏輯塊號
    block_device *b_bdev; // 磁盤設備號
}

block_nr存放的數據的邏輯塊號,通過邏輯塊號,就可以和磁盤關聯起來了。

9. bio

struct bio{
    bio_vec        *bi_io_vec; // 鏈表
    sector_t    bi_sector; // 磁盤上相關的扇區
    struct block_device *bi_bdev; // 相關的塊設備
}

一個bio連接着n個bio_vec結構,用於表示page中內容的位置

10. bio_vec

struct bio_vec{
    page *bv_page; // 指向包含的頁
    int bv_len; // 長度
    int bv_offset; //頁中的偏移
}

11. task_struct

struct task_struct{
    struct bio *bio_list; // 指向bio的鏈表頭
}

二、讀寫操作

file中的file_operations是一個操作結構,裏面包含對文件的read,write等操作,所有對文件的操作,都會轉移到該文件file->f_op->read/write等操作。

三、內存到磁盤的路徑

linux2.6之後,使用了bio的結構來描述IO操作,由於效率的原因,所以buffer_head使用場景變少了,用bio結構描述一個讀/寫操作,然後使用IO調度算法進行調度。

通過以上結構體,可以得出一條線索:

fd->file->path->dentry->inode->address_space->page->buffer_head->磁盤塊號

或者

task_struct->bio->磁盤塊號

磁盤的IO操作都是異步的,會通過特定的條件觸發把內容從內存刷新到磁盤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章