개요
container_of(입력 주소, 구조체 A, 해당 구조체 멤버) 어떤 구조체(A)의 멤버가 입력 주소일 경우 해당하는 구조체의 주소를 가져온다.
예를 들어서 linux/bpf/hashtab.c
static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
{
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
struct hlist_nulls_head *head;
struct htab_elem *l;
u32 hash, key_size;
에서 container_of의 구조를 분석해 보면,
map이란 struct bpf_map의 주소값이다. 근데 bpf_htab이란 구조체는 내부 인자중 하나로 struct bpf_map map을 가진다. 이 경우, 우리는 bpf_map의 주소값만을 알지만, bpf_map의 주소값의 bpf_htab의 상대적인 위치를 알기 때문에 결국 bpf_htab의 위치를 알 수 있다.
container_of는 다음과 같은 구현을 가진다.
1 #define container_of(ptr, type, member) ({ \
2 const typeof( ((type *)0)->member ) *__mptr = (ptr);
3 (type *)( (char *)__mptr - offsetof(type,member) );})
이에 따라서 offsetof로 인해서 구조체 에서의 상대적인 위치를 가져오고 그 결과를 __mptr즉 ptr의 위치에서 빼면서 원하는 구조체의 위치를 가져오게 되는 것이다.