磁盘及文件系统

2021年3月23日 11点热度 0条评论 来源: 心小雨

磁盘及文件系统

硬盘的物理构成:

硬盘的物理构成:
     扇区(sector)、磁道(track)、磁头、柱面(cylinder)。
分区:就是记录每一个分区的起始柱面和结束柱面。分区信息存放在0柱面0磁头1扇区上:MBR 主引导记录(446字节)+DPT磁盘分区表(64字节)+结束标志(2个字节)
     硬盘的主引导记录(MBR)是不属于任何一个操作系统的,它先于所有的操作系统而被调入内存,并发挥作用,然后才将控制权交给主分区(活动分区)内的操作系统,并用主分区信息表来管理硬盘。
     文件系统是操作系统用于明确存储设备(常见的是磁盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。

block:数据存储的最小单元
inode:索引节点,全局唯一编号,除了记录文件的属性外,同时还具有指针功能,指向文件内容放置的块(里面保存的是文件的权限,所有者,所属主等基本信息)
    1、文件的拥有者与用户组(owner/group)
    2、文件的访问模式(read/write/excute)
    3、文件的类型(type)
    4、文件建立或状态改变的时间(ctime)、最近一次的读取时间(atime)、最近修改时间(mtime)
    5、文件的大小
    6、定义文件属性的标志(flag),如setUID...
    7、文件真正内容的指针(pointer)

创建目录:分配一个inode和至少一个block
        inode记录该目录的相关属性,并指向分配到的那个块;
        block记录在这个目录下的相关文件(或目录)的关联性。
创建文件:分配至少一个inode与相对于该文件大小的快数量
         inode不记录文件名,而是记录文件的相关属性,文件名记录在目录所属的block区域

例如:读取/etc/crontab的流程如下:
     1、操作系统根据根目录(/)的相关数据可获取/etc目录所在的inode,并读取/etc这个目录所有相关属性
     2、根据/etc的inode的数据,可以获取/etc目录下所有文件的关联数据是放置在哪一个block中,并前往该block读取文件的关联性内容
     3、由上步骤的block中,可以知道crontab文件的inode所在地,并前往该inode
     4、由上步骤的inode中,可以获取crontab文件的所有属性,并前往由inode所指向的block区域,获取crontab文件内容

块组:
文件系统构成:(dumpe2fs 可以查看)

[root@localhost ~]# dumpe2fs /dev/sda1
dumpe2fs 1.45.4 (23-Sep-2019)
Filesystem volume name:   <none>
Last mounted on:          /boot
Filesystem UUID:          e12de31a-c96f-4893-8799-ed886d9ee004
Filesystem magic number:  0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              65536
Block count:              262144
Reserved block count:     13107
Free blocks:              200404
Free inodes:              65227
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Reserved GDT blocks:      127
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Mon Nov 30 21:47:51 2020
Last mount time:          Sun Mar 21 21:55:59 2021
Last write time:          Sun Mar 21 21:55:59 2021
Mount count:              7
Maximum mount count:      -1
Last checked:             Mon Nov 30 21:47:51 2020
Check interval:           0 (<none>)
Lifetime writes:          371 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:	          256
Required extra isize:     32
Desired extra isize:      32
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      ee91b084-9272-412d-820a-2ff4eff2fcbc
Journal backup:           inode blocks
Checksum type:            crc32c
Checksum:                 0xb9ddde0b
Journal features:         journal_incompat_revoke journal_64bit journal_checksum_v3
Journal size:             32M
Journal length:           8192
Journal sequence:         0x00000151
Journal start:            1
Journal checksum type:    crc32c
Journal checksum:         0xf8d7f2c5


组 0:(块 0-32767)  校验值 0x9d16 [ITABLE_ZEROED]
  主 超级块位于 0,组描述符位于 1-1
  保留的GDT块位于 2-128
  块位图位于 129 (+129),校验值 0xa1145d85
  Inode 位图位于 137 (+137),校验值 0x61ce66a7
  Inode表位于 145-656 (+145)
  28511 个可用 块,7885 个可用inode,8 个目录 ,7884个未使用的inodes
  可用块数: 4257-32767
  可用inode数: 303, 309-8192
组 1:(块 32768-65535)  校验值 0x737e [ITABLE_ZEROED]
  备份 超级块位于 32768,组描述符位于 32769-32769
  保留的GDT块位于 32770-32896
  块位图位于 130 (bg #0 + 130),校验值 0x2f669d2b
  Inode 位图位于 138 (bg #0 + 138),校验值 0x198d8536
  Inode表位于 657-1168 (bg #0 + 657)
  9466 个可用 块,8190 个可用inode,2 个目录 ,8189个未使用的inodes
  可用块数: 34030, 34032-34303, 34622-34815, 40961-49151, 49503, 49513-49955, 49958, 50837-51199
  可用inode数: 8195-16384
组 2:(块 65536-98303)  校验值 0x5952 [INODE_UNINIT, ITABLE_ZEROED]
  块位图位于 131 (bg #0 + 131),校验值 0x2970e9f3
  Inode 位图位于 139 (bg #0 + 139),校验值 0x00000000
  Inode表位于 1169-1680 (bg #0 + 1169)
  14117 个可用 块,8192 个可用inode,0 个目录 ,8192个未使用的inodes
  可用块数: 77331-77343, 77369-77375, 77415-90943, 90966-91135, 91762-92159
  可用inode数: 16385-24576
组 3:(块 98304-131071)  校验值 0x1e07 [INODE_UNINIT, ITABLE_ZEROED]
  备份 超级块位于 98304,组描述符位于 98305-98305
  保留的GDT块位于 98306-98432
  块位图位于 132 (bg #0 + 132),校验值 0x30bfe746
  Inode 位图位于 140 (bg #0 + 140),校验值 0x00000000
  Inode表位于 1681-2192 (bg #0 + 1681)
  25688 个可用 块,8192 个可用inode,0 个目录 ,8192个未使用的inodes
  可用块数: 98433-100351, 107303-131071
  可用inode数: 24577-32768
组 4:(块 131072-163839)  校验值 0x15c0 [INODE_UNINIT, ITABLE_ZEROED]
  块位图位于 133 (bg #0 + 133),校验值 0xb28af42d
  Inode 位图位于 141 (bg #0 + 141),校验值 0x00000000
  Inode表位于 2193-2704 (bg #0 + 2193)
  24576 个可用 块,8192 个可用inode,0 个目录 ,8192个未使用的inodes
  可用块数: 139264-163839
  可用inode数: 32769-40960
组 5:(块 163840-196607)  校验值 0xe46a [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  备份 超级块位于 163840,组描述符位于 163841-163841
  保留的GDT块位于 163842-163968
  块位图位于 134 (bg #0 + 134),校验值 0x00000000
  Inode 位图位于 142 (bg #0 + 142),校验值 0x00000000
  Inode表位于 2705-3216 (bg #0 + 2705)
  32639 个可用 块,8192 个可用inode,0 个目录 ,8192个未使用的inodes
  可用块数: 163969-196607
  可用inode数: 40961-49152
组 6:(块 196608-229375)  校验值 0x3ab6 [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  块位图位于 135 (bg #0 + 135),校验值 0x00000000
  Inode 位图位于 143 (bg #0 + 143),校验值 0x00000000
  Inode表位于 3217-3728 (bg #0 + 3217)
  32768 个可用 块,8192 个可用inode,0 个目录 ,8192个未使用的inodes
  可用块数: 196608-229375
  可用inode数: 49153-57344
组 7:(块 229376-262143)  校验值 0x7290 [INODE_UNINIT, ITABLE_ZEROED]
  备份 超级块位于 229376,组描述符位于 229377-229377
  保留的GDT块位于 229378-229504
  块位图位于 136 (bg #0 + 136),校验值 0xa9915399
  Inode 位图位于 144 (bg #0 + 144),校验值 0x00000000
  Inode表位于 3729-4240 (bg #0 + 3729)
  32639 个可用 块,8192 个可用inode,0 个目录 ,8192个未使用的inodes
  可用块数: 229505-262143
  可用inode数: 57345-65536

superblock(超级块):记录整个文件系统相关信息
       1、block与inode的总量
       2、未使用和已使用的inode/block数量
       3、文件系统的载入时间、最近一次写入数据的时间、最近一次检验磁盘(fsck)的时间等文件系统的相关信息
       4、有效位的值,已载入为0,未载入为1
block bitmap(块位图):此处记录block是否使用在向硬盘存储数据时,文件系统需要知道哪些块是空闲的,哪些块是已经占用了的,位图只使用0和1标识对应block是空闲还是被占用,0和1在位图中的位置和block的位置一一对应,第一位标识第一个块,第二个位标识第二个块,依次下去直到标记完所有的block。1G的文件只需要128个block做位图就能完成一一对应。通过扫描这100多个block就能知道哪些block是空闲的,速度提高了非常多。但是要注意,bmap的优化针对的是写优化,因为只有写才需要找到空闲block并分配空闲block。对于读而言,只要通过inode找到了block的位置,cpu就能迅速计算出block在物理磁盘上的地址。
inode bitmap(inode位图):此处记录inode是否使用标识inode号是否被分配的位图称为inode bitmap简称为imap。这时要为一个文件分配inode号只需扫描imap即可知道哪一个inode号是空闲的。
inode table(inode表):为每个inode的数据存放区,一个文件系统中可以说有无数多个文件,每一个文件都对应一个inode,难道每一个仅128字节的inode都要单独占用一个block进行存储吗?更优的方法是将多个inode合并存储在block中,对于128字节的inode,一个block存储8个inode,对于256字节的inode,一个block存储4个inode。这就使得每个存储inode的块都不浪费。在ext文件系统上,将这些物理上存储inode的block组合起来,在逻辑上形成一张inode表(inode table)来记录所有的inode。
block group:对用户是不可见的,子逻辑区域,有个超级标示区。为了解决bmap、inode table和imap太大的问题,引入块组概念,在物理层面上的划分是将磁盘按柱面划分为多个分区,即多个文件系统;在逻辑层面上的划分是将文件系统划分成块组。每个文件系统包含多个块组,每个块组包含多个元数据区和数据区:元数据区就是存储bmap、inode table、imap等的数据;数据区就是存储文件数据的区域。
data block(数据块):为每个block的数据存放区。
boot block部分:也称为boot sector。它位于分区上的第一个块,占用1024字节,并非所有分区都有这个boot sector,只有装了操作系统的主分区和装了操作系统的逻辑分区才有。里面存放的也是boot loader,这段boot loader称为VBR(主分区装操作系统时)或EBR(扩展分区装操作系统时),这里的Boot loader和mbr上的boot loader是存在交错关系的。开机启动的时候,首先加载mbr中的bootloader,然后定位到操作系统所在分区的boot serctor上加载此处的boot loader。
group description(组描述):既然文件系统划分了块组,那么每个块组的信息和属性元数据又保存在哪里呢?ext文件系统为每一个块组信息使用32字节描述,这32个字节称为块组描述符,所有块组的块组描述符组成块组描述符表GDT(group descriptor table)。但是不是每个块组中都存放了块组描述符。ext文件系统的存储方式是:将它们组成一个GDT,并将该GDT存放于某些块组中,存放GDT的块组和存放superblock和备份superblock的块相同,也就是说它们是同时出现在某一个块组中的。读取时也总是读取Group0中的块组描述符表信息。

创建文件:先在目录下创建一个条目,把名字和iNode对应上,回到源数据,指定块位置。
删除文件:删除条目里面的名字和iNode对应关系,将对应的iNode标记为0
复制文件:不同的inode和block
剪切文件:同一个分区,inode号和磁盘块位置都没有变,只是把条目里面的名字改变了一下

extundelete: linux下高效数据恢复工具 http://extundelete.sourceforge.net/ 安装时需要的依赖包 e2fsprogs-lib e2fsprogs-devel

stat filename #查看文件inode信息
df -i #查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令
dumpe2fs -h /dev/hda | grep "Inode size" #查看每个inode节点的大小
ls -i filename #查看文件名对应的inode号码
ls -i directoryname #列出整个目录文件的文件名和inode号码
find ./ -inum 67649036 -exec rm -rf { } \;  #使用inode号码删除文件

链接:硬链接和软链接(符号链接),多个文件指向同一个iNode,硬链接;符号连接,指向的是源文件的路径,而不是文件块。
硬链接:在个目录下的block中增加一个文件关联数据,不会用到inode与磁盘空间
       只能对文件进行创建,为了避免循环引用不能跨文件系统,可以在不同目录下
       创建硬链接可以增加文件被连接的次数
符号链接:建立一个独立的文件,这个文件会让数据的读取指向它连接的文件内容
         可以对目录创建
         可以跨文件系统
         不会增加被链接文件的链接次数
         其大小为指定路径所包含的字符个数
         
ln (link) [-s -v] 源文件 链接
-b 删除,覆盖以前建立的链接
-d 允许超级用户制作目录的硬链接
-f 强制执行
-i 交互模式,文件存在则提示用户是否覆盖
-n 把符号链接视为一般目录
-s 软链接(符号链接)
-v 显示详细的处理过程

硬链接与软链接:

du 查看文件大小 [-s -h ]
-s 只分别计算命令列中每个参数所占的总用量
-h 做单位转换

df 查看硬盘使用情况
-i 查看inode的使用情况
-P 不换行显示
-h 做单位转换

fdisk 查看当前系统识别的硬盘和分区的情况
fdisk -l [/dev/to/smoe_device_file]
还可用来管理分区
fdisk /dev/sda
p:显示当前硬件的分区,包括没有保存的改动
n:创建一个新的分区
d:删除一个分区
w:保存并退出
q:不保存退出
t:修改分区类型(文件系统类型)
l:显示所支持的所有类型



VMware虚拟机不重启添加硬盘的命令(物理机和其他虚拟机没有试过):

高级格式化:mkfs -t ext4
mkfs -t msdos /dev/sdb
mkfs.ext2 、mkfs.ext3 、mke2fs
-b:分区时设定每个数据区块占用空间大小,目前支持1024, 2048 以及4096 bytes每个块。
-i:设定inode大小
-N:设定inode数量,有时使用默认的inode数不够用,所以要自定设定inode数量。
-c:在格式化前先检测一下磁盘是否有问题,加上这个选项后会非常慢
-L:预设该分区的标签label
-j:建立ext3格式的分区,如果使用mkfs.ext3 就不用加这个选项了

查看磁盘超级块的信息:
tune2fs -l /dev/sda[n] 调整ext2/ext3/ext4文件系统参数
dumpe2fs -h /dev/sda[n] 显示ext2/ext3/ext4文件系统信息
swap分区:主要是用来内存过载使用,可以将内存上暂停进程的页面保存在swap分区中,再次启用时再分配页面。分区在系统的物理内存不够用的时候,把物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。

free 查看物理内存和交换空间使用情况

创建swap分区:
第一种方式:
单独分一个分区:fdisk /dev/sdb

更改分区ID为82

按“w”保存并退出
格式化swap分区

启动新的swap分区

修改/etc/fstab实现自动挂载

第二种方式:
创建一个文件块,这个文件所占有的空间作为swap使用:
其中of为该文件路径,count等于想要的块的数量(bs*count=文件大小)。

注:/dev/zero是一个包含无限个0的文件

格式化swap分区

修改/etc/fstab实现自动挂载

dd if=/dev/zero of=/tmp/swapfile bs=1M count=1024 #通过fdisk创建swap分区或者使用dd命令创建一个虚拟内存的文件
mkswap进行swap分区格式化
swapon 激活swap分区
swapoff 关闭swap分区
mount:挂载命令
命令格式:mount [-t vfstype] [-o options] device dir
-a:挂载fstab中提到的所有文件系统
-o remount:重新挂载已挂载的文件系统
-o loop:用来把一个文件当成硬盘分区挂接上系统
-o ro:采用只读方式挂接设备
-o rw:采用读写方式挂接设备
挂接光盘镜像文件
1、从光盘制作光盘镜像文件。将光盘放入光驱,执行下面的命令。
cp /dev/cdrom /home/sunky/mydisk.iso 
或
dd if=/dev/cdrom of=/home/sunky/mydisk.iso
2、挂载光盘镜像文件
mount -o loop -t iso9660 /home/sunky/mydisk.iso /mnt/vcdrom
自动挂载
文件系统的配置文件/etc/fstab
OS在初始时,会自动挂载此文件中定义的每个文件系统
mount -a:挂载/etc/fstab文件中定义的所有文件系统
/etc/fstab文件 实现开机自动挂载

/dev/sdb1  swap     swap    defaults        0                  0
  设备     挂载点 文件系统类型 挂载参数    是否执行备份命令dump 是否启动使用fsck扫描磁盘
fuser: 验证进程正在使用的文件或套接字文件
-v: 查看某文件上正在运行的进程
-k:
-m:针对目录,也就是挂载点,一般和-k 一起使用
fuser -km MOUNT_POINT:终止正在访问此挂载点的所有进程
wodim --devices 查看设备名(没有挂载的光盘)


传统的硬盘分区都是MBR格式,MBR分区位于0扇区,他一共512字节,前446字节是grub引导程序,中间64字节是分区表,每个分区需要16个字节表示,因此主分区和扩展分区一共只能有4个分区,超过4个的分区只能从扩展分区上再设置逻辑分区来表示。每个分区的大小无法超过2T。 MBR的最后2个字节是结束符号。

GPT格式,打破了MBR的限制,可以设置多达128个分区,分区的大小根据操作系统的不同有所变化,但是都突破了2T空间的限制。支持高达 18EB (1EB=1024PB,1PB=1024TB) 的卷大小,允许将主磁盘分区表
和备份磁盘分区表用于冗余,还支持唯一的磁盘和分区 ID (GUID)。与 MBR 分区的磁盘不同,GPT的分区信息是在分区中,而不象MBR一样在主引导扇区。为保护GPT不受MBR类磁盘管理软件的危害,GPT在主引导扇区建立了一个保护分区 (Protective MBR)的MBR分区表,这种分区的类型标识为0xEE,这个保护分区的大小在Windows下为128MB,Mac OS X下为200MB,在Window磁盘管理器里名为GPT保护分区,可让MBR 类磁盘管理软件把GPT看成一个未知格式的分区,而不是错误地当成一个未分区的磁盘。

在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。但在GPT硬盘中,分区表的位置信息储存在GPT头中。但出于兼容性考虑,硬盘的第一个扇区仍然用作MBR,之后才是GPT头。

GPT的结构如下图:

gdisk和fdisk非常类似:


n 添加一个新分区,创建新分区的时候可以看见可以有128个分区

parted,和前两个相比,更灵活,可以自行设定MBR或GPT格式和分区

通过mklabel msdos可以设定为MBR格式,然后可以通过mkpart来划分分区。

msdos                    设定为MBR格式,gpt设定为GPT格式
primary                  代表主分区,extended代表扩展分区,logical代表逻辑分区。
set number flag state    用于设置分区的用途,flag:boot、lvm、raid。State:on/off:表示开启或关闭。

parted工具分完区后无需保存,输入q退出即可。
划分好分区之后,还需要格式化才能使用。
可以通过 mkfs/mkswap来格式化文件系统。
#mkfs.xfs /dev/分区设备名#mkfs -t xfs /dev/分区设备名

可以修改fstab实现自动加载

测试是否能自动挂载

通过df -h查看已经挂载了的设备
-T选项可以显示设备的文件系统类
有的挂载点路径比较长,自动分2行显示,可以-P强制一行显示

如同进程有pid,用户有uid,每个文件系统也有自己的id,称为uuid,但是不是每个分区都有;如果某个分区没有文件系统,那么这个分区是没有uuid的。可以通过 blkid(block id)来查看。注意uuid标记的是文件系统,而不是分区。uuid的好处在于可以通过uuid这个唯一值来挂载系统,这样可以避免因为删除硬盘造成的错位,sda6变成了sda5等等。

可以通过xfs_admin -U 来手动更改文件系统的uuid(改命令只适用xfs文件系统)

总体上说 Linux 下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 VFS(Virtual Filesystem Switch),三是挂载到 VFS 中的各实际文件系统,例如 ext2,jffs 等。

VFS在内核中与其他的内核模块的协同关系:

VFS:virtual filesystem ,interface:system call

当前,除了Linux标准的文件系统Ext2/Ext3/Ext4外,还有很多种文件系统,比如reiserfs, xfs, Windows的vfat NTFS,网络文件系统nfs 以及flash 文件系统jffs2, yaffs/yaffs2 ubifs。linux通过叫做VFS的中间层对这些文件系统提供了完美的支持。

VFS存在的意义:

  1. 向上,对应用层提供一个标准的文件操作接口;
  2. 对下,对文件系统提供一个标准的接口,以便其他操作系统的文件系统可以方便的移植到Linux上;
  3. VFS内部则通过一系列高效的管理机制,比如inode cache, dentry cache 以及文件系统的预读等技术, 使得底层文件系统不需沉溺到复杂的内核操作,即可获得高性能;
  4. 此外VFS把一些复杂的操作尽量抽象到VFS内部,使得底层文件系统实现更简单

VFS 是一种软件机制,也许称它为 Linux 的文件系统管理者更确切点,与它相关的数据结构只存在于物理内存当中。所以在每次系统初始化期间,Linux 都首先要在内存当中构造一棵 VFS 的目录树(在 Linux 的源代码里称之为 namespace),实际上便是在内存中建立相应的数据结构。

    原文作者:心小雨
    原文地址: https://blog.csdn.net/xinxiaoyu_/article/details/115057383
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。