I did come across the linux kernel lists when I was looking up list implementations. I decided just to put it on the top of the struct to make it easier.
The advantage of the linux kernel list struct over mine, is you could have an object that can be put in multiple lists, because the listnode struct can be anywhere inside the larger struct. The disadvantage is you have to know what lists those are in advance:
typedef struct {
struct list_head multiples_of_5;
struct list_head multiples_of_7;
struct list_head perfect_numbers;
struct list_head prime_numbers;
unsigned int number;
} natural_numbers_t;
In cases where I may need objects that can exist in multiple lists, and I don't know what those lists are in advance, I'm always free to construct one of these:
typedef struct
{
zlistnode_t zlistnode;
natural_number_t* natnum;
} natural_number_node_t;

Find content
Not Telling