VFS四大对象之四-struct file

继上一篇文章:

http://yehe.isd.com/column/support-plan/article-edit/93709

四、file结构体

文件对象:注意文件对象描述的是进程已经打开的文件。因为一个文件可以被多个进程打开,所以一个文件可以存在多个文件对象。但是由于文件是唯一的,那么inode就是唯一的,目录项也是定的!

进程其实是通过文件描述符来操作文件的,注意每个文件都有一个32位的数字来表示下一个读写的字节位置,这个数字叫做文件位置。

565 struct file {
566         struct list_head        f_list;
567         struct dentry           *f_dentry;
568         struct vfsmount         *f_vfsmnt;
569         struct file_operations  *f_op;
570         atomic_t                f_count;
571         unsigned int            f_flags;
572         mode_t                  f_mode;
573         loff_t                  f_pos;
574         unsigned long           f_reada, f_ramax, f_raend, f_ralen, f_rawin;
575         struct fown_struct      f_owner;
576         unsigned int            f_uid, f_gid;
577         int                     f_error;
578 
579         size_t                  f_maxcount;
580         unsigned long           f_version;
581 
582         /* needed for tty driver, and maybe others */
583         void                    *private_data;
584 
585         /* preallocated helper kiobuf to speedup O_DIRECT */
586         struct kiobuf           *f_iobuf;
587         long                    f_iobuf_lock;
588 };

f_list:所有的打开的文件形成的链表!注意一个文件系统所有的打开的文件都通过这个链接到super_block中的s_files链表中!

f_dentry:与该文件相关的dentry

f_vfsmnt:该文件在这个文件系统中的安装点

f_op:文件操作,当进程打开文件的时候,这个文件的关联inode中的i_fop文件操作会初始化这个f_op字段

f_count:引用计数

f_flags:打开文件时候指定的标识

f_mode:文件的访问模式

f_pos:目前文件的相对开头的偏移

unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin:预读标志、要预读的最多页面数、上次预读后的文件指针、预读的字节数以及预读的页面数

f_owner:记录一个进程ID,以及当某些事发送的时候发送给该ID进程的信号

f_uid:用户ID

f_gid:组ID

f_error:写操作错误码

f_version:版本号,当f_pos改变时候,version递增

private_data:私有数据( 文件系统和驱动程序使用 )

重点解释一些重要字段

首先,f_flags、f_mode和f_pos代表的是这个进程当前操作这个文件的控制信息。这个非常重要,因为对于一个文件,可以被多个进程同时打开,那么对于每个进程来说,操作这个文件是异步的,所以这个三个字段就很重要了。

第二:对于引用计数f_count,当我们关闭一个进程的某一个文件描述符时候,其实并不是真正的关闭文件,仅仅是将f_count减一,当f_count=0时候,才会真的去关闭它。对于dup,fork这些操作来说,都会使得f_count增加,具体的细节,以后再说。

第三:f_op也是很重要的!是涉及到所有的文件的操作结构体。例如:用户使用read,最终都会调用file_operations中的读操作,而file_operations结构体是对于不同的文件系统不一定相同。里面一个重要的操作函数式release函数,当用户执行close时候,其实在内核中是执行release函数,这个函数仅仅将f_count减一,这也就解释了上面说的,用户close一个文件其实是将f_count减一。只有引用计数减到0才关闭文件。

注意:对于“正在使用”和“未使用”的文件对象分别使用一个双向链表进行管理。

注意上面的file只是对一个文件而言,对于一个进程(用户)来说,可以同时处理多个文件,所以需要另一个结构来管理所有的files!

即:用户打开文件表--->files_struct

172 struct files_struct {
173         atomic_t count;
174         rwlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
175         int max_fds;
176         int max_fdset;
177         int next_fd;
178         struct file ** fd;      /* current fd array */
179         fd_set *close_on_exec;
180         fd_set *open_fds;
181         fd_set close_on_exec_init;
182         fd_set open_fds_init;
183         struct file * fd_array[NR_OPEN_DEFAULT];
184 };

 解释一些字段:

count:引用计数

file_lock:锁,保护下面的字段

max_fds:当前文件对象的最大的数量

max_fdset:文件描述符最大数

next_fd:已分配的最大的文件描述符+1

fd:指向文件对象指针数组的指针,一般就是指向最后一个字段fd_arrray,当文件数超过NR_OPEN_DEFAULT时候,就会重新分配一个数组,然后指向这个新的数组指针!

close_on_exec:执行exec()时候需要关闭的文件描述符

open_fds:指向打开的文件描述符的指针

close_on_exec_init:执行exec()时候需要关闭的文件描述符初始化值

open_fds_init:文件描述符初值集合

fd_array:文件对象指针的初始化数组

注意上面的file和files_struct记录的是与进程相关的文件的信息,但是对于进程本身来说,自身的一些信息用什么表示,这里就涉及到fs_struct结构体。

  5 struct fs_struct {
  6         atomic_t count;
  7         rwlock_t lock;
  8         int umask;
  9         struct dentry * root, * pwd, * altroot;
 10         struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
 11 };

 解释一些字段:

count:引用计数

lock:保护锁

umask:打开文件时候默认的文件访问权限

root:进程的根目录

pwd:进程当前的执行目录

altroot:用户设置的替换根目录

注意:实际运行时,这三个目录不一定都在同一个文件系统中。例如,进程的根目录通常是安装于“/”节点上的ext文件系统,而当前工作目录可能是安装于/etc的一个文件系统,替换根目录也可以不同文件系统中。

rootmnt,pwdmnt,altrootmnt:对应于上面三个的安装点。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GreenLeaves

WCF系列教程之WCF服务配置

文本参考自:http://www.cnblogs.com/wangweimutou/p/4365260.html 简介:WCF作为分布式开发的基础框架,在定义服...

2016
来自专栏抠抠空间

Django之auth模块(用户认证)

auth模块简介 auth模块是对登录认证方法的一种封装,之前我们获取用户输入的用户名及密码后需要自己从user表里查询有没有用户名和密码符合的对象, 而有了a...

4225
来自专栏Java3y

看完这篇Linux基本的操作就会了

3006
来自专栏linux驱动个人学习

解析Linux中的VFS文件系统之文件系统的注册(二)

继上一篇文章:https://cloud.tencent.com/developer/article/1053882 3. 文件系统的注册 这里的文件系统是指可...

3436
来自专栏java思维导图

【读书笔记】1.1-基于TCP协议的RPC

1.1.1RPC名词解释 概念 全称Remote Process Call,即远程过程调用 rpc的实现包括服务的调用方和服务的提供方 过程 服务调用方发送RP...

2683
来自专栏Java面试笔试题

什么是DAO模式?

DAO(Data Access Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各种数据访...

1012
来自专栏Debian社区

Linux 系统 vim 编辑器使用简明教程

vi(vim)是上Linux非常常用的代码编辑器,很多Linux发行版都默认安装了vi(vim)。vi(vim)命令繁多但是如果使用灵活之后将会大大提高效率。v...

1207
来自专栏Django Scrapy

Linux 目录结构及文件基本操作

win和类unix系统的文件目录的区别 一种不同是体现在目录与存储介质(磁盘,内存,DVD 等)的关系上,以往的 Windows 一直是以存储介质为主的,主要...

3066
来自专栏闻道于事

Linux-看完这篇Linux基本的操作就会了

1973
来自专栏IT派

Python 的异步 IO:Asyncio 简介

所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知。

883

扫码关注云+社区