文件系统的运作与操作系统的文件数据有关。较新的操作系统的文件数据除了文件实际内容外,通常含有非常多的属性,例如Linux操作系统的文件权限(rwx)与文件属性(属主、属组、时间参数等)。文件系统通常会将这两部分数据存放在不同的区块,权限与属性放置到inode 中,实际数据则放置到data block 中。还有一个超级区块(superblock) 会记录整个文件系统的整体信息,包括inode与block 的总量、使用量、剩余量等。

由于每个inode与block都有编号,而每个文件都会占用一个inode,inode内则存有文件数据放置的block号码,因此,如果能够找到文件的inode,自然就能知道这个文件放置数据的block 号码,当然就能读取该文件的实际数据了。这种数据存取方法称为索引式文件系统(indexed allocation)。

Ext2就是索引式文件系统。

文件系统一开始就将inode与block规划好了,除非重新格式化(或利用resize2fs等指令变更文件系统大小),否则inode 与block 固定后就不再变动。

data block:

data block 是用来放置文件内容数据的,在Ext2 文件系统中所支持的block 大小有1K,2K,4K 三种。在格式化时block 的大小就固定了,而且每个block 都有编号,以便inode 记录。由于block 大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。

每个block 内最多只能放置一个文件的数据。

如果文件大于block 的大小,则一个文件会占用多个block。

如果文件小于block,则该block 的剩余容量就不能再存放其他文件。

至于到底该选择多大的block,师实际情况而定。

inode table:

inode 记录的文件数据至少有以下这些:

  该文件的存取模式(read/write/excute)

  该文件的属主与属组(owner/group)

  该文件的容量

  该文件创建或状态改变的时间(ctime)

  最近一次的读取时间(atime)

  最近一次的修改时间(mtime)

  定义文件特性的flag,比如SetUID

  该文件真正内容的指向(pointer)

inode 的数量与大小也在格式化时就固定了,

  每个inode 大小均固定为128bytes(ext4 可设为256bytes)

  每个文件只占用一个inode,因此文件系统能够建立的文件数量与inode数量有关

  系统读取文件时,需要先找到inode,并分析inode 所记录的权限与用户是否符合,若符合才能够开始实际读取block 的内容。

Ext2 的inode/block 与文件大小的关系:

一个inode 大小为128bytes,而inode 记录一个block 号码要花掉4bytes。这时采取的策略是定义12个直接,一个间接,一个双间接,一个三间接记录区。

superblock:

记录的信息主要有以下这些:

  block 与inode 的总量

  未使用与已使用的inode/block 数量

  block 与 inode 的大小(block 为1,2,4K,inode 为128,256bytes)

  filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘的时间等文件系统的相关信息。

  一个valid bit 数值,若此文件系统已被挂载,则valid bit 为0,若未被挂载,则valid bit 为1。

  superblock 的大小为1024bytes。

dumpe2fs: 查询Ext 家族superblock 信息的指令

df 与dumpe2fs 配合使用

输出的部分结果:

Group 0: (Blocks 0-32767) # 第一块 block group 位置
    Checksum 0x13be, unused inodes 8181
    Primary superblock at 0, Group descriptors at 1-1 # 主要 superblock 的所在喔!
    Reserved GDT blocks at 2-128
    Block bitmap at 129 (+129), Inode bitmap at 145 (+145)
    Inode table at 161-672 (+161) # inode table 的所在喔!
    28521 free blocks, 8181 free inodes, 2 directories, 8181 unused inodes
    Free blocks: 142-144, 153-160, 4258-32767 # 底下两行说明剩余的容量有多少
    Free inodes: 12-8192

文件系统与目录树的关系

目录:

当在Linux下的文件系统创建一个目录时,文件系统会分配一个inode 与至少一块block 给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块block 号码;而block 则是记录在这个目录下的文件名与该文件名占用的inode 号码数据。

查看某目录内的文件所占用的inode 号码

ls -i

执行 ll / 命令,出现的目录几乎都是1024的整倍数,这还是与block的单位大小有关。

