磁盘和分区
常规文件和目录通常存放在硬盘里。可将每块磁盘划分为一个或多个不重叠的分区,内核将每个分区视为位于/dev路径下单独设备。
磁盘分区主要是以下三种之一:文件系统、数据区域(可做裸设备对其访问)、交换区域(供虚拟内存使用)。
文件系统
文件系统是对常规文件和目录的组织集合。在文件系统中,用来分配空间的基本单位是逻辑块,即文件系统所在磁盘设备上若干连续的物理块。在ext2文件系统中,逻辑块的大小为1024、2048、4096字节。
磁盘分区和文件系统之间的关系如下:
文件系统主要由以下部分组成:
- 引导块:文件系统的首块
- 超级块:包含文件系统有关的参数信息:i节点表容量、文件系统中逻辑块大小、以逻辑块计数的文件系统大小
- i节点表:文件系统中每个文件或者目录在i节点表中都有对应着唯一一条记录,记录关于文件的各种信息。
- 数据块:文件系统中大部分空间都用于存放数据。
i节点
针对文件系统上的每个文件,文件系统的i节点表都会有一个i节点(索引节点)。主要记录以下信息:
- 文件类型(常规文件、目录、符号链接、字符设备等)
- 文件属主(UID)和文件属组(GID)
- 属主、属组、其他用户的访问权限
- 3个时间戳(最后访问时间、最后修改时间、文件状态最后改变时间)
- 文件的硬链接数量
- 文件大小,以字节为单位
- 实际分配给文件的块数量
- 指向文件数据块的指针
ext2文件系统中,i节点结构如下。每个i节点包含15指针,其中前12个指针指向文件前12个块在文件系统中的位置,接下来是一个指向指针块的指针,提供了文件第13个及后续数据块的位置。指针块中指针数量取决于文件系统中块的大小:
这样设计的优点:
- 在维持i节点结构大小固定的同时,支持任意大小的文件
- 文件系统即可以以不连续方式来存储文件块,又可以通过lseek()随机访问文件
- 因为大多数系统中的文件是小文件,这样设计满足快速对文件数据块的访问,即通过i节点直接指针访问。
虚拟文件系统
虚拟文件系统是一种内核特性,通过为文件系统创建抽象层来解决不同文件系统的不同点。VFS针对文件系统定义了一套通用的接口,所有与文件交互的程序都按照这一接口来操作,这样程序就只用访问VFS接口,而不同了解不同文件系统之间的具体实现细节。
文件属性
通过系统调用stat()、lstat()、fstat()获取文件相关信息。
#include <sys/stat.h>
int stat(const char *pathname,struct stat *statbuf);
int lstat(const char *pathname,struct stat *statbuf);
int fstat(int fd,struct stat *statbuf);
struct stat{
dev_t st_dev; //文件驻留设备id
ino_t st_ino; //文件i节点
mode_t st_mode; //文件类型
nlink_t st_nlink; //硬链接数
uid_t st_uid; //UID
gid_t st_gid; //GID
dev_t st_rdev;
off_t st_size; //文件字节数
blksize_t st_blksize; //IO最优块大小
blkcnt_t st_blocks; //总块数
time_t st_atime; //时间戳
time_t st_mtime;
time_t st_ctime;
}
参考 《TLPI》、《APUE》