linux文件系统

转自:https://www.linuxprobe.com/linux-system-structure.html

 

1.虚拟文件系统

1.1虚拟文件系统概念

    Linux 操作系统将独立的文件系统组合成了一个层次化的树形结构,并且由一个单独的实体代表这一文件系统。Linux 将新的文件系统通过一个称为“挂装”或“挂上”的操作将其挂装到某个目录上,从而让不同的文件系统结合成为一个整体。Linux 操作系统的一个重要特点是它支持许多不同类型的文件系统。Linux 中最普遍使用的文件系统是 Ext2,它也是 Linux 土生土长的文件系统。但 Linux 也能够支持 FAT、VFAT、FAT32、MINIX 等不同类型的文件系统,从而可以方便地和其它操作系统交换数据。由于 Linux 支持许多不同的文件系统,并且将它们组织成了一个统一的虚拟文件系统。  

   虚拟文件系统(VirtualFileSystem,VFS):隐藏了各种硬件的具体细节,把文件系统操作和不同文件系统的具体实现细节分离了开来,为所有的设备提供了统一的接口,VFS提供了多达数十种不同的文件系统。虚拟文件系统可以分为逻辑文件系统和设备驱动程序。逻辑文件系统指Linux所支持的文件系统,如ext2,fat等,设备驱动程序指为每一种硬件控制器所编写的设备驱动程序模块。

虚拟文件系统(VFS)是 Linux 内核中非常有用的一个方面,因为它为文件系统提供了一个通用的接口抽象。VFS 在 SCI 和内核所支持的文件系统之间提供了一个交换层。即VFS在用户和文件系统之间提供了一个交换层。

VFS在用户和文件系统之间提供了一个交换层:

带你真正认识Linux 系统结构带你真正认识Linux 系统结构

在 VFS 上面,是对诸如 open、close、read 和 write 之类的函数的一个通用 API 抽象。在 VFS 下面是文件系统抽象,它定义了上层函数的实现方式。它们是给定文件系统(超过 50 个)的插件。文件系统的源代码可以在 ./linux/fs 中找到。

文件系统层之下是缓冲区缓存,它为文件系统层提供了一个通用函数集(与具体文件系统无关)。这个缓存层通过将数据保留一段时间(或者随即预先读取数据以便在需要是就可用)优化了对物理设备的访问。缓冲区缓存之下是设备驱动程序,它实现了特定物理设备的接口。

因此,用户和进程不需要知道文件所在的文件系统类型,而只需要象使用 Ext2 文件系统中的文件一样使用它们。

1.2文件目录

      文件结构是文件存放在磁盘等存贮设备上的组织方法。主要体现在对文件和目录的组织上;

目录提供了管理文件的一个方便而有效的途径。

Linux使用标准的目录结构,在安装的时候,安装程序就已经为用户创建了文件系统和完整而固定的目录组成形式,并指定了每个目录的作用和其中的文件类型。

完整的目录树可划分为小的部分,这些小部分又可以单独存放在自己的磁盘或分区上。这样,相对稳定的部分和经常变化的部分可单独存放在不同的分区中,从而方便备份或系统管理。目录树的主要部分有 root、/usr、/var、/home 等。这样的布局可方便在 Linux 计算机之间共享文件系统的某些部分。

带你真正认识Linux 系统结构带你真正认识Linux 系统结构

Linux采用的是树型结构。最上层是根目录,其他的所有目录都是从根目录出发而生成的。

微软的DOS和windows也是采用树型结构,但是在DOS和windows中这样的树型结构的根是磁盘分区的盘符,有几个分区就有几个树型结构,他们之间的关系是并列的。最顶部的是不同的磁盘(分区),如:C,D,E,F等。

但是在linux中,无论操作系统管理几个磁盘分区,这样的目录树只有一个。从结构上讲,各个磁盘分区上的树型目录不一定是并列的。

1.3文件系统在内核中的表示

Linux内核的VFS子系统可以图示如下:

带你真正认识Linux 系统结构带你真正认识Linux 系统结构

文件与IO: 每个进程在PCB(Process Control Block)中都保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针,现在我们明确一下:已打开的文件在内核中用file结构体表示,文件描述符表中的指针指向file结构体。

