程序员福利:掀开裙子看真相之linux文件系统

 

今日头号头条号合作平台编码之妙特稿

 

编码之妙2016-09-12 11:26

 

 

投票进进入今日头条合作页面
http://toutiao.com/i6329280691225756161/

前天,在掀开裙子看真相系列中提出一个观点,世界上最好的程序员是C语言程序员,结果,java和php程序员都非常愤怒,纷纷在评论区给小编留言,说不对,世界上最好的程序员应该是C++程序员。程序员福利:掀开裙子看真相之linux文件系统

我问了几位老C++程序员,结果他们催头丧气,说:“用了十几年C++,还不敢说会”。

老c++程序员说,C是c++的一个子集,好的c++程序员都看过kernel的代码,linux kernel虽然是用c写的,但是在设计上,其实运用了很多c++的知识点,如果没有c++的功底,是很难看通kernel的源码的。

小编吓傻了。程序员福利:掀开裙子看真相之linux文件系统

那么,在本文最后,各位看客自己投标吧,看看谁是最好的程序员。

文件系统是程序员必知必会的一个知识点,如果你不想知道,也不影响你的编程生涯,只不过,当一些错误发生时,你会觉得莫名其妙,而另一些有linuxkkernel 功底的程序员则心中有底。

程序员福利:掀开裙子看真相之linux文件系统

本文介绍L i n u x内核是如何维护它支持的文件系统中的文件的,我们先介绍V F S ( Vi r t u a lFile System,虚拟文件系统),再解释一下L i n u x内核的真实文件系统是如何得到支持的。L i n u x的一个最重要特点就是它支持许多不同的文件系统。这使L i n u x非常灵活,能够与许多其他的操作系统共存。在写这本书的时候, L i n u x共支持1 5种文件系统: e x t、e x t 2、x i a、m i n i x、u m s d o s、msdos 、v f a t、p r o c、s m b、n c p、i s o 9 6 6 0、s y s v、h p f s、a ffs 和u f s。无疑着时间的推移, L i n u x支持的文件系统数还会增加。

L i n u x像U N I X一样,系统可用的独立文件系统不是通过设备标识来访问的,而是把它们链接到一个单独的树形层次结构中。该树形层次结构把文件系统表示成一个整个的独立实体。L i n u x以装配的形式把每个新的文件系统加入到这个单独的文件系统树中。无论什么类型的文件系统,都被装配到某个目录上,由被装配的文件系统的文件覆盖该目录原有的内容。该个目录被称为装配目录或装配点。在文件系统卸载时,装配目录中原有的文件才会显露出来。在硬盘初始化时,硬盘上的分区结构把物理硬盘化分成若干个逻辑分区。每个分区可以包含一个像E X T 2那样的一个独立的文件系统。文件系统用目录将文件按照逻辑层次结构组织起来。目录是记录在物理设备块中的软链接信息。包含文件系统的设备被称为块设备。程序员福利:掀开裙子看真相之linux文件系统

I D E硬盘分区/ d e v / h d a 1—系统中第一个I D E硬盘驱动器的第一个分区,就是一个块设备。L i n u x文件系统把这些块设备当作简单的线性块的集合,它不知道也不在意下层物理硬盘的实际结构。每个块设备驱动程序的任务就是把系统读该设备上某一块的请求映射成对本设备有意义的术语,如该块所在的磁道、扇区或柱面号。无论文件系统存在在何种设备上,它都可以按相同的方式进行操作。而且在使用文件系统时,由不同的硬件控制器控制的不同物理介质上的不同文件系统对系统用户是透明的。文件系统既可能在本地系统上的,也可能是通过网络链接装配的远程文件系统。

对文件进行操作的用户和程序都不需要知道/ C实际上是系统中第一个I D E硬盘上的一个装配了的V FAT文件系统,而/ E是指从I D E控制器的主I D E硬盘。即使第一个I D E控制器是P C I控制器,而第二个是同时还控制IDE 接口的C D R O M的I S A控制器,这也不会给系统造成任何不

便。我可以使用P P P网络协议和m o d e m拨号到我所在公司的局域网上。这时,可以把A l p h a

