linux文件系統的系統分析--(五)路徑名的查找

do_path_lookup是文件系統中最基本的函數,也是非常重要的,裏面各種情況,各種goto,總之各種坑爹。。

       沒能把所有的goto都理清,只看了標準情況下的路徑查找,但主要的關鍵點都是一樣的,弄清了關鍵點,心中對文件系統的路徑名查找就有了概念。不管絕對路徑名,相對路徑名,還是帶符號鏈接的,又有什麼質的區別呢?

       do_path_lookup分爲兩步:

       1、path_init根據絕對路徑或者相對路徑來初始化nameidata結構體;

       2、path_work-->link_path_walk


       link_path_walk纔是路徑查找操作中的核心:

       link_path_walk處理代表name的字符串,最後都要通過do_lookup函數來do it

       do_lookup:

       1、檢查具體底層文件系統是否有自己的hash方法(d_op->d_hash)

       2、用__d_lookup函數在dentry_hashtable這個hash表中查找

       3、如果在hash表中沒有找到,就要做真正的lookup:

             先根據要找的name和parent的dentry,分配一個dentry結構體

             調用具體文件系統的i_op->lookup函數,比如sysfs_lookup

             提前看一下sysfs_lookup的查找動作:

             sysfs_lookup-->sysfs_find_dirent 根據sysfs_dirent的組織關係,在鏈表中遍歷查找符合name的sysfs_dirent結構體,

             然後再創建inode,並將inode和dentry以及sysfs_dirent聯繫起來。


        實際文件系統的lookup方法是一個關鍵點,它根據父層次的dentry和要查找的name在子層次特有的方法來查找。sysfs的lookup方法

        是很簡單的,僅僅是遍歷一個鏈表,但實際上基於物理介質的fs的lookup應該是很複雜的,比如omfs就用hash來找,傳說的btrfs應該

        會用btree來查找吧。


       另外一個關鍵點就是:

       done:

                path->mnt = mnt;
                path->dentry = dentry;
                __follow_mount(path);

       

static int __follow_mount(struct path *path)
{
	int res = 0;
	while (d_mountpoint(path->dentry)) {
		struct vfsmount *mounted = lookup_mnt(path);
		if (!mounted)
			break;
		dput(path->dentry);
		if (res)
			mntput(path->mnt);
		path->mnt = mounted;
		path->dentry = dget(mounted->mnt_root);
		res = 1;
	}
	return res;
}
      這個函數和上篇do_add_mount中那個不起眼的while的作用是一樣的,做文件系統的切換操作。

      理解了這兩個關鍵點,不管路徑名多長,不管跨越了多少個文件系統系統,link_path_walk都會一直走下去的。

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