在簡單的介紹檔案系統之前一定要先簡單的說明一下物理的儲存介質。為什麼要介紹實體儲存體介質呢?
主要是為了說明“everything is files”。好吧……既然大家知道一切皆檔案了,我們在此就不介紹實體儲存體介質了。但是還是希望大家能夠對物理的介質進行讀寫操作,真正的感受下,讀取檔案系統第一個分區的第一個扇區的感覺。這樣便於我們理解檔案系統的概念。
首先我們查看下在裝置上的/dev/block目錄,因為磁碟作為塊裝置就存在於這個檔案下。在板子上,會是MMC開頭的檔案。例如mmcblk0即為第一個分區,而此分區又分成了mmcblk0p1……。我們在讀取分區資訊的時候只需要,讀取mmcblk0的前512位元組的資料並按照十六進位的方式輸出即可。
在linux中支援這很不同格式的檔案系統,而這些檔案系統相互之間怎樣進行通訊便成了一個很大的問題,當我們需要對資料今次那個cp的時候,我們需要知道“源檔案系統”和“目的檔案系統”。這樣進行兩種檔案系統的一次拷貝過程也許消耗資源不多,但是我們如果頻繁的進行不同的檔案系統之間的資料拷貝時,就不能忽略對資源的消耗了。因此,我們必須要採取適當的措施把這種複雜的過程抽象出來形成單獨的部分,這種情況下便產生了虛擬檔案系統VFS。
VFS是什嗎?
請自行查閱。
這裡不得不提一下,FUSE。FUSE(file system in user space)提供了一種在使用者空間實現自己的檔案系統的平台。我們可以藉助這個檔案系統完成自己的檔案系統的擴充。具體內容自行查閱。此處比較出名的應用就是實現了linux對NTFS格式檔案的支援。
一點差異
2.4核心中貌似維護了一個檔案系統的目錄,而在2.6核心中本人並沒有發現。
在2.6核心中,檔案系統中,在啟動的過程中,檔案系統會對驅動進行註冊,完成註冊之後,會在後續的時間裡,完成對裝置的掃描並且根據裝置的類型進行輪詢。當輪詢的過程,發現裝置插入時就會將裝置與驅動類型進行匹配,如果能夠匹配在mount成功,否則mount失敗並報告相應的錯誤。
2118 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2119 char __user *, type, unsigned long, flags, void __user *, data)
2120 {
2121 int ret;
2122 char *kernel_type;
2123 char *kernel_dir;
2124 char *kernel_dev;
2125 unsigned long data_page;
2126
2127 ret = copy_mount_string(type, &kernel_type);
2128 if (ret < 0)
2129 goto out_type;
2130
2131 kernel_dir = getname(dir_name);
2132 if (IS_ERR(kernel_dir)) {
2133 ret = PTR_ERR(kernel_dir);
2134 goto out_dir;
2135 }
2136
2137 ret = copy_mount_string(dev_name, &kernel_dev);
2138 if (ret < 0)
2139 goto out_dev;
2140
2141 ret = copy_mount_options(data, &data_page);
2142 if (ret < 0)
2143 goto out_data;
2144
2145 ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
2146 (void *) data_page);
2147
2148 free_page(data_page);
2149 out_data:
2150 kfree(kernel_dev);
2151 out_dev:
2152 putname(kernel_dir);
2153 out_dir:
2154 kfree(kernel_type);
2155 out_type:
2156 return ret;
2157 }
這就是核心中檔案系統mount的入口宏定義函數。在此函數中的do_mount()、do_remount()、do_newmount()函數會幫你完成你想要完成的任務,你只需要坐著喝茶就好。