도와주세요!!
커널 코드 공부하다가 의문점이 있어 질문 올립니다.
아래 inet_init 함수에서
inet_register_protosw(q); 안에 list_for_each / list_entry 로 permanent protocol flag match 검사하는 루프가 있는데
list_head 타입을 list_head 타입으로 받아서 이를 container_of 로 inet_protosw 구조체를 얻어낸다는 것이 이해가 안됩니다.
다시 말하면,
inet_register_protosw 함수의 list_for_each 매크로를 보면
list_head 타입인 &inetsw[p->type] 을 list_head 타입의 lh 변수로 받아서 이를 가지고 list_entry(container_of 매크로)로
inet_protosw 구조체를 받는 것으로 나오는데 이를 위해서는 inetsw 변수(list_head type) 가 사전에 특정 inet_protosw 구조체의
list 멤버와 연결되어 있어야 하는 게 아닌가 생각됩니다. 하지만 inet_init 함수 안의 전단 코드들을 보면 init_list_head 만 있을 뿐
inetsw 변수가 inet_protosw 구조체와 연결되는 부분이 안 보입니다.
아직 list_for_each 문에 대한 이해가 부족해서 그런건지... 고수 여러분의 많은 도움 부탁드립니다.
=============================================================================================================
< inet_init 함수 >
static int __init inet_init(void)
{
...
...
for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)
INIT_LIST_HEAD(r); // make inet_protosw doubly linked list type (not yet list created)
for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
inet_register_protosw(q);
...
...
}
===========================================================================================================
< inet_init 함수 안의 inet_register_protosw 함수 >
void inet_register_protosw(struct inet_protosw *p)
{
struct list_head *lh;
struct inet_protosw *answer;
int protocol = p->protocol;
struct list_head *last_perm;
spin_lock_bh(&inetsw_lock);
if (p->type >= SOCK_MAX)
goto out_illegal;
/* If we are trying to override a permanent protocol, bail. */
answer = NULL;
last_perm = &inetsw[p->type];
list_for_each(lh, &inetsw[p->type]) {
answer = list_entry(lh, struct inet_protosw, list);
/* Check only the non-wild match. */
if (INET_PROTOSW_PERMANENT & answer->flags) {
if (protocol == answer->protocol)
break;
last_perm = lh;
}
answer = NULL;
}