linux檔案系統之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