在file结构体中维护File Status Flag(file结构体的成员f_flags)和当前读写位置(file结构体的成员f_pos)。在上图中,进程1和进程2都打开同一文件,但是对应不同的file结构体,因此可以有不同的File Status Flag和读写位置。file结构体中比较重要的成员还有f_count,表示引用计数(Reference Count),后面我们会讲到,dup、fork等系统调用会导致多个文件描述符指向同一个file结构体,例如有fd1和fd2都引用同一个file结构体,那么它的引用计数就是2,当close(fd1)时并不会释放file结构体,而只是把引用计数减到1,如果再close(fd2),引用计数就会减到0同时释放file结构体,这才真的关闭了文件。

每个file结构体都指向一个file_operations结构体,这个结构体的成员都是函数指针,指向实现各种文件操作的内核函数。比如在用户程序中read一个文件描述符,read通过系统调用进入内核,然后找到这个文件描述符所指向的file结构体,找到file结构体所指向的file_operations结构体,调用它的read成员所指向的内核函数以完成用户请求。在用户程序中调用lseek、read、write、ioctl、open等函数,最终都由内核调用file_operations的各成员所指向的内核函数完成用户请求。

file_operations结构体中的release成员用于完成用户程序的close请求,之所以叫release而不叫close是因为它不一定真的关闭文件,而是减少引用计数,只有引用计数减到0才关闭文件。对于同一个文件系统上打开的常规文件来说,read、write等文件操作的步骤和方法应该是一样的,调用的函数应该是相同的,所以图中的三个打开文件的file结构体指向同一个file_operations结构体。如果打开一个字符设备文件,那么它的read、write操作肯定和常规文件不一样,不是读写磁盘的数据块而是读写硬件设备,所以file结构体应该指向不同的file_operations结构体,其中的各种文件操作函数由该设备的驱动程序实现。

每个file结构体都有一个指向dentry结构体的指针,“dentry”是directory entry(目录项)的缩写。我们传给open、stat等函数的参数的是一个路径,例如/home/akaedu/a,需要根据路径找到文件的inode。为了减少读盘次数,内核缓存了目录的树状结构,称为dentry cache,其中每个节点是一个dentry结构体,只要沿着路径各部分的dentry搜索即可,从根目录/找到home目录,然后找到akaedu目录,然后找到文件a。dentry cache只保存最近访问过的目录项,如果要找的目录项在cache中没有,就要从磁盘读到内存中。

每个dentry结构体都有一个指针指向inode结构体。inode结构体保存着从磁盘inode读上来的信息。在上图的例子中,有两个dentry,分别表示/home/akaedu/a和/home/akaedu/b,它们都指向同一个inode,说明这两个文件互为硬链接。inode结构体中保存着从磁盘分区的inode读上来信息,例如所有者、文件大小、文件类型和权限位等。每个inode结构体都有一个指向inode_operations结构体的指针,后者也是一组函数指针指向一些完成文件目录操作的内核函数。

和file_operations不同,inode_operations所指向的不是针对某一个文件进行操作的函数,而是影响文件和目录布局的函数,例如添加删除文件和目录、跟踪符号链接等等,属于同一文件系统的各inode结构体可以指向同一个inode_operations结构体。

inode结构体有一个指向super_block结构体的指针。super_block结构体保存着从磁盘分区的超级块读上来的信息,例如文件系统类型、块大小等。super_block结构体的s_root成员是一个指向dentry的指针,表示这个文件系统的根目录被mount到哪里,在上图的例子中这个分区被mount到/home目录下。

file、dentry、inode、super_block这几个结构体组成了VFS的核心概念。对于ext2文件系统来说,在磁盘存储布局上也有inode和超级块的概念,所以很容易和VFS中的概念建立对应关系。而另外一些文件系统格式来自非UNIX系统(例如Windows的FAT32、NTFS),可能没有inode或超级块这样的概念,但为了能mount到Linux系统,也只好在驱动程序中硬凑一下,在Linux下看FAT32和NTFS分区会发现权限位是错的,所有文件都是rwxrwxrwx,因为它们本来就没有inode和权限位的概念,这是硬凑出来的。

1.5挂载文件系统

    linux系统中每个分区都是一个文件系统,都有自己的目录层次结构。linux会将这些分属不同分区的、单独的文件系统按一定的方式形成一个系统的总的目录层次结构。这里所说的“按一定方式”就是指的挂载。