AXP Linux系统中的文件系统远程装配到/ m n t / r e m o t e目录上。

文件是数据的集合,如:本章的源文本文件就是一个叫做f i l e s y s t e m s . t e x的A S C I I码的文件。一个文件系统不仅包括该文件系统中所有文件的数据,还包括文件系统的结构信息。它记录下所有L i n u x用户和进程当作文件看待的信息、目录软链接信息以及文件保护信息等等。而且文件系统必需保证这些信息的安全性,因为操作系统的基本完整性就取决于它的文件系统。没有人会使用一个随机的丢失数据和文件的操作系统。

L i n u x支持的第一个文件系统是M I N I X文件系统,它对用户有很多限制并且性能比较差。M I N I X文件系统的文件名不能超过1 4个字符,最大文件长度是6 4 M字节。初看起来6 4 M字节好像足够大了,但现代的数据库系统需要更大的文件长度。第一个专门为L i n u x设计的文件系统是E X T (扩展文件系统),在1 9 9 2年4月设计完成并为L i n u x解决了大量的问题。但它在性能上仍有所欠缺。所以在1 9 9 3年设计了第二个扩展文件系统—E X T 2。本章主要介绍的就是这个文件系统。

在E X T文件系统加入到L i n u x中时, L i n u x系统发生了一个重大的发展。真实文件系统从操作系统中分离出来,而由一个接口层提供的真实文件系统的系统服务被称为虚拟文件系统( V F S )。V F S使得L i n u x可以支持许多种不同的文件系统,而这些文件系统都向V F S提供相同的软件接口。由于所有的L i n u x文件系统的细节都是由软件进行转换的,所有对L i n u x系统的其余部分和在系统中运行的程序来说这些文件系统是完全相同的。L i n u x的虚拟文件系统层使得你可以同时透明地装配很多不同的文件系统。

实现L i n u x虚拟文件系统要使得它对文件的访问要尽可能地快、尽可能地高效,而且一定要确保文件和数据的正确性。这两个要求彼此是不对称的。在每个文件系统被装配使用后,L i n u x的V F S会在内存中缓存来自于这些文件系统的信息。因此由于对文件或目录的创建、写、删除操作而改变了L i n u x缓存中的数据时,对文件系统的更新操作要格外小心。如果你能在运行的内核中看到文件系统的数据结构,就会看到那些文件系统读/写的数据块。代表被访问的文件和目录的数据结构可能被创建或删除,而设备驱动程序不停地工作,读取数据、保存数据。这些缓存中最重要的一个是缓冲区缓存,它把独立文件系统访问下层块设备的方法集成起来。每个被访问的块都被放到缓冲区缓存中,并根据它们的状态放在相应的队列中。缓冲区缓存不仅缓存数据缓冲区,它还有助于管理块设备驱动程序的异步接口。

展文件系统EXT2

E X T 2是为L i n u x设计的一个可扩展的高性能文件系统。它是目前为止L i n u x中最成功的文件系统,也是当前商业销售的L i n u x的基础。E X T 2与其他的许多文件系统一样都是建立在如下前提的基础上:文件中所有数据都记录在数据块中而且这些数据块的长度都是相同的。但由于在创建E X T 2文件系统时可以设定块的大小,所以不同的E X T 2文件系统块的长度可能不同。文件长度与块长度的整数倍对齐。如果块的长度是1 0 2 4字节,那么一个1 0 2 5字节的文件会占用两个1 0 2 4字节块。不幸的是这表示平均起来每个文件就要浪费半个块。在计算机领域,你通常要在C P U利用率和存储空间磁盘空间利用率之间作出折衷。这时L i n u x像大多数的操作系统一样,用降低磁盘利用率的办法来降低C P U的工作负荷。文件系统中并不是所有的块都有数据,有些块是用来记录描述文件系统结构信息的。E X T 2文件系统通过用i n o d e数据结构来表示系统中每个文件的方法来定义文件系统中的拓扑结构。i n o d e结构包括文件占用了哪些数据块、文件访问权限、文件的更改时间、文件类型等信息。E X T 2文件系统的每个文件都由一个i n o d e来表示,而每个i n o d e节点在系统中都有一个唯一标识号。文件系统的所有i n o d e节点都被记录在i n o d e表中。E X T 2目录只是一种特殊的文件,它包含指向目录中所有对象的i n o d e节点的指针。

