首页 > 其他分享 >内核hlist分析

内核hlist分析

时间:2024-05-22 15:33:20浏览次数:16  
标签:分析 hash struct lock hlist sbi inode 内核

一. 参考网址

  1. Linux 内核 hlist 详解

  2. Linux内核中的数据结构与算法(三)哈希链表

二. 源码

  1. 哈希表操作函数:include/linux/list.h

  2. 哈希表结构体定义:include/linux/types.h

  3. 两个重要结构体定义:

//hash桶的头结点
struct hlist_head {
    struct hlist_node *first;//指向每一个hash桶的第一个结点的指针
};
//hash桶的普通结点
struct hlist_node {
    struct hlist_node *next;//指向下一个结点的指针
    struct hlist_node **pprev;//指向上一个结点的next指针的地址
};

三. 疑问

1. hlist_add_head函数

1.1 源码

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
    struct hlist_node *first = h->first;
    n->next = first;
    if (first)
        first->pprev = &n->next; //为什么不用first->pprev=&n?
    h->first = n;
    n->pprev = &h->first;
}

解答:将 first->pprev = &n->next; 作为指针赋值的方式,确保了代码的灵活性和健壮性。无论 struct hlist_node 结构体内部成员的顺序如何排列,都可以正确地获取到 next 成员的地址,这使得代码更加健壮和易于维护。因此,这种方式在实际编程中是一种良好的做法,可以减少因为结构体成员顺序变化而导致的错误

四. linux内核代码运用示例

 参考内核代码: fs/fat/inode.c(fat文件系统管理)

1. 初始化哈希表

static void fat_hash_init(struct super_block *sb)
{
    struct msdos_sb_info *sbi = MSDOS_SB(sb);
    int i;

    spin_lock_init(&sbi->inode_hash_lock);
    for (i = 0; i < FAT_HASH_SIZE; i++)
        INIT_HLIST_HEAD(&sbi->inode_hashtable[i]);   //初始化其firs指针为空
}

2. 增加哈希表节点

void fat_attach(struct inode *inode, loff_t i_pos)
{
    struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);

    if (inode->i_ino != MSDOS_ROOT_INO) {
        struct hlist_head *head =   sbi->inode_hashtable
                      + fat_hash(i_pos);

        spin_lock(&sbi->inode_hash_lock);
        MSDOS_I(inode)->i_pos = i_pos;
        hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head); //增加节点
        spin_unlock(&sbi->inode_hash_lock);
    }

    /* If NFS support is enabled, cache the mapping of start cluster
     * to directory inode. This is used during reconnection of
     * dentries to the filesystem root.
     */
    if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
        struct hlist_head *d_head = sbi->dir_hashtable;
        d_head += fat_dir_hash(MSDOS_I(inode)->i_logstart);

        spin_lock(&sbi->dir_hash_lock);
        hlist_add_head(&MSDOS_I(inode)->i_dir_hash, d_head); //增加节点
        spin_unlock(&sbi->dir_hash_lock);
    }
}

3. 删除哈希表节点

void fat_detach(struct inode *inode)
{
    struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
    spin_lock(&sbi->inode_hash_lock);
    MSDOS_I(inode)->i_pos = 0;
    hlist_del_init(&MSDOS_I(inode)->i_fat_hash);    //删除节点
    spin_unlock(&sbi->inode_hash_lock);

    if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
        spin_lock(&sbi->dir_hash_lock);
        hlist_del_init(&MSDOS_I(inode)->i_dir_hash);    //删除节点
        spin_unlock(&sbi->dir_hash_lock);
    }
}

 

标签:分析,hash,struct,lock,hlist,sbi,inode,内核
From: https://www.cnblogs.com/shanyu20/p/18206345

