掛載EXT2檔案系統

2021-06-01 23:10:39 字數 3522 閱讀 4159

檔案系統的安裝主要是通用mount命令來實現的,然後通過系統呼叫由使用者態進入到核心態,把某乙個分割槽下的檔案系統掛載到某乙個目錄下,當然掛載也可以能指定掛載的檔案系統。mount函式通過sys_mount函式來實現,其具體函式如下

asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name,

char __user *type, unsigned long flags,

void __user *data);

會使用syscall_define5巨集來實現,其巨集的定義如下

=============include/linux/syscall.h================

#define syscall_define5(name, ...) syscall_definex(5, _##name, __va_args__)

=============fs/namespace.c===================

syscall_define5(mount, char __user *, dev_name, char __user *, dir_name,

char __user *, type, unsigned long, flags, void __user *, data)

引數dev_name為待安裝裝置的路徑名;dir_name則是安裝點的路徑名;type是表示檔案系統開的字串,如ext2等。此外,flags為安裝模式。**中通過getname()和copy_mount_options()將字串形式或結構形式的引數值從使用者空間複製到系統空間。這些引數值的長度都是乙個頁面,但是getname在複製時遇到字串結尾符」\0」結束,並返回指向該字串的指標;而copy_mount_options則拷貝整個頁面,並返回頁面的起始位址。

=============fs/namespace.c===================

long do_mount(char *dev_name, char *dir_name, char *type_page,

unsigned long flags, void *data_page)

do_mount函式真正來實現檔案系統的掛載,它首先找到掛載點,然後根據使用的安裝標誌,呼叫相應的函式。如果掛載乙個新的檔案系統,使用do_new_mount函式。

第1行定義乙個路徑結構體

第4行丟棄的魔數,每個檔案系統都有乙個自己的魔數

第6-8行是一些基本的安全檢查,比如檔名不能空,檔名的指標不能為空及裝置名不能為空,memchr函式是在記憶體中找乙個字元,這裡就是判斷給memchr的第乙個引數分配空間沒有。

第10-11行先判斷data_page的指標是否為空,如果為真,對它用0進行初始化。

第14-27行把將要掛載的標示分離開來,掛載的標誌有幾種含義,

ms_rdonly 檔案唯讀標誌

ms_nosuid 禁止setuid和setgid標誌

ms_nodev 禁止訪問裝置檔案

ms_noexec 不允許程式執行

ms_synchronous 檔案和目錄上的寫操作是即時的

ms_remount 重新安裝改變了安裝標誌的檔案系統

ms_mandlock 允許強制加鎖

ms_dirsync 目錄上的寫操作是即時的

ms_noatime 不更新檔案訪問時間

ms_nodiratime 不更新目錄訪問時間

ms_bind 建立乙個」繫結安裝」。

ms_move 把乙個已它裝檔案系統移動到另乙個安裝點

ms_rec 為目錄子樹遞迴地建立」繫結安裝」

ms_verbose 在安裝出錯時產生核心訊息

第28行修改標識的值,這裡的值具體是多少,可以計算出來。

第31行通過呼叫kern_path函式來得到掛載點。使用其它的路徑查詢函式來找到相應的目錄,然後放到nameidata的結構體當中。

第34行使用security_sb_mount來進行安全性檢查。

第38行如果標誌是ms_remount,呼叫do_remount()函式來實現改變乙個原已安裝的裝置的安裝方式。例如原來是按」唯讀」方式來安裝的,而現在要改為」可寫」方式;或者原來的ms_nosuid標誌位為0,而現在要改變成1等等。

第41-42如果ms_bind標誌被指定,會在系統目錄樹的另乙個安裝點上檔案或目錄能夠可見。

第45-46行如果ms_move標誌為真,要可以改變安裝檔案系統的安裝點

第47-48行使用者安裝乙個特殊檔案系統或存放在磁碟分割槽中的普通檔案時,會使用該函式。它呼叫do_kern_mount函式,傳遞的引數為檔案系統型別、安裝標誌以及塊裝置名,do_kern_mount處理實際的安裝操作並返回乙個新安裝檔案系統描述符的位址。然後呼叫do_add_mount函式。

=============fs/namespace.c===================

static int do_new_mount(struct path *path, char *type, int flags,

int mnt_flags, char *name, void *data)

第1行定義乙個區域性變數的掛載點

第2行對type的值和指標的位址是否為空進行檢查

第6行呼叫do_kern_mount函式來返回乙個掛載點

第8行把這個掛載點新增到命名空間的mount樹中。

=============fs/super.c===================

struct vfsmount *

do_kern_mount(const char *fstype, int flags, const char *name, void *data)

第1行根據具體檔案系統的型別名在核心中找到相應的file_system_type結構。

第5行在這個函式中會呼叫具體檔案的xx_get_sb,例如ext2_get_sb。

第9行減少對檔案系統的引用

=============fs/namespace.c===================

int do_add_mount(struct vfsmount *newmnt, struct path *path,

int mnt_flags, struct list_head *fslist)

第2行獲得當前程序的寫訊號量namespace->sem。

第3行可以讓當前程序休眠,同時,另乙個程序可能在完全相同的安裝點上安裝檔案系統或者甚至更改根檔案系統。

第7行核對安裝點

第14行判斷要安裝的檔案是否為鏈結檔案,如果是,則解鎖。

第17行呼叫graft_tree()把新安裝的檔案系統物件插入到namespace鍊錶、雜湊表及父檔案系統的子鍊錶中。

第21行釋放namespace->sem讀寫訊號量並返回。

總結經過這麼幾個步驟,檔案系統已經掛載到指定的目錄下,根檔案系統的掛載和這個不太一樣一,根檔案系統比這個要複雜一點,分為兩個步驟來進行的,前面有一篇文章也給介紹了,普通檔案系統的掛載步驟,基本上就上面介紹的幾個步驟,最關鍵是vfs_kern_mount這個函式會呼叫具體的檔案的xx_get_sb到具體的檔案系統中。下面給出乙個簡單的流程圖。

ext2檔案系統

ext2磁碟結構 ext2分割槽和ext2分組的分布圖 下圖是借用其他部落格的 塊組中的每個塊包含的資訊 超級快 1個塊 描述該分割槽中的整個檔案系統的資訊,包括有多少個快組,每個快組有多少個塊,多少個索引節點等。組描述符塊 n塊 塊點陣圖 1塊 索引節點位圖 1塊 索引節點 n塊 資料塊 n塊 塊...

Ext2檔案系統

ext2檔案系統的總體布局,如下圖。1檔案系統的最小儲存單元是塊 block 塊的大小一般為512bytes,或者是它的整數倍,塊的大小是在格式化是所確定的。不能修改除非重新格式化。上圖中顯示了檔案系統的總體布局,由乙個boot block和對個block group組成,每個block group...

ext2檔案系統定址

ext2 檔案系統相關介紹 ext2檔案系統,乙個檔案除了資料需要儲存之外,一些描述資訊也需要儲存,例如檔案型別 常規 目錄 符號鏈結等 許可權,檔案大小,建立 修改 訪問時間等,也就是ls l命令看到的那些資訊,這些資訊存在inode中而不是資料塊中。但是檔名存在 首先檔名不是存在inode中的,...