Linux文件系统

96
Mr希灵
2017.01.04 22:10* 字数 2634

1. 存储设备分区

一个磁盘可以划分为很多个扇区,每个扇区有512个字节,扇区是磁盘的基本存储单元。将每个扇区编号,这样磁盘就变为了一系列编了号的块组合。一个磁盘主要包括引导块,超级块,i节点表,文件存储区,进程对换区等。


  1. 引导块。引导块占用第0号物理块,不属于文件系统管辖;如果系统中有多个文件系统,只有跟文件系统才有引导程序放入引导块中,其余文件系统都不使用引导块。
  2. 超级块。文件系统的第一个块被称为超级块,这个块存放的是文件系统本身的结构信息;比如超级块记录了每个区域的大小,存放未使用磁盘的信息等。
  3. i节点表。超级块是下一个部分就是i节点表,每个文件对应一个i节点,每个文件都有一些属性,如文件大小,所有者,创建时间等。这些信息存放在对应的i节点的结构中,所有的文件都具有相同大小的i节点,这些i节点组成一个i节点表,文件系统创建后,i节点的数目是有限的。所以一个文件系统能够创建的文件也是有限的。
  4. 文件存储区。文件系统的第3个部分是文件存储区,文件的内容保存在这里,磁盘所有的块大小都是一样,如果文件大小超过一个块的大小,则文件会存放在多个次磁盘块中。
  5. 进程对换区。磁盘上会开辟一块区域, 为对换区, 当内存中的进程需要扩大占用的内存空间, 而当前内存空间不足时, 则把某些不常用的进程暂时替换到对换区中, 在适用的时候又把他们换进 内存,解决内存不足和进程之间对内存的竞争问题。

2. 文件结构

大部分的Linux文件系统(如ext2、ext3)规定,一个文件由目录项、inode和数据块组成:目录项记录了文件的i节点号和文件名;i节点则包含了文件的基础信息以及数据块的指针;数据块则包含文件的具体内容。

Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。一个目录文件的内容为目录下所有文件的目录项的列表,每个目录项有i节点号和文件名组成。因此,通过目录项即可知道文件的i节点,进而对文件内容进行访问。

i节点中通常存放了一个文件的管理信息和一些基本的系统数据(如文件的长度、文件内容存放在磁盘上的位置等)。ls -i可以查看当前目录下所有文件的i节点号;stat filename可以查看文件的系统信息,包括iNode。其结构如下:

struct dinode
{
 ushort di_mode;  /*文件类型+用户权限*/
 short di_nlink;  /*文件链接数*/
 ushort di_uid;  /*属主用户id*/
 ushort di_gid;  /*属主用户组id*/
 off_t di_size;  /*文件大小*/
 char di_addr[40]; /*文件数据区起点地址*/
 time_t di_atime; /*最后访问时间*/
 time_t di_mtime; /*最后修改时间*/
 time_t di_ctime; /*创建时间*/
}; 

i节点数据结构里面没有文件名,那文件系统是如何管理文件名,i节点和文件内容之间的关系的呢?i节点号存储在目录入口的头两个字节中,是文件名字和其内容之间的唯一联系。因此目录中的文件名被称为链,它把目录层次结构中的名称连接到它的i节点,同时也就链接到数据。同一个i节点号可以出现在多个目录中,rm命令并不是真正删除i节点,它删除的是目录入口或链。只有当链接到文件的最后的链消失后,系统才删除i节点,也就是文件本身。

在Linux中,我们通过解析路径,根据沿途的目录文件来找到某个文件。目录中的条目除了所包含的文件名,还有对应的inode编号。当我们输入$cat /var/test.txt时,Linux将在根目录文件中找到var这个目录文件的inode编号,然后根据inode合成var的数据。随后,根据var中的记录,找到text.txt的inode编号,沿着inode中的指针,收集数据块,合成text.txt的数据。整个过程中,我们参考了三个inode:根目录文件,var目录文件,text.txt文件的inodes。

假设要创建一个新文件。该新文件占3个磁盘存储块。创建文件步骤如下:

  1. 内核先找到一块空闲的i节点,内核找到空的i节点号为10,内核把文件信息记录到其中,如文件大小,文件所有者,创建时间等。
  2. 存储数据,即文件的内容存储,由于该文件需要3个数据块,内核从空闲的数据块中找到3个数据块,200,300,400。 将内容复制到这些块中。
  3. 记录分配情况,数据保存到3个数据块中,必须记录起来,以便下次查找。磁盘分配情况记录在文件的i节点的磁盘序列列表中。
  4. 增加文件名和目录。新文件的名字为hello.c,内核将文件的入口添加到目录文件中,文件名和i节点号之间的对应关系,将文件名和文件属性,内容联系起来,找到文件名就找到文件的i节点号,通过i节点号就能够找到文件的属性和内容。

3. 硬链接与软链接

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

ln命令可以创建硬链接,语法为:

ln source_file target_file

运行上面这条命令以后,源文件与目标文件的inode号相同,都指向同一个inode。inode信息中有一项叫做"链接数",记录指向该inode的文件名总数,这时就会增加1。反过来,删除一个文件名,就会使得inode节点中的"链接数"减1。当这个值减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域。

这里顺便说一下目录文件的"链接数"。创建目录时,默认会生成两个目录项:"."和".."。前者的inode号就是当前目录的inode号,等同于当前目录的"硬链接";后者的inode号就是当前目录的父目录的inode号,等同于父目录的"硬链接"。所以,任何一个目录的"硬链接"总数,总是等于2加上它的子目录总数(含隐藏目录),这里的2是父目录对其的“硬链接”和当前目录下的".硬链接"。

除了硬链接以外,还有一种特殊情况。文件A和文件B的inode号虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)。l类似于windows系统中的快捷方式。

这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:"No such file or directory"。这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化。

ln -s命令可以创建软链接,语法为:

ln -s source_file target_file

4. 文件权限

每个文件具有3种权限信息,读、写和执行;此外,还可以为不同的访问者赋予不同的权限,有文件所有者、同组用户和其他人三种权限组。ls -l可以在输出其他信息的同时,也输出权限信息。

例子:-rw-r--r--
-:文件类型(-:文件;d:目录;l:软链接文件)
文件只有三种权限:(r:读;w:写;x:执行)
rw-(u所有者);r--(g所属组);r--(o其他人)

chmod命令用于改变文件的权限,权限可以用两种方式表示:八进制数或符号。符号描述可以说明权限的相对改变,但八进制数更加容易使用。在八进制模式下通过给读权限赋值4,给写权限赋值2,给执行权限赋值1来改变权限。和ls中一样,3个数字分别说明文件所有者、组成员和其他成员的权限。

例子:
chmod 754 junk 
给文件所有者赋予读、写和执行的权限(4+2+1),组成员读和执行权限(4+1),其他成员读权限(4)

除了超级用户,就只有文件所有者本人才可以改变一个文件的权限,而不考虑权限本身是什么。

5. 目录层次

因为linux是一个多用户系统,制定一个固定的目录规划有助于对系统文件和不同的用户文件进行统一管理。但就是这一点让很多从windows转到linux的初学者感到头疼。\为根目录,在根目录有很多重要的目录,其名称和功能如下所示:

软件技术学习
Web note ad 1