歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux虛擬文件系統--文件路徑名的解析(2)--回退父目錄

Linux虛擬文件系統--文件路徑名的解析(2)--回退父目錄

日期:2017/2/28 15:28:33   编辑:Linux教程

上文介紹了解析文件路徑名的一個通體的過程,這裡再把其中的一些細節拿出來進行分析。首先對於文件名的特點,可以分為三類:普通文件名,'.'和'..',對於'.'的處理很簡單,因為它表示當前目錄,因此直接通過continue進入下一輪查找即可,對於'..',也就是退回到父目錄,本身也不是一件難事,但是這裡要考慮到幾個特殊情況,先看看內核處理'..'的方法:

相關閱讀:Linux虛擬文件系統--文件路徑名的解析(2)--回退父目錄 http://www.linuxidc.com/Linux/2012-11/74538.htm

static __always_inline void follow_dotdot(struct nameidata *nd)
{
set_root(nd);

while(1) {
struct vfsmount *parent;
struct dentry *old = nd->path.dentry;

/*如果當前所處的目錄即為根目錄則break*/
if (nd->path.dentry == nd->root.dentry &&
nd->path.mnt == nd->root.mnt) {
break;
}
spin_lock(&dcache_lock);

//如果當前所處的目錄不為當前路徑所屬文件系統的根目錄,也就是說可以直接向上退一級
if (nd->path.dentry != nd->path.mnt->mnt_root) {
nd->path.dentry = dget(nd->path.dentry->d_parent);//當前的目錄退到上一級
spin_unlock(&dcache_lock);
dput(old);
break;
}

/*下面的情況對應於當前所處的目錄為文件系統的根目錄*/
spin_unlock(&dcache_lock);
spin_lock(&vfsmount_lock);
parent = nd->path.mnt->mnt_parent;//取父文件系統
if (parent == nd->path.mnt) {//父文件系統即為本身,則表明沒有父文件系統,直接break
spin_unlock(&vfsmount_lock);
break;
}
mntget(parent);//增加父文件系統的引用計數
nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint);//取當前文件系統的掛載點,這樣就退回到了父文件系統
spin_unlock(&vfsmount_lock);
dput(old);
mntput(nd->path.mnt);
nd->path.mnt = parent;//設置當前路徑的mnt為父文件系統
}
/*一般情況下,前面的操作可以保證返回到上級目錄,但是有一種情況就是
當前目錄的上級目錄有可能還掛載了其他的文件系統,這樣會隱藏之前的文件系統,
follow_mount()用來處理這種情況*/
follow_mount(&nd->path);
}

while循環裡面的路徑可以分為三種:

1.當前目錄為nd中已經預設好的根目錄,也就是說無法再向上退一層了,這種情況直接break

2.當前目錄不為所屬文件系統的根目錄,這種情況是最常見的,可以向上退一層

3.當前目錄為所屬文件系統的掛載點,這種情況下,後退一層的話則會進入到父文件系統中,所以先要做一個文件系統的交換,再通過while(1)循環回到前面兩種情況

Copyright © Linux教程網 All Rights Reserved