首页 > 代码库 > Linux文件系统

Linux文件系统

  • 文件系统


一、文件系统的概念

1、什么是文件系统

    广义上来说,文件系统是对存储设备的数据和元数据的进行管理或者说组织的一种机制。文件系统类型是这种机制的不同管理方式。

2、存储空间的组成

    存储空间一般是由数据区 和 元数据区组成的,一般元数据区存放文件的元数据,每个文件都有自己的元数据,这些元数据存放在inode(index node)中,为了方便查找文件。

    inode用于存储文件的各种属性:

  • 文件的大小

  • 文件名

  • 属主,属组

  • 时间戳

  • 权限

  • 以及对应在磁盘上的块号(对应block的位置信息)

    每个文件中的数据,存放在数据区,由block管理。block用于存储文件内容。

    当创建一个目录时,文件系统会为该目录分配一个inode和至少一个block。该inode记录该目录的属性,并指向那块block。该block记录该目录下相关联的文件或目录的关联性和名字。   

    当创建一个文件时,文件系统会为该文件分配至少一个inode和与该文件大小相对应的数量的block。该inode记录该文件的属性,并指向block。   如果一个目录中的文件数太多,以至于1个block容纳不下这么多文件时,Linux的文件系统会为该目录分配更多的block。

    Dentry 是将 Inode 和 文件联系在一起的”粘合剂”,它将 Inode number 和文件名联系起来。Dentry 也在目录缓存中扮演了一定的角色,它缓存最常使用的文件以便于更快速的访问。Dentry 还保存了目录及其子对象的关系,用于文件系统的遍历。


二、文件系统结构

1、文件结构在存储空间中的结构如下:

wKioL1PCFlPyXmDlAADIR8YN2KA552.jpg

  • superblock: 是记录元数据的元数据。查看超级块信息:tune2fs -l DEVICE;dumpe2fs -h DEVICE

  • GDT:块组的描述信息,记录何处开始记录数据

  • Block bitmap:记录那些Block是空闲的

  • Inode bitmap:记录那些Inode是空闲的

  • Inode table:存放Inode数据,里面有好多的inode数据。

  • Data blocks:存放数据


2、链接文件

1)链接文件种类和定义

  • 硬链接:多个文件指向同一个inode(在dentry里面),此时,一个文件就称为其他文件的硬链接。没创建一个硬链接文件,Inode的引用数就会增加1。

  • 软链接:相当于windows里面的快捷方式。具体多个文件在Dentry里面指向的是一个文件名,而不是Inode。此时,这些文件称指向那个文件的软链接。

2)创建链接文件

    使用 ln [-sv] SRC DEST创建。其中-s,-v是常用选项,分别表示显示创建过程,创建软链接文件。

    但是在创建链接文件时需注意:

  • 硬链接:

        不能对目录文件创建硬链接

        硬链接不能跨分区

        创建硬链接会增加inode引用计数

  • 符号链接:

        可以对目录创建

        不受分区限制

        对文件创建符号链接不会增加引用计数

3)文件的删除、复制、移动的过程

  • 文件被删除:inode被标记为空闲(Inode bitmap),此inode指向的磁盘块被标记为空闲;如果inode被引用了多次,且此次删除未使得其引用计数降低为的话,这意味着文件被删除仅删除了一个访问路径;

  • 文件复制:创建一个新文件,并原文件中数据在新文件指向的磁盘块中再写一次的过程;

  • 文件移动:在同一个分区移到:移动文件仅是改变了文件访问路径;跨分区移到:在新分区创建文件,把数据复制过去,删除原分区数据。


3、文件系统的类型以及表示方法

1)文件系统的类型

    常见的有:ext2(不支持日志),ext3,ext4, xfs, ffs, ufs, reiserfs, jfs, vfat(fat32), ntfs

2)表示方法

