好的,我们来深入学习 statfs 系统调用
1. 函数介绍
在 Linux 系统中,文件和目录都存储在各种各样的文件系统之上,比如你系统盘常用的 ext4,或者 U 盘上的 vfat (FAT32)。每个文件系统都有自己的特性,比如总容量多大、现在用了多少、还剩多少空间、文件名最长支持多少个字符等等。
data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">statfs (Stat File System) 系统调用的作用就是查询指定路径所在文件系统的各种统计信息和属性。
你可以把它想象成一个“文件系统信息查询器”。你随便给它一个路径(比如 /home, /tmp, /mnt/my_usb),它就能告诉你这个路径所在的那个磁盘分区(文件系统)的详细情况。
简单来说,statfs 就是让你用程序来查看某个磁盘分区或挂载点的“健康报告”和“容量信息”。
典型应用场景:
磁盘空间监控:检查磁盘剩余空间,防止程序因磁盘写满而崩溃。
系统信息工具:像 df 命令就是使用 statfs (或类似的 statvfs) 来显示磁盘使用情况的。
文件系统类型检查:确认某个挂载点使用的是什么类型的文件系统(例如,检查 /tmp 是否是 tmpfs)。
资源管理:根据可用空间决定是否执行某些操作。
2. 函数原型
1 | #include <sys/vfs.h> // 包含系统调用声明 (在某些系统上可能是 <sys/statfs.h>) |
3. 功能
获取指定路径 (path) 或文件描述符 (fd) 所在文件系统的统计信息,并将结果存储在 buf 指向的 struct statfs 结构体中。
4. 参数
path:
const char * 类型。
指向一个以 null 结尾的字符串,表示文件系统中的任意一个路径名。函数会查询这个路径所在的文件系统的统计信息。
fd:
int 类型。
一个已打开文件的有效文件描述符。fstatfs 会查询该文件描述符对应的文件所在的文件系统的统计信息。
buf:
struct statfs * 类型。
一个指向 struct statfs 结构体的指针。函数调用成功后,会将查询到的文件系统信息填充到这个结构体中。
5. 返回值
成功: 返回 0。
失败: 返回 -1,并设置全局变量 errno 来指示具体的错误原因。
6. 错误码 (errno)
EACCES: (对于 statfs) 搜索 path 中的一个或多个组件时权限不足。
EFAULT: path 或 buf 指向了调用进程无法访问的内存地址。
EIO: I/O 错误(例如,读取文件系统超级块失败)。
ELOOP: 解析 path 时遇到符号链接循环。
ENAMETOOLONG: path 太长。
ENOENT: path 指定的文件或目录不存在。
ENOMEM: 内核内存不足。
ENOSYS: 系统不支持 statfs。
ENOTDIR: path 的某个前缀不是目录。
EOVERFLOW: 结构体中的某些值溢出。
EBADF: (对于 fstatfs) fd 不是有效的文件描述符。
7. struct statfs 结构体
这个结构体包含了文件系统的各种信息。主要成员包括(定义可能因架构和内核版本略有不同):
1 | struct statfs { |
关键字段解释:
f_bsize: 这是文件系统推荐用于 I/O 操作的块大小。进行读写操作时使用这个大小通常效率最高。
f_blocks: 文件系统总共有多少个块。
f_bfree: 文件系统总共有多少个空闲块。
f_bavail: 对普通用户(非 root)来说,实际还可以使用的空闲块数量。有些文件系统会保留一部分空间给 root 用户,以防系统关键进程因磁盘满而无法运行。
f_files: 文件系统总共包含多少个 Inode(索引节点)。每个文件或目录都对应一个 Inode。
f_ffree: 文件系统中空闲的 Inode 数量。
f_type: 文件系统的类型,用一个魔数 (Magic Number) 表示。例如,EXT4_SUPER_MAGIC (0xEF53) 代表 ext4,TMPFS_MAGIC (0x01021994) 代表 tmpfs。可以通过比较这个值来判断文件系统类型。
f_namelen: 文件系统支持的文件名或目录名的最大长度。
8. 相似函数或关联函数
statvfs / fstatvfs: POSIX 标准定义的函数,功能与 statfs / fstatfs 几乎相同,但使用 struct statvfs 结构体。通常推荐使用 statvfs 以获得更好的可移植性。
df: 命令行工具,显示文件系统磁盘空间使用情况。它在底层调用的就是 statfs 或 statvfs。
getmntent: 用于读取 /proc/mounts 或 /etc/mtab 文件,获取系统上所有已挂载文件系统的信息。
du: 命令行工具,估算文件和目录的空间使用情况。它通过遍历目录和文件来计算,而不是查询文件系统元数据。
9. 示例代码
下面的示例演示了如何使用 statfs 来查询不同路径的文件系统信息。
1 | #define _GNU_SOURCE // 启用 GNU 扩展 |
10. 编译和运行
1 | # 假设代码保存在 statfs_example.c 中 |
11. 预期输出 (片段)
1 | --- Demonstrating statfs --- |
12. 总结
statfs 是一个非常实用的系统调用,用于获取文件系统级别的信息。它对于系统管理、磁盘监控和资源检查类的应用程序非常有价值。通过检查空闲块数 (f_bavail) 和块大小 (f_bsize),可以轻松计算出可用磁盘空间,这对于防止程序因磁盘写满而出错至关重要。理解 struct statfs 中各个字段的含义是使用此函数的关键。