将一个文件系统的顶层目录挂到另一个文件系统的子目录上,使它们成为一个整体,称为挂载。把该子目录称为挂载点.

例如要读取硬盘中的一个格式化好的分区、光盘或软件等设备时,必须先把这些设备对应到某个目录上,而这个目录就称为“挂载点(mount point)”,这样才可以读取这些设备。 挂载后将物理分区细节屏蔽掉,用户只有统一的逻辑概念。所有的东西都是文件。

注意:

1、挂载点必须是一个目录。

2、一个分区挂载在一个已存在的目录上,这个目录可以不为空,但挂载后这个目录下以前的内容将不可用。

对于其他操作系统建立的文件系统的挂载也是这样。但是需要理解的是:光盘、软盘、其他操作系统使用的文件系统的格式与linux使用的文件系统格式是不一样的。光盘是ISO9660;软盘是fat16或ext2;windows NT是fat16、NTFS;windows98是fat16、fat32;windows2000和windowsXP是fat16、fat32、 NTFS。挂载前要了解linux是否支持所要挂载的文件系统格式。

挂载时使用mount命令,其格式:mount [-参数] [设备名称] [挂载点]

其中常用的参数有:

-t 指定设备的文件系统类型(什么提到的文件类型)

-o 指定挂载文件系统时的选项。有些也可用在/etc/fstab中。常用的有

codepage=XXX 代码页
iocharset=XXX 字符集
ro 以只读方式挂载
rw 以读写方式挂载
nouser 使一般用户无法挂载
user 可以让一般用户挂载设备

例如:

1. 挂载windows的文件系统:

1)首先我们使用sudo fdisk -l查看挂载的设备,例如最下面有:/dev/hda5

2)mkdir创建一个目录,这里的目录是作为挂在目录,就是你要把E盘挂到这个目录下:mk /mnt/winc

3)windows和linux使用的不是一个文件系统,一般情况下linux不挂载windows文件系统,所以要你手动mount:

 # mount -t vfat /dev/hda5 /mnt/winc ( -t vfat指出这里的文件系统fat32)

现在就可以进入/mnt/winc等目录读写这些文件了。

2.挂载光盘:# mk /mnt/cdrom

 # mount -t iso9660 /dev/cdrom /mnt/cdrom (关盘的名字一般都是cdrom,这条命令一般都通用)

3.虚拟机共享文件夹:例如在VirtualBox下,主机是Windows,Ubuntu是Guest。共分三步:

1). 首先要安装虚拟电脑工具包:

在VirtualBox的菜单里选择”设备”->”安装虚拟电脑工具包”,你会发现在Ubuntu桌面上多出一个光盘图标,这张光盘默认被自动加载到了文件夹/media/cdom0,而且/cdrom自动指向这个文件夹。默认设置下文件管理器会自动打开这张光盘,可以看到里面有个”VBoxLinuxAdditions.run”文件。打开一个命令行终端,依次输入”cd /cdrom”和”sudo sh ./VBoxLinuxAdditions.run”,不含双引号,开始安装工具包。安装完毕,会用英文提示要重启Ubuntu,建议立刻重启。重启后,比较明显的变化是鼠标是共享模式,并且剪贴板也和Windows共享了。如果有这些变化,说明虚拟电脑工具包已经装成功。

2). 下一步设置共享文件夹。

在共享文件夹设置窗口中,单击右侧的”添加一个共享文件夹”,路径选择你想要共享的Windows文件夹,共享名任取一个自己喜欢的,比如”myshare”,选项read-only是指是否只允许ubuntu读这个文件夹,请根据需要选择这个选项。

3). 在ubuntu下挂载这个共享文件夹:sudo mount -t vboxsf myshare /media/share

其中”myshare”是之前取的共享文件夹的名字,”/media/share”是要挂载到的目标文件.

1.6软连接、硬链接

可以用ln命令对一个已经存在的文件再建立一个新的连接,而不复制文件的内容。连接有软连接和硬连接之分,软连接又叫符号连接。它们各自的特点是:
硬连接:是给文件一个副本,原文件名和连接文件名都指向相同的物理地址。目录不能有硬连接;硬连接不能跨越文件系统(不能跨越不同的分区)文件在磁盘中只有一个拷贝,节省硬盘空间;

修改其中一个,与其连接的文件同时被修改。如果删除其中任意一个其余的文件将不受影响。