a.磁盘设备文件

  • 磁盘设备类型

    /dev/hd:磁盘接口是IDE类型的用这种方法表示

        IDE: 并口, 133MB/s

    /dev/sd:磁盘接口是SATA类型的用这种方法表示

        USB: 串行

        SATA: 串行,6Gbps/8

        SCSI: 并行,(Small Computer System Interface)

        SAS:串行

    在centos6系列中,不管是IDE类还是SATA类都是以/dev/sd这种方式表示

  • 表示磁盘类型下的不同设备

    /dev/sd[a-z]:用字母a-z表示不同的设备

  •  分区:数字表示不同的分区

    /dev/sda1 

    /dev/sda2

    分区编号:主分区、扩展分区编号1-4,逻辑分区是>=5的

b.特殊设备文件

    特殊设备文件是只有Inode,没有Block数据的文件(此时对应的就是真正的物理设备文件)。在Inode中关联的是硬件的渠道程序,通过驱动程序和硬件相关联。

    特殊文件通过设备号来标识这些文件。主设备号来标识设备类型,次设备号来标识相同设备下的不同设备。


    我们可以手动添加这样的设备文件:

    mknod: make block or character special files(man 文档的解释)

       Usage:mknod [OPTION]... NAME TYPE [MAJOR MINOR]   

    例如:mknod /dev/deviceloop b 12 4


三、磁盘的分区,格式化,挂载,卸载,磁盘修复

  • 分区

    在Linux中分区是针对柱面的。在Linux中主分区和扩展分区最多只能有四个,可以再扩展分区上创建逻辑分区,最多只能有64个逻辑分区。这是由MBR分区决定的。

    常用的分区工具有fdisk,partd等。这里我们介绍fdisk工具。

        Usage: fdisk [option]... [DEVICE]...

    查看一块磁盘的分区信息,例如:fdisk -l /dev/sda

[root@server ~]# fdisk -l /dev/sda

Disk /dev/sda: 107.4 GB, 107374182400 bytes
255 heads, 63 sectors/track, 13054 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0001477f

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        7859    62914560   8e  Linux LVM
[root@server ~]#

    给一块磁盘分区,例如:fdisk /dev/sdb。下面是fdisk的菜单栏,对常用的做了解释。

wKiom1PCLBWw59yrAAKYs9IH5XU923.jpg

    创建分区过程,例如创建一个主分区号位1的主分区,大小为500M。

wKiom1PCLmPg6dLzAAMCHYAVehs622.jpg

    最后使用fdisk中的子命令w保存退出。分区过程完毕。但是对于刚分好的区内核不知道,所以我们要让内核重读分区表。

    在 CentOS5中:

        # partprobe [DEVICE] 

    在 CentOS6中:

        # partx -d [DEVICE]

        # partx -a [DEVICE]


下面简单介绍一下parted分区工具: 

    有时我们在写脚本时,需要非交互式的对磁盘进行分区。parted是一个不错的分区工具。它是一个实时的分区工具,不像fdisk,需要w才能保存。

    Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...]    

    最常用的选项:-s | --script:( never prompts for user intervention),实现非交互方式

    常用的COMMAND:mkpart PART-TYPE [FS-TYPE] START END

        PART_TYPE的取值有primary,logical,extended

        START:1,1G 默认是M

        END:12G

    rm NUMBER delete partition NUMBER 删除一个分区

    print [devices|free|list,all|NUMBER]   显示分区信息

####下面是一些常用的操作
[root@server scripts]# parted -s /dev/sdb print
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End    Size   Type     File system  Flags
[root@server scripts]# parted -s /dev/sdb mkpart primary 1 512
[root@server scripts]# parted -s /dev/sdb mkpart extended 512  10G
[root@server scripts]# parted -s /dev/sdb mkpart logical 512 1G
[root@server scripts]# parted -s /dev/sdb print
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type      File system  Flags
 1      1049kB  512MB   511MB   primary
 2      512MB   10.0GB  9489MB  extended               lba
 5      512MB   1000MB  488MB   logical
[root@server scripts]# parted -s /dev/sdb rm 1
[root@server scripts]# parted -s /dev/sdb print
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start  End     Size    Type      File system  Flags
 2      512MB  10.0GB  9489MB  extended               lba
 5      512MB  1000MB  488MB   logical

[root@server scripts]# parted -s /dev/sdb rm 2
[root@server scripts]# parted -s /dev/sdb print
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start  End  Size  Type  File system  Flags


  • 格式化

    格式化就是在分好的区区上创建文件系统。常见的格式化工具有mkfs,mke2fs工具。

    mkfs工具使用起来简单,而mke2fs工具可以进行比较详细的设置。