dr-xr-xr-x 253 root root           0 3月  20 09:42 proc/  # /proc 不占用磁盘容量,所以为0.

文件:

假设一个block 为4K,那么创建一个100K 的文件,除了分配一个inode 与25个block 来存储该文件外,还需要多一个block 来作为区块号码的记录(因为一个inode 仅有12个直接指向)

目录树读取:

inode 本身并不记录文件名,文件名的记录是在目录的block中。因此当我们要读取某个文件时,就会经过目录的inode 与block,然后才能找到那个待读取文件的inode 号码,最终才会读到文件的block 数据。

由于目录树是由根目录开始读起,因此系统通过挂载的信息可以找到挂载点的inode 号码,此时就能够得到根目录的inode 内容,并依据该inode 读取根目录的block 内的文件名数据,再一层一层往下读到正确的文件名。

以读取 /etc/passwd中的内容为例:

创建文件时文件系统的行为:

  1). 先确定用户对于欲新增文件的目录是否具有w 和x 权限,若有的话才能新增

  2). 根据inode bitmap 找到没有使用的inode 号码,并将新文件的权限/属性写入。

  3). 根据block bitmap 找到没有使用的block 号码,并将实际的数据写入block 中,且更新inode 的block 指向数据。

  4). 将刚刚写入的inode 与block 数据同步更新inode bitmap 与block bitmap,并更新superblock 的内容。

一般将inode table 与data table 称为数据存放区域,superblock、block bitmap、inode bitmap 称为metadata。

数据不一致状态:

一般情况下,上述新增动作可以顺利完成。但也有万一,例如在文件写入文件系统时,因为突然断电、系统核心发生错误等原因导致系统中断,所以写入的数据仅有inode table 及data block,而最后一个同步更新步骤没有完成,就会发生metadata 的内容与实际数据存放区产生不一致。

在早起的Ext2 文件系统中,如果发生数据不一致问题,那么系统在重新启动时,就会藉由superblock 中记录的valid bit(是否有挂载) 与filesystem state(clearn 与否)等状态来判断是否强制进行数据一致性检查。这个过程是很费时的。这就催生了日志式文件系统(Journaling filesystem)。

日志式文件系统:

在文件系统中另开辟一个区块,专门记录写入或修改时的步骤。

  1). 预备:当系统要写入一个文件时,会先在日志记录区块中记录某个文件准备要写入的信息;

  2). 实际写入:开始写入文件的权限与数据;更新metadata 的数据;

  3. 结束:完成数据与metadata 的更新后,在日志记录区块中完成该文件的记录。

这样,在数据出现问题时,只要去检查日志记录区块,就可以知道哪个文件发生了问题,然后针对该问题做一致性检查即可,速度大大加快。

Ext3、Ext4就是日志式文件系统。通过dumpe2fs 可以看到superblock 里面含有下面的信息:

通过inode 8 记录journal 区块的block 指向,而且有8MB 的容量在处理日志。

磁盘写入的速度比内存慢得多,这会影响读写效率。为了解决这个问题,Linux有一个异步处理的方式。

当系统加载一个文件到内存后,如果该文件没有被更动过,则在内存区段的文件数据会被设定为干净的(clean)的。如果内存中文件数据被更动了,内存中的数据就会被设定为脏的(dirty),此时所有的动作都还在内存中,并没有写入磁盘,系统会不定时地将内存中设定为dirty的数据写回磁盘,以保持磁盘与内存数据的一致性。可以利用sync 指令来手动写入磁盘。

若正常关机,关机指令会主动调用sync 来将内存中的数据回写到磁盘。

每个filesystem 都有独立的inode/ block/ superblock 等信息,这个文件系统要能够链接到目录树才能被使用。将文件系统与目录树结合的动作称为挂载。挂载点一定是目录,该目录是进入该文件系统的入口。

查看系统支持哪些文件系统:

$ ls -l /lib/modules/$(uname -r)/kernel/fs

查看系统目前已加载到内存中文件系统:

$ cat /proc/filesystems

