Linux内核API d_find_alias

函数d_find_alias()通过一个拥有别名的inode结构体,来获取具有该inode结构体的目录结构体。

d_find_alias文件包含

#include <linux/dcache.h>

d_find_alias函数定义

在内核源码中的位置:linux-3.19.3/fs/dcache.c

函数定义格式:

struct dentry * d_find_alias(struct inode *inode)

d_find_alias输入参数说明

  • inode:要分配在根dentry结构体上的inode结构体,定义见文件linux-3.19.3/include/linux/fs.h,如下:
struct inode {
    umode_t                          i_mode;         /*该节点的模式*/
    unsigned short                   i_opflags;
    kuid_t                  i_uid;   /*所有者标识符*/
    kgid_t                  i_gid;   /*组标识符*/
    unsigned int            i_flags;                 /*文件系统的安装标志*/
#ifdef CONFIG_FS_POSIX_ACL
    struct posix_acl * i_acl;
    struct posix_acl * i_default_acl;
#endif
    const struct inode_operations            *i_op;   /*节点的操作函数*/
    struct super_block      *i_sb;          /*指向超级块的指针*/
    struct address_space *i_mapping;        /*指向address_space对象的指针*/
#ifdef CONFIG_SECURITY
    void                      *i_security;    /*指向索引节点安全结构的指针*/
#endif
    unsigned long             i_ino;           /*索引节点号*/
    unioc {
        const unsigned int i_nlink;            /*硬链接的数目*/
        unsigned int __i_nlink;
    };
    dev_t                     i_rdev;          /*实设备标识符*/
    loff_t                    i_size;          /*文件的字节数*/
    struct timespec           i_atime;         /*上次访问文件的时间*/
    struct timespec           i_mtime;         /*上次写文件的时间*/
    struct timespec           i_ctime;         /*上次修改索引节点的时间*/
    spinlock_t                i_lock;          /*保护索引节点一些字段的自旋锁*/
    unsigned short            i_bytes;         /*文件中最后一个块的字节数*/
    unsigned int              i_blkbits;       /*块的位数*/
    blkcnt_t                  i_blocks;        /*文件的块数*/
#ifdef __NEED_I_SIZE_ORDERED
    seqcount_t                i_size_seqcount; /*系统为i_size字段获取一致值时视同的顺序计数器*/
#endif
    unsigned long             i_state;
    struct mutex              i_mutex;         /*节点的信号量*/
    unsigned long             dirtie_when;
    struct hlist_node         i_hash;          /*用于散列表的指针*/
    struct list_head          i_wb_list;       /*dev IO的备份列表指针*/
    struct list_head          i_lru;           /*节点的LRU链表*/
    struct list_head          i_sb_list;       /*用于超级块的索引节点链表的指针*/
    union {
        struct hlist_headi_dentry;             /*引用索引节点的目录项对象链表的头*/
        struct rcu_head       i_rcu;           /*RCU链表的头指针*/
    };
    u64                       i_version;       /*版本号*/
    atomic_t                  i_count;         /*引用计数器*/
    atomic_t                  i_dio_count;     /*dio的计数器*/
    atomic_t                  i_writecount;    /*用于写进程的引用计数器*/
#ifdef CONFIG_IMA
    atomic_t                  i_readcount;     /*读计数器*/
#endif
    const struct file_operations *i_fop; /*former ->i_op->default_file_ops */
    struct file_lock          *i_flock;       /*指向文件锁链表的指针*/
    struct address_space i_data;               /*文件的address_space对象*/
    struct list_head          i_devices;       /*用于具体的字符和块设备索引节点链表的指针*/
    union {
        struct pipe_inode_info * i_pipe; /*如果文件是一个管道,则使用它*/
        struct block_device     * i_bdev; /*指向块设备驱动程序的指针*/
        struct cdev           * i_cdev;       /*指向字符设备驱动程序的指针*/
    };
    __u32                     i_generation;
#ifdef CONFIG_FSNOTIFY
    __u32          i_fsnotify_mask;            /*目录通知事件的位掩码*/
    struct hlist_head     i_fsnotify_marks; /*位掩码链表头指针*/
#endif
    void                    *i_private;    /*文件或设备的私有指针 */
};

d_find_alias返回参数说明

  • d_find_alias()函数的返回结果有两种可能:NULL和dentry结构体类型的变量。如果返回值为NULL,则说明没有相应的inode结构体;如果返回值是dentry结构体,则说明已找到了相应的inode结构体的dentry结构体。

d_find_alias实例解析

编写测试文件:d_find_alias.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");

模块初始化函数:

int d_find_alias_init(void)
{
    struct inode *inode;
    struct dentry *dentry_alias;
    inode = current->fs->pwd.dentry->d_inode;     //获取当前文件的入口目录的结点
    struct dentry *dentry_pwd = current->fs->pwd.dentry;  //获取当前文件的入口目录
    printk("The name of current dentry is %s\n", dentry_pwd->d_name.name);
                                                  // 显示当前文件的入口目录名
    dentry_alias = d_find_alias(inode);           //获取inode结构体的目录结构体信息
    // 显示函数获取的入口目录名
    printk("After \"d_find_alias\", The name of current dentry is %s\n", dentry_alias->d_name.name);
    return 0;
}

模块退出函数:

void d_find_alias_exit(void)
{
    printk("Goodbye d_find_alias\n");
}

模块初始化及退出函数调用:

module_init(d_find_alias_init);
module_exit(d_find_alias_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod d_find_alias.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。

Linux内核API d_find_alias

结果分析:

在函数d_find_alias()的调用中通过对当前目录的inode结构体作为参数传进去,得到了返回值,而返回值的目录名也为d_find_alias,和当前目录名相同,因此d_find_alias函数能够实现通过inode别名查找目录的操作。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程