Linux内核API vfs_getattr

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,会出现如图所示的结果。

Linux内核API vfs_getattr

结果分析:

vfs_getattr()函数返回值为0,表示能够成功获得虚拟文件系统的属性,同时,在该函数中还执行了generic_fillattr()函数,即对vfs的kstat结构体进行赋值。从显示结果来看,inode和kstat结构体之间相对应的值都相同,已经成功赋值操作

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程