文件系统及fsck设计思路理解

文件系统及Fsck设计思路理解

魏星

Fsck是实现对文件系统的修复功能(fs check)。理解fsck需要掌握Linux文件系统设计原理、fsck设计原理和fsck实现的步骤。

一、Linux文件系统设计原理

1、文件系统基本概念

基本概念:super block、inode、目录文件、普通文件

a、super block

超级块存储文件系统的相关信息,包括文件系统的格式,inode/block的总数、使用量、剩余量等信息。没有superblock就没有这个filesystem了。

他主要记录的信息有:

.block与inode的总数;

.未使用与已使用的inode/blodk数量;

.block与inode的大小(block为1,2,4K,inode为128byte或者256byte);

.filessystem的挂载时间、最近一次写入数据的时间、最近一次检查磁盘(fsck)的时间等文件系统的相关信息;

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

格式化就是写super block的内容。Super block对文件系统太重要了,所以是有备份隐藏在系统中的,如果这个块坏了,可以用备份的块来恢复。

恢复办法见:

http://blog.chinaunix.net/uid-26557245-id-3748168.html

b、Inode

Inodes是实现文件系统存储的关键。在Linux系统中,一个文件可以分成几个数据块存储,就好像是分散在各地的龙珠一样。为了顺利的收齐龙珠,我们需要一个“雷达”来指引,这个“雷达”就是inode。每个文件对应一个inode,每个inode中包含多个指针,指向属于该文件各个数据块。当操作系统需要读取文件时,只需要对应inode的“地图”,收集起分散的数据块,就得到文件了。数据块才是正真存储文件的地方。

文件是文件系统对数据的分割单元。文件系统用目录来组织文件,赋予文件以上下分级的结构。在硬盘上实现这一分级结构的关键是使用inode来虚拟普通文件和目录文件对象。

在Linux文件管理中除了自身的数据,还有一个附属信息,即文件的元数据(metadata)。这个元数据用于记录文件的许多信息,比如文件大小、拥有人、所属的组、创建日期、修改日期等。元数据并不包含在文件的数据中,而是由操作系统维护的,元数据包含在inode中。

当Linux想要打开一个文件时,只需要找到文件对应的inode,然后沿着指针,将所有的数据块收集起来,就可以在内存中组成一个文件的数据。

Inode包含文件的元信息,具体如下:

*文件的字节数

*文件拥有者的User ID

*文件的Group ID

*文件的读、写、执行权限

*文件的时间戳,共有三个:ctime指inode创建时间,mtime指文件内容修改时间,atime指文件访问时间。

*链接数即多少文件名指向该inode

*文件数据block的位置

Inode的特色:

每个inode大小是固定的 128字节或者256字节

每个档案都仅会占用一个inode而已

因此文件系统能够建立的档案数量与inode的数量有关

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

Inode的结构示意图

上图inode有128bytes,这样子inode能够指定多少个block呢?我们以较小的1Kblock来说明吧!

.12个直接指向:12*1K=12K

.间接:1256*1K=256K

每笔block号码的记录会花掉4bytes,因此1K的大小能够记录256笔记录

.双间接:256*256*1K

.三间接:256*256*256*1K

总额:将直接、间接、双间接、三间接相加。最大一个文件16G。

每个inode节点的大小,一般是128字节或者256字节。Inode节点的总数在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假设在一个块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整个块硬盘的12.8%。

[email protected]:/$ sudo dumpe2fs -h /dev/sdb |grep "Inode size"

[sudo] password for ubuntu:

dumpe2fs 1.41.14 (22-Dec-2010)

Inode size:          256

这就是为什么格式化以后每个盘能够存储的容量只能占整个设备80%的原因

c、目录文件

目录文件存储了一张表,该表就是该目录文件下,所有文件名和inode的映射关系。

从父亲目录中获得本文件的inode号--->找到inode-table表中找到这个inode号对应的数据域中的起点以及其他信息--->去这个数据域中读取该文件的内容(普通文件的内容是字符串,目录文件的内容是一张表)

Linux系统文件名最多127byte,那就是说这里定义的是128byte

d、普通文件

普通文件存储的是用户存储的数据内容啦!搞了半天就是为了存它嘛

2、文件系统的访问模型

文件text.txt的访问模型

在设备中实际存储为:

二、FSCK设计原理

1、Super block checking

在一个文件系统中最经常corrupt掉的是super block中的汇总信息。原因是这些信息在文件系统的block或者inode的每项改动,都需要在汇总信息中做相应的修改。因此,经常会corrupt(汇总信息与实际的文件系统信息不一致)。

Super block的一致性检查包括文件系统大小,inode数量,空闲的block块,空闲的inode数量等。文件系统的大小必须大于super block和inode使用的block数的和。文件系统的大小和布局信息是对fsck而言至关重要的信息。但并没有一种可以实际检查这些大小,因为他们是由newfs静态决定的,fsck可以检查这些大小在一个合理的范围之内。如果fsck在默认的super block中的静态的参数中检查到corrupt,它就会要求提供备用的super block所存放的地址。

2、Free block checking

Fsck会检查所有在cylinder group blocks maps(注:cylinder group即对应于fs的partions)中标记为free的块,即没有被文件占用的块。Fsck会检查free的块的数量与inode中声明使用的块的数量的和是否与整个文件系统的所有块数相等。

如果在block allocation maps中有任何错误,fsck将根据其计算的allocated blocks进行重新组建block allocation maps。

Super block中冶存有所有free块的数量信息,fsck会把自己检查的结果与super block中的信息进行比较,如果这两个数不等,则fsck会将检查得到的结果更新到super block中。

对文件系统中free inode的处理同上

3、Checking the inode state

当文件系统中有很多inode存在的时候(即很多文件),有可能会有几个inode corrupt。文件系统中的inode链表是从inode2开始顺序检查的(inode0标记没有用过的inode,inode1用来将来的扩展),直到文件系统中的最后一个inode。Inode的状态检查包括:format and type,link count,duplicated blocks,bad blocks,and inode size。

每个inode都有一个mode word,它描述了inode的type和state。Inode必须处于六种类型之一:普通inode,目录inode,symbollink inode,special block inode,special character inode,或者是socket inode。

Inode有三种allocation状态:unallocated,allocated和不属于前两种情况的情况。在第三种状态的inode就是不正确的inode,当inodes链表被写入坏的数据的时候,inode有可能进入这种状态。唯一可能修复的方法是fsck晴空这个inode(在链表中删除之)。

4、inode Links

连接数是计算每一个inode与其相连的目录项的数目。Fsck从文件系统的root目录开始检查每一个inode的连接数,并沿着目录树依次查找。每个inode的实际link count在遍历的时候计算得到。如果存储的link count非0,而计算的link count为0,则此inode没有对应的目录项。这种情况下,fsck将把这个对应的文件放入lost+found目录中。如果存储的link count与实际计算所得的值非0且不相等,那么可能是inode的link count在有一个目录加入或者删除的时候没有被响应更新。这种情况下,fsck会用计算得到的值更新存储的值。

每个inode都包含一个列表或者是列表的指针,上面记录着这个inode所使用的数据块。因为inode是这些列表,因此,当这些列表存在不一致的情况时,就直接影响到拥有它的inode。

Fsck会将一个inode声明的block number与列表中已经分配的block number比较。如果另一个inode已经声明了一个block number,那么这个block number就被加入到一个duplicate block链表中。否则,已分配的block list中会将这个block number加入。

对任何duplicate blocks,fsck将会遍历inode list找到拥有duplicated block的inode。一般而言,拥有最早修改时间的inode坏掉的可能性比较大,需要被clear。如果是这种情况,fsck将执行操作,clear这两个inodes。操作必须决定,哪个该留,哪个该clear。

Fsck检查每个inode声明的block number的范围,如果block number比文件系统中第一个数据块的块号低,或者比文件系统中的最后一个数据块的块号大,则称为bad block number。一个inode中许多的bad blocks经常是由于一个indirect block没有被写入到文件系统中,发生这种情况的前提是由于硬件异常的产生。如果一个inode含有bad block numbers,fsck会将其clear。

5、node data size

每个inode包含一定数量的data blocks。实际data block的数量是所有allocated data blocks和indirect blocks的总和。Fsck计算实际的data blocks的数量,并与inode 所记录的数值进行比较。如果两者不一致,fsck会进行修正。

每个inode包含了一个32位的size域。这个数是inode对应的文件所包含有的字节数。这个size域的一致性检查是通过计算与inode对应的最大数量的blocks数,与实际inode保存的数值比较。

6、Checking the data with an inode

一个inode可以直接或者间接的reference三种类型的data blocks。所有的referenced blocks必须是同种类型。这三种类型是:plain data blocks,symbolic link data blocks和 directory data blocks。Plain datablocks包含文件中保存的信息。Symbolic link data blocks包含一个link中包含的路径名。Directory data blocks包含目录项。Fsck只能检查directory data blocks的有效性。

Fsck会检查每个directory data block的几种一致性:directory inode指向unallocated inodes,directory inodes的数量比文件系统中的inode数量大,不正确的”.””..”directory inode numbers,没有结合在文件系统中的directories。如果一个directory data block中的inode number references一个unallocated inode,fsck将移除这个directory entry(目录项)。这种情况只发生在存在硬件异常的情况下。

三、Fsck实现步骤

Fsck由5个阶段完成

1、阶段1:检查块和大小消息

此阶段检查inode列表。它会报告在以下情况遇到的错误状态:

.检查inode类型

.设置零链接计数表

.检查坏块或重复块的inode块编号

.检查inode大小

.检查inode格式

2、阶段1B:重新扫描更多DUPS消息

在文件系统中发现重复块时,将重新扫描文件系统,以查找以前请求过该块的inode。

3、阶段2:检查路径名消息

此阶段将删除指向阶段1和1B所找到的坏inode的目录项。它将报告下列原因所导致的错误状态:

.不正确的根inode模式和状态

.目录inode指针超出范围

.目录项指向坏inode

.目录完整性检查

4、阶段3:检查目录链接

此阶段将检查在阶段2中检查的目录,并报告以下原因所导致的错误状态:

.非引用目录

.缺失的或完整的lost+found目录

5、阶段4:检查引用计数消息

此阶段将检查在阶段2和3中获得的链接计数信息。它将报告下列原因所导致的错误状态:

.非引用文件

.缺失的或完整的lost+found目录

.文件、目录、符号链接或特殊文件的链接计数不正确

.非引用文件、符号链接和目录

.文件和目录中存在坏片段或重复片段

.可用inode总计数不正确

6、阶段5:检查柱面组信息

此阶段将检查可用片段和已用inode图。它将报告下列原因导致的错误状态:

.已用inode图中缺少已分配inode

.可用片段图中缺少可用片段

.已用inode图中有可用inode

.可用片段总计数不正确

.已用inode总计数不正确

四、文件系统破坏的原因

导致一个文件系统corrupt的原因有可能有几种,而最经常的就是非正常关机流程和硬件的错误造成的。

造成corrupt的主要原因就是在停止CPU之前没有同步系统数据。如果非正常的启动没有被检测到,比如没有检查文件系统的一致性,没有恢复不一致的数据,允许使用一个corrupt的文件系统监视一种灾难。另外,一部分硬件有可能在任何时候出错,如在磁盘上的一个坏的块,或者是磁盘控制器没有响应等。

对于corrupt文件系统建议马上修护,否则后面修复越来越难阶段1B

五、解决文件系统破坏的办法

1、设备的拔出保护

设备的拔出,必须要先点击,确认才可以拔出

2、从硬件上解决

硬件解决需要提供UPS或者可充电电池,让设备一直处于工作状态;设备电源是带大电容延迟电源+断电侦测。一旦监测到断电,系统马上停止write文件系统,马上flush设备。

3、从系统软件上解决

系统通过测试,如果CPU使用率超过95%则马上降低系统负载或者直接停止部分不重要的写动作

4、从驱动层面解决

硬件增加一个可以写的、高速的耐写设备(容量很小、很贵),每次把修改制定文件map的数据先写入这个文件,然后更新文件系统,文件系统更新完成再清除这个设备的标准。文件系统每次读都要先判断是用那个地方数据是最新的。这种办法有点笨,一般只有芯片厂商修改文件系统来实现。

时间: 2024-10-19 01:11:28

文件系统及fsck设计思路理解的相关文章

角色与角色拥有哪些权限功能的设计思路理解

我们直接看图. 这只是一种设计方式,当然如果有更好的,可以自己去实现.

对RESTful Web API的理解与设计思路

距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很稳定了,所以我打算写篇总结,并在最近这段时间里提供一个ASP.net Web API的综合例子. 对四个HTTP方法的理解 众所周知,HTTP有四个方法,GET.POST.PUT和DELETE,分别对应数据库的SELECT.INSERT.UPDATE和DELETE,一般的教程说到这里也就Over了,

[三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路

Stream的概念定义   官方文档是永远的圣经~ 表格内容来自https://docs.oracle.com/javase/8/docs/api/   Package java.util.stream  一节部分原文内容的翻译 int sum = widgets.stream() .filter(b -> b.getColor() == RED) .mapToInt(b -> b.getWeight()) .sum(); 流操作被划分为中间和终端操作,并组合成流管道. 一条Stream管道由

地铁规划项目需求理解和设计思路

地铁规划项目需求理解和设计思路 需求理解 将地铁线路保存成一个可读入,简洁明了的文本 程序能正确读入这个文件,并获取地铁线路信息 程序能正确处理输入的命令行 地铁能正确输出指定地铁线经过的站点 程序能正确输出两个站点间的最短路径 程序要有健壮性,能通过各类性能测试 按要求编写博客,详细说明花费时间,代码,各个模块和测试用例 设计思路 文本格式 1号线 刘园 西横堤 果酒厂 本溪路 勤俭道..... 2号线 曹庄 卞兴 荠园西道 咸阳路...... 3号线 小淀 丰产河 华北集团...... 按照

OpenStack 通用设计思路 - 每天5分钟玩转 OpenStack(25)

API 前端服务 每个 OpenStack 组件可能包含若干子服务,其中必定有一个 API 服务负责接收客户请求. 以 Nova 为例,nova-api 作为 Nova 组件对外的唯一窗口,向客户暴露 Nova 能够提供的功能. 当客户需要执行虚机相关的操作,能且只能向 nova-api 发送 REST 请求. 这里的客户包括终端用户.命令行和 OpenStack 其他组件. 设计 API 前端服务的好处在于: 1. 对外提供统一接口,隐藏实现细节 2. API 提供 REST 标准调用服务,便

Backbone设计思路和关键源码分析

一. Backbone的江湖地位: backbone作为一个老牌js框架为大规模前端开发提供了新的开发思路:前端MVC模式,这个模式也是前端开发演变过程中的一个重要里程碑,也为MVVM和Redux等开发思路奠定了夯实的基础,后来的react,vue无不是在backbone的影响下开创出来的经典模式.为什么这么说呢?我们先来回顾下Web前端开发的大概演变流程,本过程纯粹个人理解,抛砖引玉,共同探讨,如有偏差请看官指出错误: 1. 无前端:最早的网页就是HTML,还只是静态页面,当时的脚本含量极少甚

跟张小龙学习做优秀产品经理的设计思路

提起张小龙,大家都非常熟悉这位极度优秀的产品经理,不仅仅是因为Foxmail,更因为目前深刻改变你我移动生活的移动互联网产品 - 微信,其江湖地位的确定已经让众多国内立志于做优秀产品经理的人顶礼膜拜了,我们首先借助互联网材料回顾一下微信的创立历程: 一.微信的演化历程: 2010年11月19日23时58分,张小龙在腾讯微博上写下了这么一句话: 我对iPhone5的唯一期待是,像iPad(3G)一样,不支持电话功能.这样,我少了电话费,但你可以用kik跟我短信,用googlevoice跟我通话,用

【4】JVM-GC设计思路分析

Java中将内存的控制交给JVM来实现,方便了JAVA程序猿,当然牺牲了一部分效率,不过总体来看是值得的.那么JVM中是如何设计GC的呢,本文从几个问题入手,然后分析了一下设计思路,如果有理解错误的地方,请批评指正!主要参考了<深入理解JAVA虚拟机>这本书,图是盗来的,图的内容和书上一样. 在JVM的内存模型中,堆内存是JAVA内存区域中最大的一部分,GC主要就是发生在堆中,用来回收那些无用的对象.这样直接就引申出了第一个问题:什么样的对象需要被回收?判断条件是什么?如何判断? 先谈谈什么对

(转)OAuth 2.0的设计思路

OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为RFC 6749. 原文地址:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 一.应用场景 为了理解OAuth的适用场合,让我举一个假设的例子. 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.用户为了使用该服