微信号:LinuxKernelTravel

介绍:Linux内核之旅

open()在Linux内核的实现(1)-基本实现

2015-12-13 10:41 edsionte


说明:阅读本篇之前,先阅读前一篇 “open()在Linux内核的实现-准备工作”,open()在Linux内核的实现”系列文章将分析open系统调用在Linux内核中的实现过程。本系列文章分为六篇,每篇文章都描述 open()实现的一部分内容,与前后的系列文章保持相对独立。前篇文章属于前序,集中说明后续文章涉及到的基本原理和基本数据结构,并且对整个分析过程进行Q&A。


1.基本说明

在用户态使用open()时,必须向该函数传入文件路径和打开权限。这两个参数传入内核后,内核首先检查这个文件路径存在的合法性,同时还需检查使用者是否有合法权限打开该文件。如果一切顺利,那么内核将对访问该文件的进程创建一个file结构。

在用户态,通常open()在操作成功时返回的是一个非负整数,即所谓的文件描述符(fd,file descriptor);并且,用户态后续对文件的读写操作等都是通过fd来完成的。由此可见fd与file结构在内核中有一定的关联。

具体的,内核使用进程描述符task_struct来描述一个进程,而该进程所有已打开文件对应的file结构将形成一个数组files(其为files_struct结构),内核向用户返回的fd便是该数组中具体file结构的索引。默认情况下,每个进程创建后都已打开了标准输入文件、标准输出文件、标准错误文件,因此他们的文件描述符依次为0、1和2。

2.函数分析

2.1.do_sys_open

明白了上述原理,那么open系统调用在内核中的基本实现过程就很清晰。根据系统调用入口函数的命名规则,open系统调用的入口函数应该为sys_open。不过,目前内核统一使用SYSCALL_DEFINEn宏来描述系统调用入口函数,因此可以在open.c文件中找到该入口函数,具体如下所示:

1 SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode);

该函数内部直接调用了do_sys_open函数,具体声明如下:

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

这个函数的参数基本上与open系统调用的参数一致。

该函数可以简单概括open系统调用的功能:

1.通过build_open_flags()将用户态的flags和mode转换成对应的内核态标志;

2.由于filename是用户态的内存缓冲区(使用了__user修饰),因此通过getname()将文件名从用户态拷贝至内核态;

3.get_unused_fd_flags()为即将打开的文件分配文件描述符;也就是在当前进程的files数组中寻找一个未使用的位置;

4.通过do_filp_open()为文件创建file结构体;

5.如果创建file成功,则通过fd_install()将fd和file进行关联;如果创建file失败,通过put_unused_fd()将已分配的fd返回至系统,并且根据file生成错误的fd;

6.通过putname()释放在内核分配的路径缓冲区;

7.返回fd;

当open系统调用执行完毕后,fd返回用户态,内核态新建了与其关联的file;对于每个进程而言,通过files_struct来记录其所打开的文件,具体通过fd_array数据保存fd和file的对应关系,fd本质为该数组的索引。

3.总结

至此,open的基本实现过程已经分析完毕。不过do_sys_open函数没有直接体现文件路径的查找过程,这部分将是整个open系统调用内核实现的重要部分。如果对此感兴趣,可以继续阅读本系列后续文章。

参考资料:

1.Linux源码3.2.69;

2.Linux系统调用open七日游:http://blog.chinaunix.net/uid-20522771-id-4419666.html

3.深入理解Linux内核:http://book.douban.com/subject/2287506/;

4.深入Linux内核架构:http://book.douban.com/subject/4843567/;

5.Linux内核探秘:http://book.douban.com/subject/25817503/;




 
Linux内核之旅 更多文章 Linux内核之旅—微信平台开篇 《Linux内核设计与实现》章节节选—操作系统和内核简介 hurlex这个基于x86架构的内核 操作系统中的哲学 杂谈:物理世界,虚拟世界
猜您喜欢 周末--刷爆朋友圈的《黑凤梨》完整版来啦~ 自助式商业智能的"因为所以"和科学道理 行业 | 当“能源”遇上“互联”,给我一粒火种,我能烧透半边天 10个最“牛叉”的代码注释 从粗放式到精益化编程