Linux内核Hash Table结构
近期在学习linux内核netfilter框架中有关conntrack和分片重组相关的代码过程中,顺便学习到了内核中hash表的结构。在此记录一下。
内核中hash表的定义:
struct hlist_head{
struct hlist_node *first;
}
struct hlist_node {
struct hlist_node *next,**pprev;
}
- hlist_head表示哈希表的头结点。哈希表中每一个entry(list_entry)所对应的都是一个链表(hlist).hlist_head结构体只有一个域,即first。First指针指向该hlist链表的第一个结点。
- hlist_node结构体有两个域,next和pprev。
(1)next指向下个hlist_node结点,倘若该结点是链表的最后一个节点,next则指向NULL
(2)pprev是一个二级指针,它指向前一个节点的next指针。
更详细的内核Hash Table相关的
注意:hlist_node hash表节点的结构体中只有其他节点的指针信息,即只有表本身所需的结构,没有额外空间存储Value信息。那么使用hash记录信息是,信息存储到哪了呢?或者说找到了hash节点,又怎么能找到相关联的信息呢?
内核提供了container_of宏来解决上面提出的疑问。具体实现是:hash节点(hlist_node)可作为另一结构体A的成员,A中的其他成员用于存储必要的信息。通过Hash表查询到hlist_node的地址后,container_of宏可以通过hlist_node的地址得到其父结构体A的地址。
container_of宏
container_of宏定义:
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
void *__mptr = (void *)(ptr); \
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
!__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
((type *)(__mptr - offsetof(type, member))); })
未完待续。。。