1)mkfs

    mkfs : make file system,创建文件系统

        Usage: mkfs -t FSTYPE [DEVICE] 等价 mkfs -t FSTYPE = mkfs.FSTYPE

        例如:mkfs -t ext4 = mkfs.ext4

    注意:有些文件系统Linux内核是支持的,但是我们创建的时候却没有这种文件系统。这是由于Linux的发行版没有将这些功能编译到内核中去。由于Linux内核是模块化的,而且支持动态编译。如果我们使用某一模块的话,可以手动添加进去。

    使用lsmod可以查看内核编译进去的模块。

    以CentOS6为例,发行版不支持xfs文件系统,此时我们可以讲安装这个模块的一个管理工具。

    # yum -y install xfsprogs 

2)mke2fs

    mke2fs是ext系列文件系统的管理工具,但实际上也可以管理其他的文件类型。

    mkfs的常用参数


常用参数具体意义
-t

-t 指定文件系统的类型

例如:mke2fs -t ext4 /dev/sdb1

-b

-b 指定Block的大小,一般是1024,2048,4096

例如:mke2fs -t ext4 -b 1024 /dev/sdb1

-L

-L 指定分区的卷标(别名)

例如:mke2fs -t ext4 -L DATA /dev/sdb1

相当于:e2label /dev/sdb1 DATA

-j

-j 支持日志,针对那些没有日志的文件系统

例如:mke2fs -t ext2 -j /dev/sdb1

-i

-i 定义多上个字节创建一个Inode,次字节数应大于Bock的字节数

例如:mke2fs -t ext4 -b 1024 -i 2048 /dev/sdb1

-N-N 指定可用的节点数
-m

-m 预留百分比,默认是5

为什么要预留呢?这是为了方便管理员的一些操作。

-O-O 指定分区特性
-U

-U 设定磁盘的UUID

这个信息通过 blkid [-L LABEL] DEVICE查看


[root@server ~]# mke2fs -t ext4  -b 2048 -m 3 -L DATA /dev/sdb1
mke2fs 1.41.12 (17-May-2010)
Filesystem label=DATA
OS type: Linux
Block size=2048 (log=1)
Fragment size=2048 (log=1)
Stride=0 blocks, Stripe width=0 blocks
130560 inodes, 261040 blocks
7831 blocks (3.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=267386880
16 block groups
16384 blocks per group, 16384 fragments per group
8160 inodes per group
Superblock backups stored on blocks: 
	16384, 49152, 81920, 114688, 147456

Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@server ~]# blkid /dev/sdb1
/dev/sdb1: UUID="4a7da175-992f-4cd8-8327-96ec40c1d8f2" TYPE="ext4" LABEL="DATA"

    至此格式化完毕。

    但是我们在格式化完毕后,发现某些属性忘记添加了。可以使用tune2fs命令来修改。

        Usage:tune2fs [options].. [DEVICE]...

    常用参数:

        -j :添加日志

        -L LABEL修改卷标

        -m 修改预留百分比

        -O [^]FEATURE: 启用指定特性,特性前加^,表示关闭此种特性

        -o [^]mount-options: 开启或关闭指定的挂载选项

  • 挂载

    挂载的目的是让已经格式化好的分区和某个目录相关联,提供访问磁盘分区的入口。长使用的挂载命令式mount。

        Usage: mount [options]... DEVICE MOUNT_POINT

    这里对挂载点的基本要求是:必须是目录;一般使用空目录作为挂载点。

    常用参数:



常用参数具体意义示例
-t-t 指定挂载文件系统类型mount -t ext4 -w /dev/sdb1 /mnt
-r-r 只读挂载
-w-w 读写挂载
-L-L 卷标挂载(使用卷标来确定设备)mount -t ext4 -L DATA  /mnt
-U-L UUID挂载(使用UUID来确定设备)
-a-a 自动挂载,读取/etc/fstab文件mount -a -n
-n-no-mtab 不更新/etc/mtab文件
-o 

-o optoin指定额外属性,多个属性用逗号隔开

,如果不指定,则使用默认属性。

