免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1074 | 回复: 1
打印 上一主题 下一主题

[文件系统] 有关内核path_walk的疑惑 [复制链接]

论坛徽章:
1
2015亚冠之卡尔希纳萨夫
日期:2015-07-27 18:11:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-27 17:51 |只看该作者 |倒序浏览
最近在看一些文件系统的东西,有个不解的地方是,path_walk函数怎么检索从一个type(ramfs)过渡到另外一个type(fat16)?

想在flash的分区1中创建目录“xw”时,遇到上述的问题。
1) 先在Ramfs文件系统里边创建目录“/data"
2) 把一个flash分区1(属于fat16)挂载(mount)在目录"/data"
3) 需要path_walk解析出“/data”对应的nameidata
4) 然后调用fat16里边inode_operation的“mkdir”

其中第3点,理论上讲look_up到“data”时,已进入fat16系统里边了,这样才能检索到fat16对应的inode,才能使用fat16对应创建目录的方法。这个过程kernel是怎么做呢?

小弟是刚看文件系统不久的,源码看起来好繁琐好晕,提的问题不一定对,还望大虾们多多指导呀。

论坛徽章:
1
2015亚冠之卡尔希纳萨夫
日期:2015-07-27 18:11:47
2 [报告]
发表于 2015-07-28 10:15 |只看该作者
本帖最后由 maybe524 于 2015-07-28 10:19 编辑

终于知道kernel是怎么做了,因为在look_up的过程中,会不断地判断dentry是否被挂载(kernel-2.6.26):
  1. static int do_lookup(struct nameidata *nd, struct qstr *name,
  2.                      struct path *path)
  3. {
  4.         struct vfsmount *mnt = nd->path.mnt;
  5.         struct dentry *dentry = __d_lookup(nd->path.dentry, name);        // 在父目录所在的散列表(缓存)中查找该目录项对象

  6.         if (!dentry)
  7.                 goto need_lookup;
  8.         if (dentry->d_op && dentry->d_op->d_revalidate)         // 如果在缓存中找到,那么检查是否仍然有效
  9.                 goto need_revalidate;
  10. done:
  11.         path->mnt = mnt;
  12.         path->dentry = dentry;
  13.         __follow_mount(path);  // 检查当前的dentry是否是一个挂载点
  14.         return 0;

  15. need_lookup:
  16.         dentry = real_lookup(nd->path.dentry, name, nd);        // 如果在__d_lookup中未找到,需要在最底层的文件系统中查找操作
  17.         if (IS_ERR(dentry))
  18.                 goto fail;
  19.         goto done;

  20. need_revalidate:
  21.         dentry = do_revalidate(dentry, nd);
  22.         if (!dentry)
  23.                 goto need_lookup;
  24.         if (IS_ERR(dentry))
  25.                 goto fail;
  26.         goto done;

  27. fail:
  28.         return PTR_ERR(dentry);
  29. }
复制代码
  1. static int __follow_mount(struct path *path)
  2. {
  3.         int res = 0;
  4.         while (d_mountpoint(path->dentry)) { // 检查dentry->d_mounted是否大于1,如果大于,则判定dentry是一个挂载点
  5.                 struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
  6.                 if (!mounted)
  7.                         break;
  8.                 dput(path->dentry);
  9.                 if (res)
  10.                         mntput(path->mnt);
  11.                 path->mnt = mounted;
  12.                 path->dentry = dget(mounted->mnt_root); // 在此例子中,dentry指向flsh分区1的root的目录。哈哈,这样就完成了从ramfs到fat的过渡了。
  13.                 res = 1;
  14.         }
  15.         return res;
  16. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP