1. 首先传到vfs的do_sys_open,在open.c中。

      long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)

此时,我们只知道open传递过来的一些参数,比如filename,open调用是这样的

     int open(const char *pathname, int flags, mode_t mode);

 因此,只有dfd是新加的,我们先不管他的作用。

do_sys_open主要做以下事情

(1) int fd = build_open_flags(flags, mode, &op);//将open传递过来的flags和mode进行整理,赋值给op

   fd = get_unused_fd_flags(flags);//分配一个未使用的fd

    这个fd就是返回给用户open函数的fd。

(2) tmp = getname(filename); 将文件名做整理,并填充给tmp结构//struct filename *tmp;

(3) struct file *f = do_filp_open(dfd, tmp, &op); 这个就是实际的打开函数,填充struct file

(4) fd_install(fd, f); 将fd与 f进行关联。

2. 上面第(3)步是核心内容。首先我们在这里看struct file结构,/include/linux/fs.h

里面有三个比较重要的域。

  1. struct inode *f_inode; /* cached value */
  1. const struct file_operations *f_op;
  1. struct address_space *f_mapping;

我们看do_filp_open如何对他们进行填充。

(1)首先创建struct nameidata nd; set_nameidata(&nd, dfd, pathname);

  1. struct nameidata {
  2. struct path path;
  3. struct qstr last;
  4. struct path root;
  5. struct inode *inode; /* path.dentry.d_inode */
  6. unsigned int flags;
  7. unsigned seq;
  8. int last_type;
  9. unsigned depth;
  10. char *saved_names[MAX_NESTED_LINKS + 1];
  11.  
  12. /* Intent data */
  13. union {
  14. struct open_intent open;
  15. } intent;
  16. };

set_nameidata主要使用参数 pathname 。

static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
{
  struct nameidata *old = current->nameidata;
  p->stack = p->internal;
  p->dfd = dfd;
  p->name = name;
  p->total_link_count = old ? old->total_link_count : 0;
  p->saved = old;
  current->nameidata = p;
}

struct task_struct首先使用局部指针指向当前进程的nameidata, struct nameidata *old = current->nameidata; 也即是说,每个进程结构包含一个nameidata

然后只是给nd的total_link_count和pathname赋值。inode并没有管。total_link_count据说是用来防止循环死链的。

(2) filp = path_openat(&nd, op, flags | LOOKUP_RCU);

首先是file = get_empty_filp(); 为struct file 分配内存。

path_init为nd的path和inode赋值,为path->dentry赋值. static int link_path_walk 为nd->last 赋值

(3)主要的打开操作在 do_last 中。

link_path_walk 用于一级一级解析文件路径,每一级都调用do_last。 参考:http://alanwu.blog.51cto.com/3652632/1120652

3. 现在我们来分析 link_path_walk

函数原型:static int link_path_walk(const char *name, struct nameidata *nd)

调用方式:link_path_walk(s, nd) ,调用时,s通过 s=path_init(nd, flags)进行了赋值。

(1)首先,while (*name=='/') name++;假设name是/home/user/xxx,这条语句将name定位到h这个地方。疑惑:这里为什么要用while?这不是会导致路径名可以有多个斜杠?

    如果while后name为null,则直接返回0. 这表明路径是一个目录。

(2)

4. 最终,do_last 调用 lookup_open, 调用atmoic_open,调用dir->i_op->atomic_open

      dir是struct inode类型的,定义在/include/linux/fs.h,其中的 struct inode_operations i_op结构含有 atomic_open指针。

