1. 程式人生 > >linux檔案系統之mount流程分析

linux檔案系統之mount流程分析

本質上,Ext3 mount的過程實際上是inode被替代的過程。例如,/dev/sdb塊裝置被mount到/mnt/alan目錄。那麼mount這個過程所需要解決的問題就是將/mnt/alan的dentry目錄項所指向的inode遮蔽掉,然後重新定位到/dev/sdb所表示的inode索引節點。在沒有分析閱讀linux vfs mount程式碼的時候,我的想法是修改dentry所指向的inode索引節點,以此實現mount檔案系統的訪問。經過分析,在實際的vfs mount實現過程中,還是和我原始的想法略有差別,但是,基本目標還是相同的。

Linux VFS的mount過程基本原理如下圖所示:

當用戶輸入”mount /dev/sdb /mnt/alan”命令後,Linux會解析/mnt/alan字串,並且從Dentry Hash表中獲取相關的dentry目錄項,然後將該目錄項標識成DCACHE_MOUNTED。一旦該dentry被標識成DCACHE_MOUNTED,也就意味著在訪問路徑上對其進行了遮蔽。

在mount /dev/sdb裝置上的ext3檔案系統時,核心會建立一個該檔案系統的superblock物件,並且從/dev/sdb裝置上讀取所有的superblock資訊,初始化該記憶體物件。Linux核心維護了一個全域性superblock物件連結串列。s_root是superblock物件所維護的dentry目錄項,該目錄項是該檔案系統的根目錄。即新mount的檔案系統內容都需要通過該根目錄進行訪問。在mount的過程中,VFS會建立一個非常重要的vfsmount物件,該物件維護了檔案系統mount的所有資訊。Vfsmount物件通過HASH表進行維護,通過path地址計算HASH值,在這裡vfsmount的HASH值通過“/mnt/alan”路徑字串進行計算得到。Vfsmount中的mnt_root指向superblock物件的s_root根目錄項。因此,通過/mnt/alan地址可以檢索VFSMOUNT Hash Table得到被mount的vfsmount物件,進而得到mnt_root根目錄項。


例如,/dev/sdb被mount之後,使用者想要訪問該裝置上的一個檔案ab.c,假設該檔案的地址為:/mnt/alan/ab.c。在開啟該檔案的時候,首先需要進行path解析。在解析到/mnt/alan的時候,得到/mnt/alan的dentry目錄項,並且發現該目錄項已經被標識為DCACHE_MOUNTED。之後,會採用/mnt/alan計算HASH值去檢索VFSMOUNT Hash Table,得到對應的vfsmount物件,然後採用vfsmount指向的mnt_root目錄項替代/mnt/alan原來的dentry,從而實現了dentry和inode的重定向。在新的dentry的基礎上,解析程式繼續執行,最終得到表示ab.c檔案的inode物件。


關鍵資料結構說明
Linux VFS mount所涉及的關鍵資料結構分析如下。

