vfs_getattr()函数的作用是得到当前虚拟文件系统的属性。首先将目录下的节点赋值给新声明的inode结构体,执行函数security_inode_getattr(),如果是得到的值大于0,则返回该值,若不大于0,则继续执行inode中操作函数getattr(),若仍小于0,则执行generic_fillattr,最后返回值为0。
vfs_getattr文件包含
#include <linux/fs.h>
vfs_getattr函数定义
在内核源码中的位置:linux-3.19.3/fs/stat.c
函数定义格式:
int vfs_getattr(struct path * path, struct kstat *stat)
vfs_getattr输入参数说明
path:定义见文件linux-3.19.3/include/linux/path.h。
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
};
- 其中
mnt
为判断在内核里是否属于私有的vfsmount结构体,其定义及详细说明参考极客笔记中__mnt_is_readonly()函数函数的参数说明部分。dentry为判断在内核里是否属于私有的dentry,其定义及详细说明参考极客笔记中d_alloc ()函数的参数说明部分。 stat
:要被赋值的kstat结构体,其定义及详细说明参考极客笔记中generic_fillattr()函数的参数说明部分。
vfs_getattr返回参数说明
vfs_getattr()
函数返回值为整型,即0或者错误码。返回0表示已经成功获取了vfs的属性,若不返回0则表示出错。
vfs_getattr实例解析
编写测试文件:vfs_getattr.c
头文件声明如下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/path.h>
#include <linux/sched.h>
MODULE_LICENSE("GPL");
自定义kstat结构体:
struct kstat stat=
{
.nlink = 10,
};
模块初始化函数定义:
// 模块初始化函数
int __init vfs_getattr_init(void)
{
int data1;
struct dentry *dentry;
struct vfsmount *vfs;
struct inode *inode;
struct path path;
dentry = current->fs->pwd.dentry;
vfs = current->fs->pwd.mnt;
inode = dentry->d_inode;
path.mnt=vfs;
path.dentry = dentry;
// 输出原始初值
printk("Current \"vfs_getattr\", stat.dev = %d\n", stat.dev);
printk("Current \"vfs_getattr\", stat.ino = %d\n", stat.ino);
printk("Current\"vfs_getattr\", stat.mode = %d\n", stat.mode);
printk("Current \"vfs_getattr\", stat.nlink = %d\n", stat.nlink);
printk("Current \"vfs_getattr\", stat.uid = %d\n", stat.uid);
printk("Current \"vfs_getattr\", stat.gid = %d\n", stat.gid);
printk("inode->i_sb->s_dev = %d\n", inode->i_sb->s_dev);
printk("inode->i_ino = %d\n", inode->i_ino);
printk("inode->i_mode = %d\n", inode->i_mode);
printk("inode->i_nlink = %d\n", inode->i_nlink);
printk("inode->i_uid = %d\n", inode->i_uid);
printk("inode->i_gid = %d\n", inode->i_gid);
// 获取当前虚拟文件系统的属性
data1= vfs_getattr(&path, &stat);
printk("The returned result of \"vfs_getattr\" is :%d\n", data1);
printk("After \"vfs_getattr\", stat.dev = %d\n", stat.dev);
printk("After \"vfs_getattr\", stat.ino = %d\n", stat.ino);
printk("After \"vfs_getattr\", stat.mode = %d\n", stat.mode);
printk("After \"vfs_getattr\", stat.nlink = %d\n", stat.nlink);
printk("After \"vfs_getattr\", stat.uid = %d\n", stat.uid);
printk("After \"vfs_getattr\", stat.gid = %d\n", stat.gid);
return 0;
}
模块退出函数:
void vfs_getattr_exit(void)
{
printk("Goodbye vfs_getattr\n");
}
模块初始化及退出函数调用:
module_init(vfs_getattr_init);
module_exit(vfs_getattr_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod vfs_getattr.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
结果分析:
vfs_getattr()函数返回值为0,表示能够成功获得虚拟文件系统的属性,同时,在该函数中还执行了generic_fillattr()函数,即对vfs的kstat结构体进行赋值。从显示结果来看,inode和kstat结构体之间相对应的值都相同,已经成功赋值操作