open调用过程的更多相关文章

  1. FormatMessage与GetLastError配合使用,排查windows api调用过程中的错误

    前一段时间在学习windows api调用过程中,遇到过一些调用错误或者程序没能显示预期的结果,或者直接出现vc运行时错误. 这对新手来说是司空见惯的事,因为不太熟悉难免会出错,出错的信息如果能显示很 ...

  2. pro*c调用过程

    数据库内有无参数过程名为procedure. pro*c调用过程 EXEC SQL EXECUTE   BEGIN     procedure;   END; END-EXEC; 需要在cfg配置文件 ...

  3. Hadoop中客户端和服务器端的方法调用过程

    1.Java动态代理实例 Java 动态代理一个简单的demo:(用以对比Hadoop中的动态代理) Hello接口: public interface Hello { void sayHello(S ...

  4. Hbase的WAL在RegionServer基本调用过程

    版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221 来源:腾云阁 https://www.qclo ...

  5. Servlet视频学习笔记 57-58 (servlet入门和调用过程)

    网易云课堂<30天轻松掌握JavaWeb视频>servlet部分 课时57 servlet开发入门 servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术.S ...

  6. 最原始的COM组件调用过程(不使用注册表信息)

    最原始的COM组件调用过程(不使用注册表信息) 最近因为项目的关系开始研究COM组件了,以前都认为COM过时了,所以也没怎么接触. 现在好好补补课了. 一般调用COM都是通过注册表找到它的位置, 然后 ...

  7. oracle顺序控制语句goto、null和分页过程中输入输出存储、java程序的调用过程

    顺序控制语句1 goto建议不要使用 declare i number:=; begin loop dbms_output.put_line(i); then goto end_loop; end i ...

  8. .net ADF 中 Ajax 的调用过程.

    图示是 .net ADF Ajax调用过程的简略过程: 1,2)当页面初始化之后, 浏览器一旦触发回调事件, 脚本函数负责处理回调信息, 并调用 ASP.NET 2.0/3.5 中的 WebForm_ ...

  9. alsa声卡分析alsa-utils调用过程

    如何分析tinyplay 播放音频和tinymix的过程?需要相应的工具来支持追查: 一.利用strace工具分析tinyplay和tinymix: strace -o tinyplay.log ti ...

  10. springMVC源码分析--HandlerInterceptor拦截器调用过程(二)

    在上一篇博客springMVC源码分析--HandlerInterceptor拦截器(一)中我们介绍了HandlerInterceptor拦截器相关的内容,了解到了HandlerInterceptor ...

随机推荐

  1. objective-c中#import和@class的区别

    在Objective-C中,可以使用#import和@class来引用别的类型, 但是你知道两者有什么区别吗? @class叫做forward-class,  你经常会在头文件的定义中看到通过@cla ...

  2. php——两种无限级分类

    /** * 无级递归分类 TP框架 * @param int $assortPid 要查询分类的父级id * @param mixed $tag 上下级分类之间的分隔符 * @return strin ...

  3. .net core 使用 codegenerator 创建默认CRUD代码

    dotnet.exe aspnet-codegenerator controller --force --controllerName [controller-name] --relativeFold ...

  4. ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题意: 求动态区间第K大. 分析: 把修改操作看成删除与增加 ...

  5. Hadoop三种模的安装配置过程

    JDK+Hadoop安装配置.单机模式配置 以下操作在SecureCRT里面完成 1.关闭防火墙 firewall-cmd --state 显示防火墙状态running/not running sys ...

  6. 前端进阶之路:初涉Less

    阅读目录 一.Less介绍 1.官方介绍 2.自己理解 3.Less.Sass.Stylus 二.Less使用入门 1.开发模式下使用Less 2.运行模式下使用Less 三.常见用法示例 1.从第一 ...

  7. Python基础语法06--文件

    Python 文件I/O 本章只讲述所有基本的的I/O函数,更多函数请参考Python标准文档. 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式.此函数把你 ...

  8. BUPT复试专题—最小距离查询(2013)

    题目描述 给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始).你需要完成下面两个操作:INSERT c  其中c是一个待输入的字符.你需要在字符串的末尾添加这个字符.保证 ...

  9. 【转】Code Your Own PHP MVC Framework in 1 Hour

      原文: https://www.codeproject.com/Articles/1080626/Code-Your-Own-PHP-MVC-Framework-in-Hour --------- ...

  10. MAC上Nuclide的安装

    MAC上Nuclide的安装 本文版权归作者全部,如需转载请联系孟祥月 CSDN博客:http://blog.csdn.net/mengxiangyue 独立博客:http://mengxiangyu ...