f_type:文件系统的魔术数(magic number),用于标识文件系统类型(如 EXT4 为 0xEF53)。
f_bsize:文件系统的块大小,是进行 I/O 操作的最优单位。
f_blocks/f_bfree/f_bavail:分别表示总块数、空闲块数、普通用户可使用的空闲块数(可能受配额限制)。
f_files/f_ffree:总 inode 数和空闲 inode 数(对应 df -i 命令显示的信息)。
f_namelen:该文件系统支持的最大文件名长度。
f_flags:文件系统的挂载标志(如只读、同步写入等)。
struct kstatfs {
__u64 f_type; /* 文件系统类型(如 EXT4_SUPER_MAGIC) */
__u64 f_bsize; /* 块大小(文件系统的最优 I/O 块大小) */
__u64 f_blocks; /* 总块数(以 f_bsize 为单位) */
__u64 f_bfree; /* 空闲块数 */
__u64 f_bavail; /* 非特权用户可使用的空闲块数 */
__u64 f_files; /* 总 inode 数 */
__u64 f_ffree; /* 空闲 inode 数 */
__kernel_fsid_t f_fsid; /* 文件系统标识符 */
__u64 f_namelen; /* 最大文件名长度 */
__u64 f_frsize; /* fragment 大小(文件系统的基本块大小) */
__u64 f_flags; /* 文件系统标志(如 ST_RDONLY 等) */
__u64 f_spare[4]; /* 预留字段,用于未来扩展 */
};
#include <linux/init.h> // 包含模块初始化相关函数
#include <linux/module.h> // 包含模块相关宏定义
#include <linux/kernel.h> // 包含内核相关函数,如printk
#include <linux/fs.h>
#include <linux/statfs.h>
#include <linux/fs_struct.h>
// 模块加载函数,当模块被加载时调用
static int __init hello_init(void)
{
// 返回0表示加载成功
int result=0,i=0;
struct path *current_path;
struct kstatfs buf; // 用于存储文件系统信息的结构体
printk(KERN_INFO "Entering vfs_stats_init\n");
current_path = ¤t->fs->pwd;
if (!current_path->dentry) {
printk(KERN_ERR "Failed to get current path\n");
return -1;
}
// 调用vfs_statfs,传递struct path指针(修正参数类型)
result = vfs_statfs(current_path, &buf);
if (result < 0) {
printk(KERN_ERR "vfs_statfs failed with error: %d\n", result);
return result;
}
// 打印文件系统信息
printk(KERN_INFO "File system information:\n");
printk(KERN_INFO " f_bsize: %ld (块大小,字节)\n", buf.f_bsize);
printk(KERN_INFO " f_frsize: %ld (片段大小,字节)\n", buf.f_frsize);
printk(KERN_INFO " f_blocks: %ld (总块数)\n", buf.f_blocks);
printk(KERN_INFO " f_bfree: %ld (空闲块数)\n", buf.f_bfree);
printk(KERN_INFO " f_bavail: %ld (可用块数,非root用户)\n", buf.f_bavail);
printk(KERN_INFO " f_files: %ld (总inode数)\n", buf.f_files);
printk(KERN_INFO " f_ffree: %ld (空闲inode数)\n", buf.f_ffree);
printk(KERN_INFO " f_namelen: %ld (最大文件名长度)\n", buf.f_namelen);
printk ("<0>out vfs_stats_init\n");
return 0;
}
// 模块卸载函数,当模块被卸载时调用
static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye, World! Linux driver unloaded\n");
}
// 注册模块加载和卸载函数
module_init(hello_init);
module_exit(hello_exit);
// 模块许可证声明,必须要有,否则加载时会报警告
MODULE_LICENSE("GPL");
// 模块作者信息
MODULE_AUTHOR("Camera");
// 模块描述信息
MODULE_DESCRIPTION("A simple Linux driver - Hello World");
// 模块版本信息
MODULE_VERSION("0.1");
df -i //用于查看文件系统的 inode 使用情况
dmesg -c // -c clear 清空该缓冲区,后续使用dmesg命令将只能看到此操作之后新产生的内核消息
输出中Inodes表示总inode数(系统可创建的最大文件数上限),
IUsed表示已使用的inode数(近似等于已创建的文件/目录总数,因每个文件/目录对应一个inode)