Re: [TOMOYO 05/15](repost) Domain transition handler functions.

Tetsuo Handa
2007-10-03T11:25:08Z

Hello.

YOSHIFUJI Hideaki wrote:
> Introducing your own list is not good.
> Please use hlist or introduce new "slist".

James Morris wrote:
> You're introducing a custom API, which is open-coded repeatedly throughout
> your module.
>
> All linked lists (at least, new ones) must use the standard kernel list
> API.

It seems that standard kernel list API does not have singly-linked list manipulation.
I'm considering the following list manipulation API.

--- Start of code ---
#include <stdio.h>
#include <stdlib.h>

static inline void prefetch(const void *x) {;}
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );})

/*
* nphlist -- hlist with no pointer to previous
*/
struct nphlist_node {
struct nphlist_node *next;
};
struct nphlist_head {
struct nphlist_node *first;
};

#define NPHLIST_HEAD_INIT { .first = NULL }
#define NPHLIST_HEAD(name) struct nphlist_head name = NPHLIST_HEAD_INIT
#define INIT_NPHLIST_HEAD(ptr) ((ptr)->first = NULL)
#define INIT_NPHLIST_NODE(ptr) ((ptr)->next = NULL)

static inline void nphlist_add(struct nphlist_node *entry, struct nphlist_head *list) {
struct nphlist_node *ptr = list->first;
if (ptr) {
while (ptr->next)
ptr = ptr->next;
ptr->next = entry;
} else {
list->first = entry;
}
}

#define nphlist_entry(ptr, type, member) container_of(ptr,type,member)

/**
* nphlist_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop cursor.
* @pos: the &struct nph_list to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the nphlist_node within the struct.
*/
#define nphlist_for_each_entry(tpos, pos, head, member) \
for (pos = (head); \
pos && ({ prefetch(pos->next); 1;}) && \
({ tpos = nphlist_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)

struct something {
struct nphlist_node next;
int v;
};

static NPHLIST_HEAD(data);

int main(int argc, char *argv[]) {
struct something *ptr;
struct nphlist_node *p;
int i;
for (i = 0; i < 10; i++) {
printf("add %d\n", i);
ptr = malloc(sizeof(*ptr));
INIT_NPHLIST_NODE(&(ptr->next));
ptr->v = 10 + i;
nphlist_add(&(ptr->next), &data);
}
printf("dump\n");
nphlist_for_each_entry(ptr, p, data.first, next) {
printf("%d\n", ptr->v);
}
return 0;
}
--- End of code ---

Where should I put this API, in include/linux/list.h or security/tomoyo/include/tomoyo.h ?

If I should put in include/linux/list.h , what name would be appropriate?
May I name it "slist" instead of "nphlist" ?

Regards.