磁盘、分区、文件系统

一:磁盘

        物理上来说,硬盘主要由若干盘片、机械手臂、读写磁头与主轴马达组成。盘片表面涂以磁性介质,用以存储数据。每个盘片有两面,都可记录信息。而读写主要是透过在机械手臂上的读写磁头来达成。实际运作时,主轴马达让盘片转动,然后机械手臂可伸展使磁头到达指定的位置,在盘片上进行读写动作。每个盘片有两个面,每个面都有一个磁头,

 

        逻辑上来说,又有磁道(track)、扇区(Sector)和柱面(Cylinder)的概念:

        当磁盘旋转时,磁头若保持在一个位置上,则每个磁头都会在磁盘表面划出一个圆形轨迹,这些圆形轨迹就叫做磁道(track)。这些磁道用肉眼是看不到的,磁盘上的信息便是沿着这样的轨道存放的。

        盘片上的每个磁道被等分为若干个弧段,这些弧段便是磁盘的扇区,每个扇区存放512个字节的信息,磁盘驱动器在向磁盘读取和写入数据时,都是以扇区为单位。

        柱面:磁盘通常由一组盘片构成,不同盘片相同半径的磁道所组成的圆柱称为柱面。每个盘面都被划分为数目相等的磁道,并从外缘的“0”开始编号。磁道与柱面都是表示不同半径的圆,在许多场合,磁道和柱面可以互换使用。

        如下图所示:

        通过以上这些参数可以得到硬盘的容量,基计算公式为:存储容量=磁头数×磁道(柱面)数×每道扇区数×每扇区字节数 

 

        注意:早期的磁盘,每个磁道上的扇区数目是一样的,如下图所示:

        越往外,扇区的面积也就越大。每个扇区的数据量是相同的,都是512字节。所以,外面扇区的数据密度低,里边扇区的数据密度高。

        但是这样在外围扇区上,就浪费了大量面积,限制了磁盘的容量。后来为了增大磁盘容量,采用了线性寻址的新技术。每个磁道上扇区数变得不一样了,越往外磁道的扇区数目越多。现在的磁道扇区数目是一个换算平均值。如下图:

 

        另外:当向硬盘中写入数据时,是先写入最外层的磁道,写满所有扇区之后,在向内层磁道写入。这就是为什么硬盘用久了,读写速度会变慢的原因。因为同样的角速度下,线速度越往外越快。

        同样的时间,磁头在外面磁道可以扫过10个扇区的面积,读写10个扇区的数据,但在里面的磁道只能扫过1个扇区的面积,读写1个扇区的扇区。所以,此时可以做磁盘整理或者格式化,这样外面的磁道得到试用。

 

二:分区

        主引导记录(Master Boot Record,MBR),又叫做主引导扇区,是计算机开机后访问硬盘时所必须要读取的首个扇区,它存储在0号盘面的0号磁道的1号扇区上。系统在启动时主动去读取这个区块的内容,这样系统才会知道你的程序放在哪里且该如何进行启动。

        在总共512字节的扇区中,MBR只占用了其中的446个字节,另外的64个字节记录了硬盘分区表(Disk Partition Table,DPT),最后两个字节“55”和“AA”,是分区的结束标志。它们共同组成了硬盘的主引导扇区。

 

        64字节的硬盘分区表可以保存四个分区的信息,因此,所谓的“分区”,只是针对这64字节的分区表进行配置而已!

        每个分区的信息占16个字节,其中记录了该分区开始和结束的磁道(柱面)号。也就是说,分区的最小单位是磁道(柱面)。这4个分区,可以称为主要分区或扩展分区。

        所以对于采用MBR型分区结构的硬盘,最多只能识别4个主要分区。如果需要得到更多的分区,就需要使用扩展分区。扩展分区也是主要分区的一种,但它与主要分区的不同在于,扩展分区可以划分为无数个逻辑分区。

 

        Linux系统中,分区命名为sda1-sda4或者hda1-hda4(其中a表示硬盘编号可能是a、b、c等等)。在MBR硬盘中,分区号1-4是主分区(或者扩展分区),逻辑分区号只能从5开始。

        在MBR分区表中,一个分区最大的容量为2T,且每个分区的起始柱面必须在这个disk的前2T内。若有一个3T的硬盘,根据要求至少要把它划分为2个分区,且最后一个分区的起始扇区要位于硬盘的前2T空间内。如果硬盘太大则必须改用GPT分区方式。

        GPT磁盘分区样式支持最大分区为128 EB(Exabytes),并且磁盘的分区数没有上限,只受到操作系统限制。

 