相关文章

  • 4/7一文讲透网络传输流程 epoll内核模型 reactor用户空间处理模型
    epoll是内核如何将由层层协议栈去除tcp头,根据四元组查socket文件,将sk_buffer放到socket接受队列的 reactor  五种IO模型,三种线程处理模型     回溯算法之全排列 将所有需要用到的数组包括路径数组状态数组都初始化好然后都放进dfs参数里面 这......
  • 案例分析:通过两个学生项目的例子,推断出这些团队的血型
    案例分析:通过两个学生项目的例子,推断出这些团队的血型:1、STG游戏的跳票(为了完美,推迟了7天,但是7天之后也没有发布……)我怀着无比沉痛的心情宣布,我们的游戏因尚未达到预期的可玩性,为了不丢人现眼,延迟发布i天(i<=7)。我们在起初的计划中,以发布后一周的下载量作为项目衡量的标准。虽......
  • STRIDE模型应用于信息安全威胁分析学习
    STRIDE模型应用与信息安全威胁分析学习一、引言功能安全风险分析是对系统的系统性失效和随机性失效进行风险评估,对于网络安全风险,需要通过威胁分析识别系统的威胁场景,用于形成有对应威胁的控制措施和有效的分层防御,威胁分析是信息安全风险分析的重要组成部分。二、威胁分析的步......
  • 订单系统需求分析说明(抄)
    对外:官网、渠道、商城、商家后台中台:订单系统<-产品系统<-促销系统(管理优惠信息)服务:会员、仓储库存、支付、风控、消息多一个服务系统、订单系统就会多一个服务信息订单(创建、修改、支付、生产、确认、完成、取消、退货、退款)逻辑(状态规则、金额计算规则、......
  • 数据分析进阶
    numpynumpy提供了一种数组类型,高维数组,提供了数据分析的运算基础(业务表一般就是二维)importnumpyasnp导入numpy库,并查看numpy版本np._version_创建array数据类型一致的一个连续的内存空间,python的列表list不要求数据类型一致numpy的设计初衷是用于运算的,所以对数据类型进......
  • 《安富莱嵌入式周报》第337期:超高性能信号量测量,协议分析的开源工具且核心算法开源,工
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 视频版:https://www.bilibili.com/video/BV1PT421S7TR/目录1、一款超高性能信号量测量,协议分析的开源跨平台上位机工具ngscopeclient,核心算法全开源2、ST推出面向工业安全......
  • Linux实验(安装内核)
    Linux实验(安装内核)以下所有操作皆以机房电脑上的虚拟机为基础环境下载链接:Linux课程机房虚拟机#‍预备工作:打开虚拟机->设置->添加​,选择硬盘后点击下一步,全部都是默认选项​​新建磁盘后需要重启虚拟机,然后执行以下命令‍装载磁盘fdisk/dev/sdb更新分区par......
  • 进程通信--管道(存在于内核区)
    在Linux中,管道(pipe)是一种用于进程间通信(IPC)的机制,它允许数据在两个进程之间单向传输。管道有两种类型:匿名管道和命名管道(FIFO)。匿名管道匿名管道通常用于具有父子关系的进程之间的通信。它由pipe()系统调用创建。匿名管道只存在于创建它的进程及其子进程之间。匿名管道创建后,......
  • 全面了解网络性能监测与流量分析
    当前数字化时代,网络系统的复杂性与日俱增,网络性能监测和流量分析已成为网络管理的关键所在。本文将从多个角度为您剖析网络性能监测和流量分析的精髓,助您深入了解网络的运行脉搏。网络性能监测:把握关键指标网络性能监测涉及多个重要方面:带宽监控及时掌握网络带宽使用状况......
  • python实现客户价值分析
    本章使用的客户价值分析主要使用的是聚类分析方法,那么在对客户进行聚类前,首先使用RFM模型分析客户价值,下面进行RFM模型讲解:1.RFM模型RFM模型是衡量客户价值和潜在价值,它是衡量客户价值和潜在价值的主要工具手段。大部分人员都会接触到该模型,RFM模型是国际上最成熟、最为容易的......