虚拟文件系统

图1 – 7 – 4给出了L i n u x内核的虚拟文件系统与它的真实文件系统之间的关系。虚拟文件系统要管理在任何时间装配的所有不同的文件系统,所以它要维护一些描述整个虚拟文件系统和真实的被装配的文件系统的数据结构。非常令人感到迷惑的是, V F S用超级块和i n o d e节点的方式来表示系统的文件,这与E X T 2文件系统使用超级块和i n o d e节点的方式完全一样。与E X T 2文件系统的i n o d e节点一样, V F S的i n o d e节点也用于描述系统中的文件、目录以及虚拟文件系统( V F S )的内容、拓扑结构。从现在开始为了避免混淆,我会使用VFS inode节点和V F S超级块以区别于E X T 2的i n o d e节点、超级块。

在每个文件系统初始化时,它向V F S进行注册。这个过程发生在系统启动操作系统自我初始化的过程中,真实的文件系统或者是安装在内核中的,或者是作为内核的可载入模块。文件系统模块只有在系统需要它们时才会被载入,例如V FAT文件系统如果以内核模块的方式存在的话,它会在装配V FAT文件系统时被载入。每当包含文件系统的块设备被装配时(包括根文件系统),V F S都会读入它的超级块。每种类型文件系统的超级块读例程必须要确定出整个文件系统的拓扑结构,并把这些信息映射到V F S超级块数据结构中。V F S文件系统包含了系统中所有装配文件系统的列表和它们的V F S超级块信息。每个V F S超级块包含执行某些特殊功能的例程的信息和指向它们的指针。例如代表装配的E X T 2文件系统的超级块包含指向读E X T 2文件系统i n o d e节点的例程。这个读例程像所有文件系统读i n o d e节点的例程一样,会填充VFS inode节点的对应域。每个V F S超级块都有一个指向文件系统第一个VFS inode节点的指针。对根文件系统来说,这个指针指向的i n o d e节点是用来表示“/”目录的。上面所讲的信息映射对E X T 2文件系统是非常高效的,但对其他的文件系统效率可能会降低。

在系统进程访问目录和文件时,系统会调用

搜索系统中VFS inode 节点的进程。例如,对一

个目录敲l s命令或对文件使用c a t命令都会使V F S

文件系统搜索代表其所在文件系统的VFS inode节点组。由于系统中的每个文件和目录都是由一个VFS inode节点表示的,所以有一些i n o d e节点会被经常访问。这些经常被访问的i n o d e节点被记录在缓存中以加速访问过程。如果要访问的i n o d e节点不在i n o d e缓存中,那么系统会调用文件系统的专门例程来读入相应的i n o d e节点。读入i n o d e节点的操作会使得它被加入到i n o d e缓存中,而对该i n o d e节点的后续访问使得它被保存在i n o d e缓存中。那些访问频率较低的V F Si n o d e节点会被从i n o d e缓存中删除掉。

所有的L i n u x文件系统使用共同的缓冲区缓存来缓存从下层物理设备来的数据,通过这种方式来加速文件系统对它们对应的物理设备的访问。缓冲区缓区是独立于文件系统的,并被集成为L i n u x内核用于分配、读写数据缓冲区的一种机制。它的显著优势是使得L i n u x文件系统从下层物理介质和支持物理介质的设备驱动程序中独立出来。所有的块设备向L i n u x内核进行注册,并向上提供一个统一的、基于块操作的异步接口,即使像S C S I这样复杂的块设备也支持相同的接口。在真实文件系统从下层物理硬盘读数据时,它会向控制该设备的设备驱动程序发出读物理块的请求。缓冲区缓存集成了这个块设备接口。所有由文件系统读出的块都被放入由所有的文件系统和L i n u x内核共享的全局缓冲区缓存中,缓存中所有的缓冲区是由它的块号和所在设备的标识来标识的。所以,如果经常需要访问相同的数据的话,那么这些数据可以直接从缓冲区缓存中取出而不是从硬盘直接读出(从硬盘读数据块花费的时间要长一些)。有些设备支持预读操作,这时系统推测可能使用的数据块会被设备读出,以防文件系统需要它们。