三:文件系统

        磁盘分区完毕后还需要进行格式化,之后操作系统才能够使用这个分区。因为每种操作系统所配置的文件属性/权限并不相同,为了存放这些文件所需的数据,因此需要将分区进行格式化,以成为操作系统能够利用的文件系统格式。

        因此,每种操作系统能够使用的文件系统并不相同。比如:Windows使用NTFS文件系统,Linux使用ext4文件系统等。默认的情况下,Windows系统不会识别 Linux的Ext4的。

 

1:inode、block、硬链接、软链接

        一般而言,一个分区只能够被格式化成为一个文件系统。

        在Linux的文件系统中,除了文件的实际内容外,还包含很多文件属性,如文件权限、所有者、创建时间、修改时间、文件大小等。通常会将文件内容和文件属性两部份的数据分别存放在不同的区域。文件属性放置到 inode 中,实际数据则放置到block中。

        另外,还有一个super block会记录整个文件系统的整体信息,比如inode和data block 的总量、使用量、剩余量,以及文件系统的格式与相关信息等。

 

        每个inode与block都有编号。一个文件占用一个inode。除了记录文件属性之外,inode中还记录此文件的数据所在的block号; block存储文件的实际内容,每个block 内最多只能够放置一个文件的数据;若文件太大,会占用多个block。

        如下图所示,文件系统先格式化出inode与block的区块,假设某一个文件的属数据放置在4号inode 内,而这个inode记录了文件数据的实际放置点为2,7,13,15这四个block中。这种数据存取的方法称为索引式文件系统(indexed allocation),Linux的文件系统就采用这种方式:

 

        文件系统一开始就将 inode 与 block 规划好了,除非重新格式化(或者利用 resize2fs 等命令变更文件系统大小),否则 inode 与 block 固定后就不再变动。

        另外,文件系统在格式化的时候基本上是分为多个柱面组的,每个柱面组都有独立的 inode/block/superblock 系统。

 

        而且,还有一个block bitmap (区块对照表),该表记录了block的状态,比如哪些block是未使用的,哪些是已使用的。inode同样有一个记录inode状态的inodemap,记录那些inode是未使用的。

        每个区段与 super block 的信息都可以使用 dumpe2fs 这个命令来查询!

 

        如下图,表示一个分区的结构图:

 

        inode是固定长度的记录项,包含文件的大部分信息。

        另外,当创建一个目录时,会分配一个inode与至少一块block给该目录。其中,inode 记录该目录的相关权限与属性,并记录该目录分配到的那块block号码;而block则是记录,在这个目录下的,所有文件的文件名,以及该文件的inode号。结构图如下:

        目录的block存储目录项,目录项包含该目录下,所有文件的文件名和inode号。通过inode号,就可以得到该文件的实际内容。

        上图中,有两个目录项指向同一个inode。每个inode都有一个链接计数,其值是指向该inode的目录项数。只有当链接计数为0时,才可以删除文件。

        这也是硬链接的基本原理。多个目录项对应到同一个 inode 号上,就是硬链接了。因此,一般来说,使用硬链接,磁盘的空间与inode的数目都不会改变!硬链接的限制有:不能跨文件系统;不能链接目录。

 

        而软链接,就是在创建一个独立的文件,该文件的实际内容(数据块)中,包含了它所指向的文件的名字。

        使用ln命令,可以创建硬链接或软链接。

 

2:挂载

        Linux内的所有数据都是以文件的形态来呈现的,所有文件组成一个树状的层次结构,该结构以”/”为根目录。如下图所示:

 

        这种树状层次结构,是如何与硬盘内的数据结合呢?这就是“挂载”(mount)了。

 

        所谓的“挂载”,就是用一个目录作为进入点,将磁盘分区的数据放置在该目录下;也就是说,进入该目录就可以读取该分区的内容。这个动作称为“挂载”,进入点的目录称为“挂载点”。

        整个Linux系统最重要的是根目录,因此根目录一定需要挂载到某个分区。其他的目录则可依需求,挂载到不同的分区。如下图:

 

四:命令

        针对一个全新的硬盘,需要采取以下动作才能使用:

        a:对磁盘进行分区;

        b:对该分区进行格式化,以创建系统可用的文件系统;

        c:若想要仔细一点,则可对刚刚创建好的文件系统进行检验;

        d:在 Linux 系统上,创建挂载点,并将文件系统挂载上来;

 