Vfsmount資料結構
Vfsmount資料結構是vfs mount最為重要的資料結構,其維護了一個mount點的所有資訊。該資料結構描述如下:
struct vfsmount {struct list_head mnt_hash;/* 連線到VFSMOUNT Hash Table */struct vfsmount *mnt_parent;/* 指向mount樹中的父節點 */struct dentry *mnt_mountpoint;/* 指向mount點的目錄項 */struct dentry *mnt_root;/* 被mount的檔案系統根目錄項 */struct super_block *mnt_sb;/* 指向被mount的檔案系統superblock */#ifdef CONFIG_SMP  
    struct mnt_pcp __percpu *mnt_pcp;atomic_t mnt_longterm;/* how many of the refs are longterm */#elseint mnt_count;int mnt_writers;#endifstruct list_head mnt_mounts;/* 下級(child)vfsmount物件連結串列 */struct list_head mnt_child;/* 鏈入上級vfsmount物件的連結串列點 */int mnt_flags;/* 4 bytes hole on 64bits arches without fsnotify */#ifdef CONFIG_FSNOTIFY  
    __u32 mnt_fsnotify_mask;struct hlist_head mnt_fsnotify_marks;#endifconstchar*mnt_devname;/* 檔案系統所在的裝置名字,例如/dev/sdb */struct list_head mnt_list;struct list_head mnt_expire;/* link in fs-specific expiry list */struct list_head mnt_share;/* circular list of shared mounts */struct list_head mnt_slave_list;/* list of slave mounts */struct list_head mnt_slave;/* slave list entry */struct vfsmount *mnt_master;/* slave is on master->mnt_slave_list */struct mnt_namespace *mnt_ns;/* containing namespace */int mnt_id;/* mount identifier */int mnt_group_id;/* peer group identifier */int mnt_expiry_mark;/* true if marked for expiry */int mnt_pinned;int mnt_ghosts;};

在Linux核心中不僅存在VFSMOUNT的Hash Table,而且還維護了一棵Mount物件樹,通過該mount樹,我們可以瞭解到各個檔案系統之間的關係。該mount樹描述如下:



上圖所示為三層mount檔案系統樹。第一層為系統根目錄“/”;第二層有兩個mount點,一個為/mnt/a,另一個是/mnt/b;第三層在/mnt/a的基礎上又建立了兩個mount點,分別為/mnt/a/c和/mnt/a/d。通過mount樹,可以對整個系統的mount結構一目瞭然。

Superblock資料結構
每個檔案系統都會擁有一個superblock物件對其基本資訊進行描述。對於像ext3之類的檔案系統而言,在磁碟上會持久化儲存一份superblock元資料資訊,記憶體的superblock物件由磁碟上的資訊初始化。對於像block device 之類的“偽檔案系統”而言,在mount的時候也會建立superblock物件,只不過很多資訊都是臨時生成的,沒有持久化資訊。Vfs superblock資料結構定義如下:
struct super_block {struct list_head    s_list;/* 鏈入全域性連結串列的物件*/dev_t           s_dev;/* search index; _not_ kdev_t */unsignedchar       s_dirt;unsignedchar       s_blocksize_bits;unsignedlong       s_blocksize;loff_t          s_maxbytes;/* Max file size */struct file_system_type *s_type;conststruct super_operations   *s_op;/* superblock操作函式集 */conststruct dquot_operations   *dq_op;conststruct quotactl_ops   *s_qcop;conststruct export_operations *s_export_op;unsignedlong       s_flags;unsignedlong       s_magic;struct dentry       *s_root;/* 檔案系統根目錄項 */struct rw_semaphore s_umount;struct mutex        s_lock;int         s_count;atomic_t        s_active;#ifdef CONFIG_SECURITY  
    void*s_security;#endifconststruct xattr_handler **s_xattr;struct list_head    s_inodes;/* all inodes */struct hlist_bl_head    s_anon;/* anonymous dentries for (nfs) exporting */#ifdef CONFIG_SMP  
    struct list_head __percpu *s_files;#elsestruct list_head    s_files;#endif/* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */struct list_head    s_dentry_lru;/* unused dentry lru */int         s_nr_dentry_unused;/* # of dentry on lru *//* s_inode_lru_lock protects s_inode_lru and s_nr_inodes_unused */spinlock_t      s_inode_lru_lock ____cacheline_aligned_in_smp;struct list_head    s_inode_lru;/* unused inode lru */int         s_nr_inodes_unused;/* # of inodes on lru */struct block_device *s_bdev;struct backing_dev_info *s_bdi;struct mtd_info     *s_mtd;struct list_head    s_instances;struct quota_info   s_dquot;/* Diskquota specific options */int         s_frozen;wait_queue_head_t   s_wait_unfrozen;char s_id[32];/* Informational name */  
    u8 s_uuid[16];/* UUID */void*s_fs_info;/* Filesystem private info */fmode_t         s_mode;/* Granularity of c/m/atime in ns.  
       Cannot be worse than a second */  
    u32        s_time_gran;/*  
     * The next field is for VFS *only*. No filesystems have any business  
     * even looking at it. You had been warned.  
     */struct mutex s_vfs_rename_mutex;/* Kludge *//*  
     * Filesystem subtype.  If non-empty the filesystem type field  
     * in /proc/mounts will be "type.subtype"  
     */char*s_subtype;/*  
     * Saved mount options for lazy filesystems using  
     * generic_show_options()  
     */char __rcu *s_options;conststruct dentry_operations *s_d_op;/* default d_op for dentries *//*  
     * Saved pool identifier for cleancache (-1 means none)  
     */int cleancache_poolid;struct shrinker s_shrink;/* per-sb shrinker handle */};

程式碼流程分析
Linux中實現mount操作需要一定的程式碼量,下面對Linux VFS Mount程式碼進行分析說明,整個分析過程按照mount操作函式呼叫流程進行。程式碼分析基於Linux-3.2版本。

當用戶在使用者層執行mount命令時,會執行系統呼叫從使用者態陷入linux核心,執行如下函式(namespace.c):
SYSCALL_DEFINE5(mount,char __user *, dev_name,char __user *, dir_name,char __user *, type,unsignedlong, flags,void __user *, data){int ret;char*kernel_type;char*kernel_dir;char*kernel_dev;unsignedlong data_page;/* 獲取mount型別 */  
    ret = copy_mount_string(type,&kernel_type);if(ret <0)goto out_type;/* 獲取mount點目錄字串 */  
    kernel_dir = getname(dir_name);if(IS_ERR(kernel_dir)){  
        ret = PTR_ERR(kernel_dir);goto out_dir;}/* 獲取裝置名稱字串 */  
    ret = copy_mount_string(dev_name,&kernel_dev);if(ret <0)goto out_dev;/* 獲取其它選項 */  
    ret = copy_mount_options(data,&data_page);if(ret <0)goto out_data;/* 主要函式,執行掛載檔案系統的具體操作 */  
    ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,(void*) data_page);  
 