由于删除文件要在同一个索引节点属于唯一的连接时才能成功,因此可以防止不必要的误删除。

符号连接(软连接):用ln -s命令建立文件的符号连接符号连接是linux特殊文件的一种,作为一个文件,它的数据是它所连接的文件的路径名。类似windows下的快捷方式。

当然删除这个连接,也不会影响到源文件,但对连接文件的使用、引用都是直接调用源文件的。

具体关系可以看下图:

带你真正认识Linux 系统结构带你真正认识Linux 系统结构

从图上可以看出硬链接和软链接的区别:

1:硬链接原文件和新文件的inode编号一致。而软链接不一样。

2:对原文件删除,会导致软链接不可用,而硬链接不受影响。

3:对原文件的修改,软、硬链接文件内容也一样的修改,因为都是指向同一个文件内容的。

1.7文件系统访问原理

在Windows系统中, 一切东西都是存放在硬盘上的。启动系统后,先确定硬盘,再确定硬盘上的分区以及每个分区所对应文件系统,最后是存放在某个分区特定的文件系统中的文件。 也就是说,Windows是通过 “某个硬盘-硬盘上的某个分区-分区上的特定文件系统-特定文件系统中的文件” 这样的顺序来访问到一个文件的。

但是与Windows不同, Linux 系统中的一切都是存放在唯一的 虚拟文件系统中的,这个 虚拟文件系统是树状的结构以一个根目录开始。启动系统后,先有这个 虚拟文件系统,再识别出各个硬盘, 再把某个硬盘的某个分区挂载到这个 虚拟文件系统的某个子树上(即分区用某个子目录来表示),再确定分区对应的子目录文件系统,最后的文件就存放在这个特定的文件系统中。 也就是说, Linux 系统是通过 “虚拟文件系统-硬盘-硬盘上的分区-分区上的特定文件系统-特定文件系统中的文件” 这样的顺序来访问一个文件的。

可能对习惯了使用Windows的用户来说, Linux 的方式有些不适应,它的 虚拟文件系统,实质就是一颗目录树,最开始的目录叫做根目录,根目录中又有每一级子目录,或者文件,子目录又有子子目录和文件,其中每个子目录都特定的功能这个功能(这些是约定俗成了的,在后面 常用的重要目录 (See section 1.2.1) 中会详细说明)。

也许有人会问,没有这个虚拟文件系统就无法使用硬盘,可是最开始没有硬盘,那么这个 虚拟文件系统以及相应的组织结构是怎么存放起来的呢?这个问题,就像先有鸡还是先有蛋这个问题一样看似简单实则……但是,在 Linux 中,很轻易地跳出了这个思维循环,问题的答案并没在 虚拟文件系统 和 硬盘 这两者之间徘徊,而是第三者—— 内存 ,Linux系统启动起来之后,整个 虚拟文件系统的组织结构,都是随着每次内核系统的启动自动在内存中建立好了的,根本就不需要硬盘。

举例说明

下面用直观的例子,来说明两者的不同,以加深理解。假设我们的机器上面有一个硬盘,硬盘分为三个区。

在Windows系统中, 我们启动系统之后就会看到 C, D, E, 盘符,它们分别对应硬盘上的三个分区,增加硬盘,或者分区,会导致盘符的增加(注意由于历史原因, A, B 用于表示软驱,硬盘分区盘符从 C 开始按字母递增),这里的每个分区都各自可以被格式化为不同的文件系统(这里的文件系统,包括例如 NTFS 格式, FAT32 格式等),文件系统的基本功能就是为了存放文件的,不同文件系统区别一般在于管理其中存放的文件的功能的强弱,所以分区被格式化成指定格式的文件系统之后,就可以存放任何文件和目录了,我们看到的 C, D, E 内容也就对应了硬盘中相应分区的数据内容。

但是,与Windows中把硬盘分区看成 C, D, E 盘符不同, Linux 中最开始根本就没有硬盘的概念,就只有一个纯粹的 虚拟文件系统。如果想要使用哪个硬盘的某个分区,就把那个分区 “挂载” 到某个子目录之下,这样硬盘中的分区,文件系统,目录等内容就呈现到了那个子目录里面。也就是说,在 Linux 中,我们使用硬盘中的数据,实际是先把硬盘的某个分区 “挂载” 到某个子目录下,然后通过那个子目录来访问的。这个例子中, 通常硬盘会对应 虚拟文件系统中的/dev/sda (如有多个硬盘,则为 /dev/sda, /dev/sdb, ……, 按字母递增), 其三个分区对应 /dev/sda1, /dev/sda2,/dev/sda3 (多个分区按数字递增,不同硬盘的分区,对应为 /dev/sdb1, /dev/sdb2 等等), 默认硬盘各个分区会被挂载到 虚拟文件系统系统中类似 /mnt/sda1/, /mnt/sda2/, /mnt/sda3/ 的目录(在 Linux 又叫挂载点)中,在/etc/fstab 文件中,我们可以找到分区文件和挂载点的对应关系描述。这样,硬盘相应的分区就做为整个 虚拟文件系统根目录下的一颗子树,反映到了子目录(挂载点)上,子目录中的内容就对应分区中的数据。

假设访问上述硬盘第三个分区 dir1 目录中的文件 test.file

1.8嵌入式文件系统启动脚本实例

/etc/init.d # cat rcS 
#!/bin/sh

runlevel=S
prevlevel=N
umask 022 
export PATH runlevel prevlevel
source /etc/profile

/bin/mount -t tmpfs -o size=8M none /var
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/empty
mkdir -p /var/tmp
mkdir -p /var/shm

/bin/mount -a
/bin/hostname -F /etc/HOSTNAME
/bin/echo /bin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

mkdir -p /dev/shm 
/bin/mount -t tmpfs -o size=2M tmpfs /dev/shm

cd /dev
mkdir -p /dev/pts 
/bin/mount -t devpts devpts /dev/pts

/bin/mount -t tmpfs -o size=16M tmp /tmp


/usr/sbin/telnetd &
/usr/usr-bin/vsftpd &

mkdir -p /tmp/work/app
/usr/usr-bin/ubiattach /dev/ubi_ctrl -m 3
if [ -c /dev/ubi1 -a -c /dev/ubi1_0 ];then
        mount -t ubifs -o sync /dev/ubi1_0 /tmp/work/app  //挂载硬盘分区
else
        /usr/usr-bin/ubimkvol /dev/ubi1 -N app -s 13MiB
        mount -t ubifs -o sync /dev/ubi1_0 /tmp/work/app
fi

mkdir -p /tmp/work/backup
/usr/usr-bin/ubiattach /dev/ubi_ctrl -m 4
if [ -c /dev/ubi2 -a -c /dev/ubi2_0 ];then
        mount -t ubifs -o sync /dev/ubi2_0 /tmp/work/backup
else
        /usr/usr-bin/ubimkvol /dev/ubi2 -N backup -s 8MiB
        mount -t ubifs -o sync /dev/ubi2_0 /tmp/work/backup//挂载硬盘分区
fi

mkdir -p /tmp/work/data
/usr/usr-bin/ubiattach /dev/ubi_ctrl -m 5
if [ -c /dev/ubi3 -a -c /dev/ubi3_0 ];then
        mount -t ubifs -o sync /dev/ubi3_0 /tmp/work/data
else
        /usr/usr-bin/ubimkvol /dev/ubi3 -N data -s 72MiB
        mount -t ubifs -o sync /dev/ubi3_0 /tmp/work/data//挂载硬盘分区
fi

insmod /usr/usr-drv/ly_exwdg.ko
ifconfig eth0 192.168.8.203
ifconfig lo 127.0.0.1 up

if [ ! -e /work/app ]; then
        ln -s /tmp/work/app /work/app
fi

if [ ! -e /work/backup ]; then
        ln -s /tmp/work/backup /work/backup
fi

if [ ! -e /work/data ]; then
        ln -s /tmp/work/data /work/data
fi

/usr/usr-bin/checkpart
/usr/usr-bin/en_fswp    
/usr/usr-bin/checkcrc

cd /tmp/work/app
if [ -f startup.sh ];then
        cp /tmp/work/app/startup.sh /tmp/startup.sh
        chmod 777 /tmp/startup.sh
        cd /
        /tmp/startup.sh
fi

if [ ! -f /tmp/work/app/startup* ];then
        ly_shell
fi

cd /

终端中app bakup data 目录分别挂载了硬盘中三个不同的分区,虚拟文件系统存在于内存之中,当需要使用外部硬盘设备时,需要挂载到对应的目录上

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值