1:分区

        fdisk命令用于对磁盘进行分区操作,比如列出磁盘分区信息,增加分区,删除分区等。

        通过fdisk -l命令,可以列出所有的磁盘信息;若要针对某块磁盘操作,则直接在fdisk后跟磁盘名即可:

# fdisk /dev/hdc
The number of cylinders for this disk is set to 5005.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help):  

        注意,fdisk后跟的是磁盘名,而非分区名, 因此在/dev/hdc后无需加数字,否则会出错。    输入m后,可以列出所有帮助信息。

Command (m for help): m   <== 输入 m 后,就会看到底下这些命令介绍
Command action
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition            <==删除一个partition
   l   list known partition types
   m   print this menu
   n   add a new partition           <==新增一个partition
   o   create a new empty DOS partition table
   p   print the partition table     <==在屏幕上显示分割表
   q   quit without saving changes   <==不储存离开fdisk程序
   s   create a new empty Sun disklabel
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit  <==将刚刚的动作写入分割表
   x   extra functionality (experts only)

2:格式化

        mkfs命令用来对分区进行格式化。该命令实际上是一个命令集合:

root@ubuntuhh:~# mkfs[Tab][Tab]
mkfs          mkfs.cramfs   mkfs.ext3     mkfs.ext4dev  mkfs.minix    mkfs.ntfs     
mkfs.bfs      mkfs.ext2     mkfs.ext4     mkfs.fat      mkfs.msdos    mkfs.vfat 

        使用mkfs -t ext3,实际上调用的是mkfs.ext3

 

3:挂载

        mount命令就是用于将文件系统挂载到树状层级结构中,而umount命令则相反,用于解除挂载。

        mount的标准用法是:mount –t type device dir

        该命令,将类型为type,device上的文件系统,attach到dir上。dir之前的内容、拥有者以及访问模式等都不再可见。

 

        自Linux2.4.0开始,允许将某些目录remount到其他目录上:mount--bind olddir newdir。执行上述命令后,同样的内容会出现在两个目录上,比如:

[root@hh ~]# mount --bind / /root/testdir2
[root@hh ~]# ls /root/testdir2
bin     data  lib         misc  proc                salt-syndic.log  sys  zabbix
boot    dev   lib64       mnt   redis-3.0.5         sbin             tmp
cache   etc   lost+found  net   redis-3.0.5.tar.gz  selinux          usr
cgroup  home  media       opt   root                srv              var

        可见/root/testdir2的内容跟/一样了。甚至可以将单个文件remount到单个文件上。

[root@hh testdir]# touch 1.txt
[root@hh testdir]# touch 2.txt
[root@hh testdir]# mount --bind 1.txt 2.txt
[root@hh testdir]# echo "hello, world" > 1.txt 
[root@hh testdir]# cat 2.txt 
hello, world

        此时查看mount的输出:

[root@hh testdir]# mount
/dev/mapper/vg_hh-lv_root on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw,rootcontext="system_u:object_r:tmpfs_t:s0")
/dev/sda1 on /boot type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
.host:/ on /mnt/hgfs type vmhgfs (rw,ttl=1)
vmware-vmblock on /var/run/vmblock-fuse type fuse.vmware-vmblock (rw,nosuid,nodev,default_permissions,allow_other)
/ on /root/testdir2 type none (rw,bind)
/root/testdir/1.txt on /root/testdir/2.txt type none (rw,bind)

        但是,--bind只能处理单一文件系统,也就是说,如果olddir中的子目录存在submount的情况,则bind不会连同submount一起bind。比如,在上面例子的情况下:

[root@hh ~]# df -h
Filesystem                 Size  Used Avail Use% Mounted on
/dev/mapper/vg_hh-lv_root   27G  8.8G   17G  36% /
tmpfs                      747M   72K  747M   1% /dev/shm
/dev/sda1                  485M   63M  397M  14% /boot
.host:/                    201G  105G   96G  53% /mnt/hgfs
 
[root@hh ~]# ll testdir2/boot
total 0
[root@hh ~]# ls /boot
config-2.6.32-431.el6.x86_64         initramfs-3.8.13-16.2.1.el6uek.x86_64.img  System.map-3.8.13-16.2.1.el6uek.x86_64
config-3.8.13-16.2.1.el6uek.x86_64   lost+found                                 vmlinuz-2.6.32-431.el6.x86_64
efi                                  symvers-2.6.32-431.el6.x86_64.gz           vmlinuz-3.8.13-16.2.1.el6uek.x86_64
grub                                 symvers-3.8.13-16.2.1.el6uek.x86_64.gz

        可见,/boot中的内容,并没有mount到/root/testdir2/boot目录下。如果希望submount一起挂载的情况,可以使用--rbind选项:

[root@hh ~]# umount /root/testdir2
[root@hh ~]# ll testdir2
total 0
[root@hh ~]# mount --rbind / /root/testdir2
[root@hh ~]# ls /root/testdir2
bin     data  lib         misc  proc                salt-syndic.log  sys  zabbix
boot    dev   lib64       mnt   redis-3.0.5         sbin             tmp
cache   etc   lost+found  net   redis-3.0.5.tar.gz  selinux          usr
cgroup  home  media       opt   root                srv              var

[root@hh ~]# ls /root/testdir2/boot
config-2.6.32-431.el6.x86_64         initramfs-3.8.13-16.2.1.el6uek.x86_64.img  System.map-3.8.13-16.2.1.el6uek.x86_64
config-3.8.13-16.2.1.el6uek.x86_64   lost+found                                 vmlinuz-2.6.32-431.el6.x86_64
efi                                  symvers-2.6.32-431.el6.x86_64.gz           vmlinuz-3.8.13-16.2.1.el6uek.x86_64
grub                                 symvers-3.8.13-16.2.1.el6uek.x86_64.gz
initramfs-2.6.32-431.el6.x86_64.img  System.map-2.6.32-431.el6.x86_64

        可见,/boot已经mount到/root/testdir2/boot下了。

 

        自linux2.5.1开始,允许将一个mount点移动到其他地方,使用以下命令即可:mount--move olddir newdir

        proc文件系统不与任何设备关联,当挂载它时,可以指定任意字符串,比如proc,来表示一个设备。(不要使用none,否则umount时可能会有歧义)。

 

        umount命令用于detach设备上的文件系统与树状文件层级的关联。可以通过文件系统的mount点,除了当该设备mount到多个目录上时,也可以通过给定设备来执行mount。

 

4:/etc/fstab和/etc/mtab

        系统启动时,会根据/etc/fstab文件进行挂载。

        /etc/fstab文件记录了各种文件系统的信息,每一行描述了一个文件系统。行中的字段以tabs或者空格进行分隔。以’#’开头的行是注释行。该文件中的行顺序很重要,因为fsck、mount和umount命令都是顺序遍历该文件进行工作的。

        第一个字段,表示设备;第二个字段表示文件系统的mount点;第三个字段表示文件系统的类型;第四个字段表示文件系统的挂载选项;第五个字段用于dump命令,判断该文件系统是否需要dump,如果该字段为0,则表示无需dump;第六个字段用于fsck命令,决定在系统启动时文件系统的检查顺序。

 

        文件/etc/fstab中,每行描述了哪些设备,使用什么选项,mount到哪个目录上。该文件通常用在以下三种场景下:

        a:命令mount -a[-t type] [-O optlist],该命令会根据fstab文件中(合适的type,或者options)中的内容,进行mount,除了那些包含noauto关键字的行。使用-F选项,可以使得mount并行处理。

        b:当用mount命令,处理在fstab中记录的某个文件系统时,可以仅给出设备,或者挂载点即可。

        c:一般情况下,只有超级用户可以mount文件系统,但是,如果fstab文件中的某行包含user选项,则任何用户可以挂载相应的文件系统。

        因此,比如文件中有内容:/dev/cdrom  /cd  iso9660 ro,user,noauto,unhide,则任何用户都可以将CDROM中上的iso9660文件系统进行挂载,直接使用以下命令即可:mount  /dev/cdrom       或      mount  /cd

        只有执行mount的用户才可以进行umount,如果希望所有用户都可以umount则可以在fstab中,使用users来代替user。

 

        mount和umount在文件/etc/mtab中,维护当前挂载的文件系统情况。如果mount命令不加任何参数,则该命令会打印出该文件中内容。

 

参考:

http://vbird.dic.ksu.edu.tw/linux_basic/0230filesystem_3.php

http://blog.csdn.net/badbad_boy/article/details/4313645

https://www.zhihu.com/question/20537787

http://vbird.dic.ksu.edu.tw/linux_basic/0230filesystem_1.php

原文地址:https://www.cnblogs.com/gqtcgq/p/7247068.html