I'm working with a few kernel modules (4.19.97) and I allocate struct my_sock
like the following.
struct my_target {
union thingA { ... } a;
struct thingB *b;
};
struct my_sock {
struct sock sk;
// ...
struct my_target target;
};
struct my_sock *my_s;
my_s = my_sock_alloc();
// ...
my_s->sk.sk_prot->init(sk);
The above ends up calling this callback.
static int my_init(struct sock *sk)
{
// I do the following because I cannot pass in the allocated
// `struct my_sock` into this function.
struct my_sock *ms = my_sk(sk);
// I want to access my_s->my_target or any field within
// `struct my_target` here, but at this point, `ms` is
// pointing to the the first member of `struct my_sock`, and
// not the originally allocated `my_s`.
ms->target.a;
}
static inline struct my_sock* my_sk(const struct sock *s)
{
return container_of(s, struct my_sock, sk);
}
// Here's how my_s gets allocated. Note that this is not the same
// structure as the first member of `struct my_sock`.
struct my_sock* my_sock_alloc(void)
{
struct my_sock *sk = NULL;
sk = kmem_cache_zalloc(my_sk_cachep, GFP_KERNEL);
if (!sk)
return NULL;
return sk;
}
And here's the problem. The kernel has the code for container_of
within include/linux/kernel.h
which casts a member of a structure out to the containing structure
, per the commentary.
When I use my_sk(sk)
, I get the pointer address of the first member of the containing struct. The problem is that this is a different address than my_s
which I allocated in the very first line and I need the pointer to my_s
in order to access the target
member.
Thoughts as to how I might access my_s->target
within the call my_init()
(and not make things global)?
since sk
is the very first field in struct my_sock
, you can just cast the pointer and things should work:
struct my_sock *ms = (struct my_sock *)sk;
the extra work done in container_of is only needed when the "base" struct is not the first field.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.