资源描述:
《linux open系统调用完全剖析》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Linux系统是如何区分普通文件与设备驱动文件的研究一文件的打开一般来说对于文件或者是设备的操作都是从open开始的,我们首先要打开这个设备节点或者是普通文件,才可以对这个文件进行read、write、ioctl、mmap等操作。所以一切的起源于open。我们首先从open开始研究。在linux系统进程当中,分为内核空间和用户空间。当我们在用户空间通过open之后,会产生一个软中断,然后通过系统调用陷入内核空间。通过系统调用号,我们可以跳转到该中断例程的入口地址,我们接着看内核源码的实现。1、在arch/x86/include/asm/unist
2、d_32.h中定义了系统调用号#define__NR_restart_syscall0#define__NR_exit1#define__NR_fork2#define__NR_read3#define__NR_write4#define__NR_open5#define__NR_close6#define__NR_waitpid7。。。。。。。。2、当产生系统调用的时候,会进入到下面这个函数:SYSCALL_DEFINE3(open,constchar__user*,filename,int,flags,int,mode){longret;if
3、(force_o_largefile())flags
4、=O_LARGEFILE;ret=do_sys_open(AT_FDCWD,filename,flags,mode);/*avoidREGPARMbreakageonx86:*/asmlinkage_protect(3,ret,filename,flags,mode);returnret;}3、最终会调用到do_sys_open(),这个函数首先分配一个可用的文件描述符。并且通过调用do_filp_open()通过传进来的文件名查找到inode信息,并且根据这些信息创建一个file对象,并且将
5、inode和file的关系关联起来。longdo_sys_open(intdfd,constchar__user*filename,intflags,intmode){/*获取文件名称,由getname()函数完成,其内部首先创建存取文件名称的空间,然后*从用户空间把文件名拷贝过来*/char*tmp=getname(filename);intfd=PTR_ERR(tmp);if(!IS_ERR(tmp)){/*获取一个可用的fd,此函数调用alloc_fd()函数从fd_table中获取一个可用fd,并做些简单初始化,此函数内部实现比较简单,此
6、次分析不细看,注意,对于文件描述符fd来讲,它只对本进程有效,也即它只在该进程中可见而在其它进程中代表着完全不同的文件。*/fd=get_unused_fd_flags(flags);if(fd>=0){/*fd获取成功则开始打开文件,此函数是主要完成打开功能的函数,在此先放一放,下面详细分析*///如果分配fd成功,则创建一个file对象structfile*f=do_filp_open(dfd,tmp,flags,mode,0);if(IS_ERR(f)){/*打开失败,释放fd*/put_unused_fd(fd);fd=PTR_ERR(f
7、);}else{/*文件如果已经被打开了,调用fsnotify_open()函数,根据inode所指定的信息进行打开函数(参数为f)将该文件加入到文件监控的系统中。该系统是用来监控文件被打开,创建,读写,关闭,修改等操作的*/fsnotify_open(f->f_path.dentry);/*将文件指针安装在fd数组中将structfile*f加入到fd索引位置处的数组中。如果后续过程中,有对该文件描述符的操作的话,就会通过查找该数组得到对应的文件结构,而后在进行相关操作。*/fd_install(fd,f);}}/*释放放置从用户空间拷贝过来的
8、文件名的存储空间*/putname(tmp);}returnfd;}4、do_filp_open函数的一个重要作用就是根据传递近来的权限进行分析,并且分析传递近来的路径名字,根据路径名逐个解析成dentry,并且通过dentry找到inode,inode就是记录着该文件相关的信息,包括文件的创建时间和文件属性所有者等等信息,根据这些信息就可以找到对应的文件操作方法。在这个过程当中有一个临时的结构体用于保存在查找过程中的相关信息,就是structnameidata{structpathpath;//当前目录的dentry数据结构structqstr
9、last;//这个结构体也是临时性的,主要用来保存当前目录的名称,杂凑值。unsignedintflags;intlast_type;u