linux内核探秘4---文件系统(最简单的文件系统aufs)

本文主要介绍了Linux内核中的文件系统,特别是aufs文件系统的概念和操作,包括基本概念如超级块、inode、file_operations、dentry等,以及文件系统的安装和创建过程。通过对aufs文件系统的实例分析,阐述了如何通过mount机制将文件系统挂载到Linux的虚拟文件系统中,并探讨了文件和目录的创建。此外,还讨论了如何通过get_sb()函数获取和创建超级块,以及创建文件时的dentry和inode操作。
摘要由CSDN通过智能技术生成

最近一周报名的内核课程讲到了文件系统这一章,老师布置了2个作业:

1.复习文件系统中超级块的创建过程

2.复习文件系统中文件的创建过程

 

老师给了一个最简单的aufs文件系统的例子,里面注册了aufs, 然后调用kern_mount对文件系统进行挂载,然后创建了1个目录,3个文件,总体来说实现了最简单的

文件系统的功能,作业主要是为了熟悉超级块的创建(这也涉及到了mount的过程), 文件的创建(了解inode和dentry).

 

在做作业之前,先把课程视频学习了,然后网上找资料学习,这篇文章主要是根据网上的几篇比较牛的文章进行了整合,有些也是直接搬过来了,整合之后的过程更加清楚。

在基础知识之后,我也贴出了作业代码流程,有些代码还没怎么看懂(所以注释还没写)。。等我请教了别人之后,再来添加。

 

一、基本概念

1.一块磁盘(块设备),首先要按照某种文件系统(如 NTFS)格式进行格式化,然后才能在其上进行创建目录、保存文件等操作。在 Linux 中,有“安装(mount)”文件系统和“卸载(unmount)”文件系统的概念。一块经过格式化的“块设备”(不管是刚刚格式化完的,没有创建任何名录和文件;还是已经创建了目录和文件),只有先被“安装”,才能融入 Linux 的文件系统中,用户才可以在它上面进行正常的文件操作。

 

2.  Linux 把目录或普通文件,统一看成“目录节点”。通常一个“目录节点”具有两个重要属性:名称以及磁盘上实际对应的数据。“符号链接”是一种特殊的目录节点,它只有一个名称,没有实际数据。这个名称指向一个实际的目录节点。

 

3.“接口结构”:在 内核代码中,经常可以看到一种结构,其成员全部是函数指针,例如:

struct file_operations {

  struct module *owner;

  loff_t (*llseek) (struct file *, loff_t, int);

  ssize_t (*read) (struct file *, char *, size_t, loff_t *);

  ssize_t (*write) (struct file *, const char *, size_t, loff_t *);

  int (*readdir) (struct file *, void *, filldir_t);

  unsigned int (*poll) (struct file *, struct poll_table_struct *);

  int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

  int (*mmap) (struct file *, struct vm_area_struct *);

  int (*open) (struct inode *, struct file *);

  int (*flush) (struct file *);

  int (*release) (struct inode *, struct file *);

  int (*fsync) (struct file *, struct dentry *, int datasync);

  int (*fasync) (int, struct file *, int);

  int (*lock) (struct file *, int, struct file_lock *);

  ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);

  ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);

  ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

  unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

};

 

 

 

4. 虚拟文件系统

Linux 通过虚拟文件系统 (VFS) 来支持不同的具体的文件系统,那么 VFS 到底是什么?

从程序员的角度看,VFS 就是一套代码框架(framework),它将用户与具体的文件系统隔离开来,使得用户能够通过这套框架,以统一的接口在不同的具体的文件系统上进行操作。

这套框架包括:

l 为用户提供统一的文件和目录的操作接口,如  open, read, write

l 抽象出文件系统共有的一些结构,包括“目录节点”inode、“超级块”super_block 等。

l 面向具体的文件系统,定义一系列统一的操作“接口”, 如 file_operations, inode_operations, dentry_operation,具体的文件系统必须提供它们的实现。

l 提供一套机制,让具体的文件系统融入 VFS 框架中,包括文件系统的“注册”和“安装”

l 实现这套框架逻辑的核心代码 

 

 

 

二、核心数据结构

1.inode 和 file_operations

先看一下文件在内存和磁盘上是如何描述的?每个文件至少有一个数据结构存放该文件的信息,例如大小,创建时间,修改时间、uidgid 等,这个数据结构就是inode.

l inode 描述了一个目录节点物理上的属性.

l 本来inode中应该包含文件名称等信息,但是由于符号链接的存在,导致一个文件可能存在多个文件名称,所以把和文件名称相关的信息从inode中隔离出来,放入另外一个数据结构中dentry,由dentry结构中的d_inode指向对应的inode(所以寻找inode的过程实际上就是寻找dentry的过程)所以一个文件可以有两个数据结构表示inodedentry.

l 对于文件的操作,通过inode中的i_fop来指向file_operations(上面的一个数据结构)中的操作,不同的文件系统会实现具体的细节。

 

2. 目录节点入口(根据路径名寻找目标文件--简单版)

Linux中目录也被作为文件看待,只是目录是一种比较特殊的文件。其特殊之处在于文件的内容是该目录中文件和子目录的dentry的描述符,通过这些dentry的描述符可以找到文件或子目录的dentry,进而找到相应的inode

目录内容(文件和子目录dentry的描述符)---》文件或目录的dentry--->inode(文件信息)

下面我们看看如果根据绝对路径寻找一个文件/tmp/temp/abc的:

l 首先找到根文件系统的根目录文件(/)的 dentry 和 inode

l 由这个 inode 提供的操作接口 i_op->lookup(),找到下一层节点tmp的 dentry 和 inode

l 由 ‘tmp’ 的 inode 找到 ‘temp’ 的 dentry 和 inode

l 最后由 ‘temp’ 的 inode 找到 ‘abc’ 的 dentry 和 inode

 

通过相对路径找到文件/tmp/temp/abc的过程:

假如我们目前的工作目录为/tmp/temp/dir_a 中,比如我们通过拷贝命令拷贝该文件:cp ../abc ./ 如何通过相对路径寻找文件呢?

dentry这个数据结构的成员,其中有一个是d_parent,数据结构定义如下

struct dentry { 删除了无关的成员

struct dentry *d_parent; /* parent directory */

struct inode *d_inode; /* Where the name belongs to - NULL is * negative */

unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */

 

}

d_parent指向了本目录的父目录的dentry,这样就在通过“..”时就是通过该指针找到的父目录dentry,找到父目录inode,进而找到父目录下的所有文件的信息。

 

Dentry , inode,和文件操作file_operations的关系:

 

 

 

3. Super_blocksuper_operations

一个存放在磁盘上的文件系统如 EXT2 等,在它的格式中通常包括一个“超级块”或者“控制块”的部分,用于从整体上描述文件系统,例如文件系统的大小、是否可读可写等等。

虚拟文件系统VFS中也通过“超级块”这种概念来描述文件系统整体的信息,对应的结构是 struct super_blocksuper_block 除了要记录文件大小、访问权限等信息外,更重要的是提供一个操作“接口”super_operations

 

struct super_operations {

            struct inode *(*alloc_inode)(struct super_block *sb);
            void (*destroy_in

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值