Linux 通过一个名叫Virtual Filesystem Switch(VFS) 的核心功能去管理filesystem。

Linux filesystem的更多相关文章

  1. 转载--linux filesystem structures

    In this article, let us review the Linux filesystem structures and understand the meaning of individ ...

  2. buildroot linux filesystem 初探

    /****************************************************************************** * buildroot linux fi ...

  3. RH033读书笔记(15)-Lab 16 The Linux Filesystem

    Lab 16 The Linux Filesystem Goal: Develop a better understanding of Linux filesystem essentials incl ...

  4. Linux & Filesystem Hierarchy Standard

    Linux & Filesystem Hierarchy Standard The Filesystem Hierarchy Standard of Linux https://zhuanla ...

  5. Linux filesystem structures.

    1. / – Root Every single file and directory starts from the root directory. Only root user has write ...

  6. Linux filesystem detection

    16 down vote accepted The reason you can't find it is because, for the most part, it's not in the ke ...

  7. Linux 基础

    命令说明 $ type cmd # 获取命令类型 $ which cmd # 命令的位置 $ help cmd / cmd --help / man cmd # 获取命令帮助 $ whatis cmd ...

  8. Oracle Linux 5.7安装VMware Tools的问题

    案例环境介绍:     虚拟机的版本:VMware® Workstation 8.0.3 build-703057    操作系统版本:Oracle Linux Server release 5.7 ...

  9. Linux File Recovery Study

    Background Today I did stupid things that I went into the ~/Downloads/ and pressed [Alt] + [A] then ...

随机推荐

  1. 使用HttpClient和WebRequest时POST一个对象的写法

    [一]步骤: 1)将对象转化为Json字符串. 2)将Json字符串编码为byte数组. 3)设置传输对象(WebRequest或者HttpClient)的ContentType是"appl ...

  2. Centos 05 系统目录讲解

    本节内容 1.linux目录结构 2.主目录功能简介 3.重要子目录 linux目录结构 在linux里面,逻辑上所有目录只有一个顶点,根是所有目录的起点. 根下面是类似一个倒挂的树一样的层次结构 可 ...

  3. LeetCode第十一题-可以装最多水的容器

    Container With Most Water 问题简介:通过一个给定数组,找出最大的矩形面积 问题详解:给定一个数组,包含n个非负整数a1,a2,…,an,其中每个表示坐标(i,ai)处的点,绘 ...

  4. shiro执行原理

    一.架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精妙.Shiro的应用不依赖任何容器,它也可以在JavaSE下使用.但是最常用的环境还是JavaEE.下面以 ...

  5. Copley-STM32串口+CANopen实现双电机力矩同步

    原来有个CANopen的主站卡,现在没了,只有单片机,用单片机来制作一个CANopen的主站卡貌似不是很难,但是需要时间.无奈仔细看了一个Copley的说明,决定采用CAN口+串口来实现之前的功能. ...

  6. linux软件管理

    People who cannot find time for recreation are obliged sooner or later to find time for illness.腾不出时 ...

  7. sort排序用法

    Python] sorted函数 我们需要对List.Dict进行排序,Python提供了两个方法对给定的List L进行排序,方法1.用List的成员函数sort进行排序,在本地进行排序,不返回副本 ...

  8. 这篇文章主要介绍了Citrix XenServer 6.1 安装图解教程

    本次为使用VirtualBox虚拟机过安装测试机过程,我们在使用Vm(无论是Vbox还是VMware等)我们的CPU都必须可支持Intel-V或AMD-V,并且在VM软件设置和BIOS设置开启虚拟化支 ...

  9. Hadoop| YARN| 计数器| 压缩| 调优

    1. 计数器应用 2. 数据清洗(ETL) 在运行核心业务MapReduce程序之前,往往要先对数据进行清洗,清理掉不符合用户要求的数据.清理的过程往往只需要运行Mapper程序,不需要运行Reduc ...

  10. Django 学习第十一天——中间键和上下文处理器

    一.中间键的引入: Django中间件(Middleware)是一个轻量级.底层的"插件"系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出. djang ...