Chinaunix首页 | 论坛 | 博客
  • 博客访问: 438813
  • 博文数量: 99
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 1012
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-20 16:30
个人简介

linux kernel 工程师

文章分类

全部博文(99)

文章存档

2018年(5)

2017年(12)

2016年(27)

2015年(10)

2014年(43)

2012年(2)

我的朋友

分类: LINUX

2016-12-21 17:52:48





                            


1.    Follow_dotdot


点击(此处)折叠或打开

  1. /* nd里面有当前路径的dentry和vfsmount信息 */
  2. static __always_inline void follow_dotdot(struct nameidata *nd)
  3. {
  4.     set_root(nd);

  5.     /* 关于这个while循环,如图1的情景:
  6.     mount /dev/sdc1 /mnt/tmp1
  7.     mount /dev/sdd1 /mnt/tmp1,
  8.     cd /mn/tmp1; 此时path的dentry和mnt指向的是图1中的/dev/sdd1 这个 层次的dentry和vfsmnt
  9.     cd ../

  10.     下面着重分析返回父目录的情形
  11.     1.    while第1次执行循环, 情景1和情景2都不符合,执行情景3的follow_up函数。    
  12.         执行follow_up的结果是,path的dentry和mnt指向了sdc1层次的dentry和vfsmnt ,follow_up返回1,循环继续。
  13.     2.    第2次执行while循环时, 情景1和情景2依旧都不符合,继续执行情景3的follow_up函数。
  14.         执行follow_up的结果是,path的dentry和mnt指向了/mnt/tmp1层次的dentry和vfsmnt 。注意“/mnt/tmp1”,“/mnt/”, “/”这三个路径在同一个设备上,使用的是同一个vfsmount结构。follow_up返回1,循环继续。
  15.     3.    第3次执行while循环时,执行情景2,path的dentry更新为“/mnt”对应的dentry, path的mnt保持不变。While循环结束。
  16.     */

  17.     /* 对于图2的情形
  18.     a.    cd /mnt/tmp1; mkdir wgh;    cd /mnt/tmp1/wgh;
  19.     b.    第1步完成之后,把设备“/dev/sdc1” mount到/mnt/tmp1
  20.     c.   /mnt/tmp1/wgh路径下, 执行cd ..

  21.     下面着重分析该情景下返回父目录的过程:

  22.     1.    while第1次执行循环, 情景1不符合,情景2符合, path的dentry更新为“/mnt/tmp1”对应的dentry, path的mnt保持不变。While循环结束。
  23.     2.    path停留在图2中 /mnt/tmp1层次,那么将看不到挂在/mnt/tmp1下面的/dev/sdc1设备。为了能够看到/dev/sdc1下的文件,需要执行follow_mount函数。 通过执行follow_mount函数, path->mnt和path->dentry分别指向/dev/sdc1层次下的dentry和vfs_mount.
  24.     */

  25.     while(1) {
  26.         struct dentry *old = nd->path.dentry;
  27.         /*
  28.         情景1:如果当前路径的dentry,vfsmount结构与current->fs->dentry以及
  29.         current->fs->mnt相同, 则说明已经是当前进程的根节点
  30.         */
  31.         if (nd->path.dentry == nd->root.dentry &&
  32.          nd->path.mnt == nd->root.mnt) {
  33.             break;
  34.         }
  35.         /*
  36.         情景2:如果当前路径的dentry不等于vfsmount->mount_root, 则说明当前dentry的父节点的dentry在一个设备上
  37.          */
  38.         if (nd->path.dentry != nd->path.mnt->mnt_root) {
  39.             /* rare case of legitimate dget_parent()... */
  40.             nd->path.dentry = dget_parent(nd->path.dentry);
  41.             dput(old);
  42.             break;
  43.         }
  44.         /* 情景3:程序走到这里,说明当前dentry与父dentry不在一个设备上follow_up会更新path的dentry和mnt,用父dentry和父vfsmount结构来替换。如果函数返回值为0,表示当前路径已经是根路径,需要结束while循环。 */
  45.         if (!follow_up(&nd->path))
  46.             break;
  47.     }

  48.     follow_mount(&nd->path);
  49. }



1.1 follow_up


点击(此处)折叠或打开

  1. /* 如果一个path的dentry就是该path->mnt的mount_root, 说明该path是一个设备的根节点,该path被mount到另外一个路径上 */
  2. int follow_up(struct path *path)
  3. {
  4.     struct vfsmount *parent;
  5.     struct dentry *mountpoint;
  6.     spin_lock(&vfsmount_lock);
  7.     /* 根据当前路径的mnt找到mnt_parent */
  8.     parent = path->mnt->mnt_parent;
  9.     if (parent == path->mnt) { /*是根设备,返回0 */
  10.         spin_unlock(&vfsmount_lock);
  11.         return 0;
  12.     }
  13.     mntget(parent);
  14.     /* 根据当前路径的mnt找到mnt_point */    
  15.     mountpoint = dget(path->mnt->mnt_mountpoint);
  16.     spin_unlock(&vfsmount_lock);
  17.     dput(path->dentry);
  18.     path->dentry = mountpoint;
  19.     mntput(path->mnt);
  20.     path->mnt = parent;
  21.     return 1; /* 当前路径非根设备,返回1 */
  22. }


1.2 follow_mount


点击(此处)折叠或打开

  1. static void follow_mount(struct path *path)
  2. {
  3.     while (d_mountpoint(path->dentry)) {
  4.         struct vfsmount *mounted = lookup_mnt(path);
  5.         if (!mounted)
  6.             break;
  7.         dput(path->dentry);
  8.         mntput(path->mnt);
  9.         path->mnt = mounted;
  10.         path->dentry = dget(mounted->mnt_root);
  11.     }
  12. }



阅读(1227) | 评论(0) | 转发(0) |
0

上一篇:how to use sysroot in wrlinux6.0

下一篇:attach_mnt

给主人留下些什么吧!~~