简体   繁体   中英

How to access containing structure from a member in C?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM