struct task_struct {

.........................

struct mm_struct*mm;//内存描述符的指针

struct files_struct *file;    //进程打开文件表

pid_t pid;

..............................

};

struct files_struct {
        atomic_t count;                               //引用计数
        spinlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
 struct fdtable *fdt;                          //管理文件描述符
 struct fdtable fdtab;                         //管理文件描述符
        fd_set close_on_exec_init;                    //位图
        fd_set open_fds_init;                         //位图
        struct file * fd_array[NR_OPEN_DEFAULT];      //文件描述符数组
};

注意文件表项中有一个引用计数,来表示,多几个文件描述符,指向这个文件表项。。不同的文件描述符可以指向相同的文件表项

/文件描述符数组/

文件描述符数组对应的struct file指针,数组的元素,是指向file的指针

apue中的对应图片是

其中文件表项是struct file类型对象

struct file {
    ……
     struct list_head        f_list;        /*文件对象链表*/
    struct dentry          *f_dentry;       /*相关目录项对象*/
    struct vfsmount        *f_vfsmnt;       /*相关的安装文件系统*/
    struct file_operations *f_op;           /*文件操作表*/
    ……
};

struct file_operations {
    ……
    //文件读操作
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ……
    //文件写操作
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    ……
    int (*readdir) (struct file *, void *, filldir_t);
    ……
    //文件打开操作
    int (*open) (struct inode *, struct file *);
    ……
};

每个file结构体都有一个指向dentry结构体的指针,“dentry”是directory entry(目录项)的缩写。

file对象中包含一个指针,指向dentry对象。dentry对象代表一个独立的文件路径,如果一个文件路径被打开多次,那么会建立多个file对象,但它们都指向同一个dentry对象。

struct dentry {
  atomic_t d_count; 目录项对象使用计数器
  unsigned int d_flags; 目录项标志
  struct inode * d_inode; 与文件名关联的索引节点
  struct dentry * d_parent; 父目录的目录项对象
  struct list_head d_hash; 散列表表项的指针
  struct list_head d_lru; 未使用链表的指针
  struct list_head d_child; 父目录中目录项对象的链表的指针
  struct list_head d_subdirs;对目录而言,表示子目录目录项对象的链表
  struct list_head d_alias; 相关索引节点(别名)的链表
  int d_mounted; 对于安装点而言,表示被安装文件系统根项
  struct qstr d_name; 文件名
  unsigned long d_time; /* used by d_revalidate */
  struct dentry_operations *d_op; 目录项方法
  struct super_block * d_sb; 文件的超级块对象
  vunsigned long d_vfs_flags;
  void * d_fsdata;与文件系统相关的数据 
  unsigned char d_iname [DNAME_INLINE_LEN]; 存放短文件名
  };

struct inode {
unsigned long                     i_ino;
atomic_t                               i_count;
umode_t                               i_mode;
unsigned int                        i_nlink;
uid_t                                      i_uid;
gid_t                                      i_gid;
dev_t                                     i_rdev;
loff_t                                      i_size;
struct timespec                   i_atime;
unsigned long                     i_blocks;
unsigned short                    i_bytes;
unsigned char                      _sock;
12
struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */
struct super_block *i_sb;
......
};

在内存中, 每个文件都有一个dentry(目录项)和inode(索引节点)结构,dentry记录着文件名,上级目录等信息,正是它形成了我们所看到的树状结构;而有关该文件(该文件可以是磁盘上面的目录文件)的组织和管理的信息主要存放inode里面,它记录着文件在存储介质上的位置与分布。同时dentry->d_inode指向相应的inode结构。dentry与inode是多对一的关系,因为有可能一个文件有好几个文件名(inode(可理解为ext2 inode)对应于物理磁盘上的具体对象,dentry是一个内存实体,其中的d_inode成员指向对应的inode。也就是说,一个inode可以在运行的时候链接多个dentry,而d_count记录了这个链接的数量。)

VFS文件系统中的inode和dentry与实际文件系统的inode和dentry有一定的关系,但不能等同。真实磁盘文件的inode和dentry是存在于物理外存上的,但VFS中的inode和dentry是存在于内存中的,系统读取外存中的inode和dentry信息进行一定加工后,生成内存中的inode和dentry。虚拟的文件系统也具有inode和dentry结构,只是这是系统根据相应的规则生成的,不存在于实际外存中。

我们谈到目录项和索引节点时,有两种含义。一种是在存储介质(硬盘)中的(如ext3_inode),一种是在内存中的,后者是根据在前者生成的。内存中的表示就是dentry和inode,它是VFS中的一层,不管什么样的文件系统,最后在内存中描述它的都是dentry和inode结构。

VFS dentry结构:

每个文件都有一个dentry(可能不止一个),这个dentry链接到上级目录的dentry。根目录有一个dentry结构,而根目录里的文件和目录都链接到这个根dentry,二级目录里的文件和目录,同样通过dentry链接到二级目录。这样一层层链接,就形成了一颗dentry树。从树顶可以遍历整个文件系统的所有目录和文件。

为了加快对dentry的查找,内核使用了hash表来缓存dentry,称为dentry cache。dentry cache在后面的分析中经常用到,因为dentry的查找一般都先在dentry cache里进行查找。

磁盘上面的概念:

目录项:包括文件名和inode节点号(磁盘上面的概念)(用于指向磁盘数据块)inode是指向一个文件数据区的指针号码,一个inode对应着系统中唯一的一片物理数据区,而位于两个不同物理数据区的文件必定分别对应着两个不同的inode号码,这里是磁盘的dentry

Inode:又称文件索引节点,是文件基本信息的存放地和数据块指针存放地。

数据块:文件的具体内容存放地。

inode指向的是数据块(数据块包括:普通文件块和目录文件块)

硬连接和软连接:在磁盘层面上升到内存层面,linux操作系统的vfs层面。

一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Linux系统允许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为"硬链接"(hard link)。

即VFS中的多个dentry,对应同一个VFD中的inode。就是硬连接

软连接:

文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)。这种文件的数据部分仅包含它所要链接文件的路径名

软链接有自己的inode,并在磁盘上有一小片空间存放路径名。因此,软链接能够跨文件系统,也可以和目录链接!其二,软链接可以对一个不存在的文件名进行链接,但直到这个名字对应的文件被创建后,才能打开其链接。

超级块和dentry关系:

inode有一个指针指向超级块,超级块主要是描述文件类型(ext3还是别的类型),同时超级块有一个指针,指向dentry缓存中的dentry。表明此此文件系统是挂载在什么目录下面

linux文件系统相关概念的更多相关文章

  1. Linux文件系统学习(一)之相关概念⭐⭐⭐

    “一切皆是文件”是 Unix/Linux 的基本哲学之一.不仅普通的文件,目录.字符设备.块设备.套接字等在 Unix/Linux 中都是以文件被对待:它们虽然类型不同,但是对其提供的却是同一套操作界 ...

  2. Linux的相关概念

    1 Linux的相关概念 1.1 什么是操作系统? 操作系统(英语:operating system,缩写:OS)是管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石.操作系统需要处 ...

  3. [apue] linux 文件系统那些事儿

    前言 说到 linux 的文件系统,好多人第一印象是 ext2/ext3/ext4 等具体的文件系统,本文不涉及这些,因为研究具体的文件系统难免会陷入细节,甚至拉大段的源码做分析,反而不能从宏观的角度 ...

  4. linux文件系统体系结构 和 虚拟文件系统(VFS)

    图 1. Linux 文件系统组件的体系结构 用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C 库(glibc),它们为文件系统调用(打开.读取.写和关闭)提供用户接口.系统调用接口的 ...

  5. Linux文件系统

    今天学习了Linux文件系统,现在来做个小总结. 首先Linux中一切都是文件,下面这个清单是Linux系统的顶层目录结构. 清单 1. Linux 系统的顶层目录结构 / 根目录 ├── bin 存 ...

  6. linux 文件系统简介

    linux文件系统简介   文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基 ...

  7. Linux文件系统层次结构标准

    该标准的目的是定义Linux文件系统的标准路径,使得开发者和用户可以在合理的位置找到需要的东西. Linux的文件布局的大体想法是将文件和目录分为如下3组: 对运行Linux的某一特定系统唯一的文件和 ...

  8. linux文件系统节点详解

    linux文件系统有两层结构,逻辑结构和物理结构.也就是inode和block. 每个文件都有一个inode, 记录文件属性:权限,时间还有最重要的block号码. block是实际存放文件内容的地方 ...

  9. Linux文件系统应用---系统数据备份和迁移(用户角度)

    1   前言 首先承诺:对于从Windows系统迁移过来的用户,困扰大家的  “Linux系统下是否可以把系统文件和用户文件分开到C盘和D盘中” 的问题也可以得到完满解决. 之前的文章对Linux的文 ...

随机推荐

  1. ManualResetEvent 用法

    第一.简单介绍 ManualResetEvent 允许线程通过发信号互相通信.通常,此通信涉及一个线程在其他线程进行之前必须完成的任务.当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时, ...

  2. Celery-4.1 用户指南: Extensions and Bootsteps (扩展和Bootsteps)

    自定义消息消费者 你可能想要嵌入自定义的 Kombu 消费者来手动处理你的消息. 为了达到这个目的,celery 提供了一个 ConsumerStep bootstep 类,你只需要定义 get_co ...

  3. 微信小程序的组件总结

    本文介绍微信小程序的组件 视图容器 基础内容 表单组件 导航组件 媒体组件 视图容器 view 布局容器 <view hover-class='bg'>222</view> 可 ...

  4. IOCP编程原理(转)

    在我的博客之前写了很多关于IOCP的“行云流水”似的看了让人发狂的文章,尤其是几篇关于 IOCP加线程池文章,更是让一些功力不够深厚的初学IOCP者,有种吐血的感觉.为了让大家能够立刻提升内力修为,并 ...

  5. 第九章 Java中线程池

    Java中的线程池是运用场景最多的并发框架,几乎所有需求异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 降低资源消耗:通过重复利用已创建的线程降低线程创建和 ...

  6. LNMP 1.1 php编译安装

    LNMP 是 Linux nginx mysql php  nginx和apache一样也是一种web服务.在静态web服务中nginx更胜一筹.在动态中不比apache有优势. LNMP的mysql ...

  7. DAY11-MYSQL索引原理与慢查询优化

    一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...

  8. hadoop再次集群搭建(3)-如何选择相应的hadoop版本

    之前接触过很多很多hadoop版本,现在重新搭建平台,面临选择哪个版本的问题. 当我们决定是否采用某个软件用于开源环境时,通常需要考虑以下几个因素: (1)是否为开源软件,即是否免费. (2) 是否有 ...

  9. Android中pull解析XML文件的简单使用

    首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐 ...

  10. java中一些常用的英语

     abstract (关键字  ) 抽象  ['.bstr.kt]  access vt.访问,存取  ['.kses]'(n.入口,使用权)  algorithm n.算法  ['.lg.rie ...