天天看點

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都會一直走下去的。

繼續閱讀