V F S文件系统还支持目录查找缓存机制,所以经常使用的目录的i n o d e节点可以更快地被找到。如果要做个实验的话,你可以对最近没有使用的目录作一下l s操作。第一次l s操作时你可能会注意到一个短暂的停顿,而第二次它会立即返回结果,目录缓存存放的不是代表目录的i n o d e节点(这些i n o d e节点是在i n o d e缓存中的),而只有一些全目录名和对应索引节点的节点号的映射。

/proc文件系统

/ p r o c文件系统才真正显示出了Linux VFS文件系统的能量。/ p r o c目录、子目录以及下面的文件都不是真正存在的。那么你怎么可以对/ p r o c / d e v i c e s用c a t命令呢? / p r o c文件系统像真实的文件系统一样向V F S文件系统注册自己。V F S文件系统在打开它的文件或目录,请求它的i n o d e节点时, / p r o c文件系统利用来自内核的信息创建这些文件、目录。例如:内核的/ p r o c / d e v i c e s文件是从内核描述设备的数据结构创建来的。/ p r o c文件系统为用户提供了一个查看内核内部工作的只读窗口。像L i n u x内核模式这样的L i n u x子系统,都在/ p r o c文件系统中创建实体。

特殊设备文件

L i n u x像所有版本的U N I X T M一样,把它的硬件设备作为一个特殊文件看待。例如:/ d e v / n u l l是空设备。设备文件不使用文件系统的任何数据空间,它只是设备驱动程序的访问点。E X T 2文件系统和Linux VFS文件系统都把设备文件实现成特殊类型的i n o d e节点。系统有两种类型的设备文件:字符和块设备文件。在内核中设备驱动程序实现了文件的语义:你可以对它们执行打开、关闭等操作。字符设备允许为字符模式进行I / O操作而块设备要求所有的I / O操作都经过缓冲区缓存。当设备文件收到的一个I / O请求时,会把请求传送给系统中相应的设备驱动程序。这个设备驱动程序有时并不是真正的设备驱动程序而是像S C S I设备驱动程序层那样的某些子系统的伪设备驱动程序。设备文件由标识设备类型的主设备号和标识主设备类型对应实例的次类型来访问。例如对系统第一个I D E控制器的I D E硬盘,它的主设备号是3,而I D E硬盘的第一个分区的类型号为1。所以对/ d e v / h d a 1使用l s – l命令会产生如下结果:

在内核中的每个设备都由一个两字节长的k d e v t数据结构唯一地表示。k d e v t结构的第一字节包含次设备号,而第二字节包含主设备号。上面的I D E设备在内核中被记为0 x 0 3 0 1。一个代表块或字符设备的E X T 2文件系统的i n o d e节点,在它的第一个直接块指针中记录下设备的主设备号和次类型号。当V F S文件系统读设备文件时,代表该设备文件的VFS inode数据结构把自己的i r d e v域置成对应的设备标识符。

程序员福利:掀开裙子看真相之linux文件系统

$$$$$$$$$$$$$$$$$$$$$$$$

更多精彩,请访问我们的网站:我爱狄八哥(52debug@net )我爱狄八哥,我爱debug,华语地区最大的技术类垂直社区52debug。net

微信公众号:coding-art (编码之妙)

微信公众号:debug51(我爱debug) 点下订阅点个赞,小编今天的工资,全靠你了。若是能转发下,明天的就更有干劲了。

看到这里,发一则告示:tango.unity虚拟现实技术 q q 群号:318423655
$$$$$$$$$$$$$$$$$$$$$$$$

讲一名谷歌码神的故事,说一说如何从0学习android编程

隔壁老王亲述:华人如何打入谷歌安卓核心开发团队

安卓程序员福利,掀开裙子看真相之linux进程间通讯

 


分享:
编码之妙 Asked on 2016年9月12日 in android.
Add Comment
0 Answer(s)

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.