    free_page(data_page);  
out_data:  
    kfree(kernel_dev);  
out_dev:  
    putname(kernel_dir);  
out_dir:  
    kfree(kernel_type);  
out_type:return ret;}

do_mount()函式是mount操作過程中的核心函式,在該函式中,通過mount的目錄字串找到對應的dentry目錄項,然後通過do_new_mount()函式完成具體的mount操作。do_mount()函式分析如下:
long do_mount(char*dev_name,char*dir_name,char*type_page,unsigned
            
           

相關推薦

linux檔案系統mount流程分析

本質上,Ext3 mount的過程實際上是inode被替代的過程。例如,/dev/sdb塊裝置被mount到/mnt/alan目錄。那麼mount這個過程所需要解決的問題就是將/mnt/alan的dentry目錄項所指向的inode遮蔽掉,然後重新定位到/dev/sdb所

linux 檔案系統superblock

為了實際測試這個pagecache和對裸盤操作的區別,我一不小心敲錯命令,將一個磁碟的super_block給抹掉了,全是0, dd if =/dev/zero of=/dev/sda2 bs=4096 count=1 seek=2234789 2234789是我的某個測試檔案的

Linux檔案系統許可權體系

目錄 ①檔案屬性mode 什麼是檔案的許可權: >>>Linux一切皆檔案,多個使用者登入作業系統,系統有預設檔案,root檔案,每個使用者也有自己的檔案,此時需要對檔案系統進行       

Linux檔案系統使用者與組管理

目錄 ①使用者與組管理之重要檔案 (1)/etc/passwd (2)/etc/shadow (3)/etc/login.defs (4)/etc/skel (目錄) (5)/etc/de

Linux檔案系統壓縮資料&歸檔資料(打包)

目錄 ①Linux檔案壓縮工具 工具 檔案拓展名 gzip .gz bzip2 .bz2 zip

Linux檔案系統hard link&symbol link

引自:https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/ 這個圖很清楚的表示出硬連結和軟連結的方式。 1.硬連結:

Linux檔案系統FHS

一、FSH簡介     FHS是Filesystem Hierarchy Standard的縮寫,目前絕大多數Linux版本採用這種檔案組織形式 二 、FSH下的標準目錄簡介     1./boot:引導檔案存放目錄,核心檔案(vmlinuz)、引導載入器(b

Linux檔案系統元資料

日誌檔案系統(journaling file systems)可防止系統崩潰時導致的資料不一致問題。對檔案系統元資料(metadata)的更改都被儲存在一份單獨的日誌裡,當發生系統崩潰時可以根據日誌正確地恢復資料。除此

linux檔案系統Inode

檔名 -> inode -> device block  轉自:http://www.cnblogs.com/itech/archive/2012/05/15/2502284.html 一、inode是什麼? 理解inode,要從檔案儲存說起。 檔

FAT16檔案系統目錄項分析(四)

FAT16檔案系統的FDT分析 1:FDT位置 FDT的含義為檔案目錄表,它在一個檔案系統中的具體位置是緊跟在FAT2之後。 定位過程: A:系統通過讀取該分割槽表資訊,定位到其DBR扇區 B:讀取DBR的保留扇區數(OEH –0FH). C:讀取每個FAT扇區數(16H

Linux檔案系統aufs

aufs的全稱是advanced multi-layered unification filesystem,主要功能是把多個資料夾的內容合併到一起,提供一個統一的檢視,主要用於各個Linux發行版的livecd中,以及docker裡面用來組織image。 據說由於auf

linux檔案系統i節點詳解

0塊:引導塊,每塊1024B 1塊:超級塊 2塊:i節點點陣圖 3塊:邏輯塊點陣圖 4...18:i節點區塊 19塊:資料塊,剛好和Linux檔案系統分析之二中提到的資料塊開始於第19塊吻合。 下面分析第一個i節點,它位於塊號為4的塊中,即是第五塊了。 00001000h: ED 41 00 00 80

Linux 檔案系統入門必看!

在 Linux 中,最直觀、最可見的部分就是 `檔案系統(file system)`。下面我們就來一起探討一下關於 Linux 中國的檔案系統,系統呼叫以及檔案系統實現背後的原理和思想。這些思想中有一些來源於 MULTICS,現在已經被 Windows 等其他作業系統使用。Linux 的設計理念就是 `小的就

Linux檔案系統分析二(超級塊,i節點點陣圖和邏輯塊點陣圖)

第二個扇區和第一個扇區一樣屬於引導塊,這裡就不列舉出其內容了,這裡的一塊是兩個扇區即1024B。接下來的一塊就是大名鼎鼎的超級塊了。其內容如下:00000400h: E0 01 A0 05 01 00 01 00 13 00 00 00 00 1C 08 10 ; ??..

Linux系統啟動流程

linux系統啟動流程開機自檢(bios)MBR引導GRUB菜單加載內核(kernel)init 進程初始化·由linux內核加載運行/sbin/init·是系統的第一個進程·PID永遠為1init進程的配置文件參數說明/etc/inittab配置默認運行級別/etc/sysconfig/init控制tty終

Linux系統"皮毛系列"(二) Linux檔案系統的簡介

一、Linux檔案系統 1、檔案系統簡介 Linux系統的理念是:一切都是檔案。 其實這個是Unix系統的哲學思想,而Linux是由Unix系統而來,所以也繼承了這個思想: Unix系統把一切資源都看作是檔案,包括硬體裝置。硬體所形成的檔案,通常稱為裝置檔案。這樣使用者

Android系統載入Apk檔案的時機和流程分析(1)--Android 4.4.4 r1的原始碼

Android系統在啟動時安裝應用程式的過程,這些應用程式安裝好之後,還需要有一個Home應用程式來負責把它們在桌面上展示出來,在Android系統中,這個預設的Home應用程式就是Launcher了。Android系統的Home應用程式Launcher是由Activit

Linux--根檔案系統的掛載過程分析

【轉自 http://blog.csdn.net/guopeixin/article/details/5962482】 前言: 本篇文章以S3C6410公版的Linux BSP和U-Boot來進行分析,文中所有提及的名詞和資料都是以該環境為例,所有的程式碼流程

linux檔案系統啟動流程、啟動指令碼

下面是一張Linux啟動流程圖: 在瞭解啟動流程之前,我們應該先知道系統的幾個重要指令碼和配置檔案,他們對應的路徑為: 1. /sbin/init 2. /etc/inittab 3. /etc/rc.d/rc.sysinit 4. /etc/rc.d/rcN.d //這

linux檔案系統系統分析--(十二)vfs層的三個hashtable

在vfs_caches_init中有三個重要的hashtable:mount_hashtabledentry_hashtable inode_hashtable Hashtable有什麼作用?主要的查詢的效率很高,vfs層用這三個就是為了提高查詢效率。另外一個,inode