rw, suid, dev, exec, auto, nouser, async, and relatime


async:异步I/O,数据写操作先于内存完成,而后再根据某种策略同步至持久设备中

sync: 同步I/O,数据写操作完成后立即同步到磁盘中


atime/noatime: 文件和目录被访问时是更新最近一次的访问时间戳


auto/noauto:设备是否支持mount的-a选项自动挂载


diratime/nodiratime: 目录被访问时是更新最近一次的访问时间戳


dev/nodev: 是否支持在此设备上使用设备


exec/noexec: 是否允许执行此设备上的二进制程序文件


suid/nosuid: 是否支持在此设备的文件上使用suid


remount: 重新挂载,通常用于不卸载的情况下重新指定挂载选项


ro: 只读

rw: 读写


user/nouser: 是否允许普通挂载此文件设备


acl: 在此设备是支持使用facl,默认不支持

mount -t ext4 -o sync,acl,suid,noexec /dev/sdb1 /mnt



挂载情况:

  wKiom1PCQyOhLEXxAALq2uScc84679.jpg    

    至此,挂载已完成。

    但是,这些挂载内容在下次重新开机之后,就不在了。所以,为了下次开机之后还能挂载到,我们要把这些信息保存到配置文件/etc/fstab。

wKioL1PCS2TBuyJnAAHBXqLbrWw808.jpg

    注意:如果挂载点目录不是空文件时,它原先在里面的文件就会被隐藏起来。

  • 卸载

    当不需要使用这个分区的时候,需要将这个磁盘分区卸载。使用 umonut DEVICE 或者 umont DEVICE_POINT 来卸载。

    但是,在卸载的时候我们刚好在访问这个目录,那么会提示设备忙,拒绝退出。此时,有2种解决方案:1、退出此目录。2、使用fuser命令强制退出。

wKioL1PCR63j-NV7AAHUZjo_gOU304.jpg

  • 磁盘检查

    什么情况下会进行磁盘检查呢?在出现意外情况下,比如说断电,导致了正在写入磁盘的数据非正常退出。使用fsck 或者 e2fsck工具来检查。

    fsck:check and repair a Linux file system

        -t fstype

        -a: 自动修复错误

        -r: 交互式修复错误

    e2fsck: 专用于修改ext系列文件系统

        -y: 对问题自动回答为yes 

        -f: 强制进行检测

  • swap分区

    swap是交换分区,一般情况下是在内存不够的情况下,启用的一种机制。是将外存作为在特殊情况下当做内存使用,一般情况下模式内存的2倍。

########第一种情况:使用一个分区作为交换分区###########

#第一步:添加一个交换分区
[root@server ~]# fdisk -l /dev/sdb | grep "swap"
/dev/sdb2              66         197     1060290   82  Linux swap / Solaris 
#第二步:将这个分区格式化为swap
[root@server ~]# mkswap /dev/sdb2
Setting up swapspace version 1, size = 1060284 KiB
no label, UUID=ccf2f05f-fcf8-46ca-a304-d759887785d1
#第三步:挂载使用
[root@server ~]# swapon /dev/sdb2
[root@server ~]# swapon -s
Filename				Type		Size	Used	Priority
/dev/dm-1                               partition	2097144	0	-1
/dev/sdb2                               partition	1060280	0	-2

########第二种情况:使用一个文件作为交换分区###########
#第一步:添加一个作为交换分区的文件
[root@server ~]# dd if=/dev/zero of=./myswap bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 50.1967 s, 21.4 MB/s
#第二步:将这文件区格式化为swap
[root@server ~]# mkswap -f ~/myswap 
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=f818dd1c-395f-4da2-bf5e-1edb1483100e
#第三步:挂载使用
[root@server ~]# swapon ./myswap 
[root@server ~]# swapon -s
Filename				Type		Size	Used	Priority
/dev/dm-1                               partition	2097144	0	-1
/root/myswap                            file		1048568	0	-2

###卸载使用 swapoff [DEVICE] 就可以。当然,要想在下次开机时加载,必须将这些写入到/etc/fstab 文件中去。

本文出自 “黑夜过后” 博客,请务必保留此出处http://guoting.blog.51cto.com/8886857/1437607