APUE—UNIX文件系统


在linux系统中——一切都是文件。

1. 磁盘物理结构

磁盘的物理结构如下:

 

磁盘由很多盘面组成,而盘面上则是由很多同心圆环组成的磁道,每个磁道又被切割成许多扇区。所有磁盘面的同一个磁道构成一个柱面,同一柱面的所有磁道写完后,才会移入下一柱面。

磁盘的最小组成单位可以看成扇区,每个扇区的大小逻辑上看起来是512字节,但实际上底层的物理扇区是4096字节,可以通过如下方式去得到:

gqx@gqx-Lenovo-Product:~$ sudo fdisk -l 
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

  由于扇区太小了,如果实际操作的时候按扇区为单位去读写数据的效率比较低,就比如10M的文件,磁头就需要读取(1024*10/512)20480次移动操作,所以一般都是用块(多个扇区)这个逻辑概念来实现具体的读写操作,一个块的大小通常是4096个字节:

gqx@gqx-Lenovo-Product:~$ sudo tune2fs -l /dev/sda4 | grep "Block size"
Block size:               4096

2. 文件系统的结构

  在UNIX系统里当我们将上述的磁盘结构上升一层到具体的文件层面时,就会将磁盘划分成很多个分区,每个分区对应一个文件系统,磁盘、分区和文件系统的结构如下:

 

  • 自举块:也称为引导块,分区中文件系统自身引导程序存放的地方。

  • 超级块:超级块在每个文件系统的根上,超级块描述和维护文件系统的状态。

  • ......

这里只关注柱面组里的i节点和数据块部分结构,其中数据块存放着文件的具体内容,如下图:

4.文件的权限位

  这里不再简单的论述九个简单(r,w,x)权限位,而是对其余三个(和三个角色的最后一位执行权限共享位表示)做解释:

  1. setuid:设置使文件在执行阶段具有文件所有者的权限。比如一般用户想要更改自己的登入密码,而这个文件是存放在/etc/shadow下的,但是只有root才有权限去读写,这个时候就需要/usr/bin/passwd文件来帮我们完成。

    gqx@gqx-Lenovo-Product:~/桌面$ ll /usr/bin/passwd 
    -rwsr-xr-x 1 root root 54256 5月  17  2017 /usr/bin/passwd*

    通过执行该命令,系统看到passwd命令文件的属性有小写s后,表示这个命令的属主权限被gqx用户获得,也就是gqx用户获得文件/etc/shadow的读写权限。

  2. setgid:该权限只对目录有效。目录被设置该位后,任何用户在此目录下创建的文件都具有和该目录所属的组相同的组。

  3. sticky bit(粘着位):该位可以理解为防删除位。 一个文件是否可以被某用户删除,主要取决于该文件所属的组是否对该用户具有写权限。如果没有写权限,则这个目录下的所有文件都不能被删除,同时也不能添加新的文件。 如果希望用户能够添加文件但同时不能删除文件,则可以对文件使用sticky bit位。设置该位后,就算用户对目录具有写权限也不能删除该文件。(比如ubuntu里的目录/tmp和/var/tmp, 除文件所有者外,超级用户也有权限删除,其他用户没有权限)

当前用户可以通过umask(既是C函数,也是shell的一个命令)来控制创建文件的权限:

gqx@gqx-Lenovo-Product:~/shellTest$ umask 
0002
gqx@gqx-Lenovo-Product:~/shellTest$ touch a
-rw-rw-r-- 1 gqx gqx    0 7月   3 14:14 a
gqx@gqx-Lenovo-Product:~/shellTest$ umask 0022
gqx@gqx-Lenovo-Product:~/shellTest$ umask
0022
gqx@gqx-Lenovo-Product:~/shellTest$ touch b
gqx@gqx-Lenovo-Product:~/shellTest$ ls -l
-rw-rw-r-- 1 gqx gqx    0 7月   3 14:14 a
-rw-r--r-- 1 gqx gqx    0 7月   3 14:26 b
#创建新文件:读写权限为666-022=644

  参考资料:

    《UNIX环境高级编程》