at v2.6.36-rc1 2.4 kB view raw
1#ifndef _FLEX_ARRAY_H 2#define _FLEX_ARRAY_H 3 4#include <linux/types.h> 5#include <asm/page.h> 6 7#define FLEX_ARRAY_PART_SIZE PAGE_SIZE 8#define FLEX_ARRAY_BASE_SIZE PAGE_SIZE 9 10struct flex_array_part; 11 12/* 13 * This is meant to replace cases where an array-like 14 * structure has gotten too big to fit into kmalloc() 15 * and the developer is getting tempted to use 16 * vmalloc(). 17 */ 18 19struct flex_array { 20 union { 21 struct { 22 int element_size; 23 int total_nr_elements; 24 struct flex_array_part *parts[]; 25 }; 26 /* 27 * This little trick makes sure that 28 * sizeof(flex_array) == PAGE_SIZE 29 */ 30 char padding[FLEX_ARRAY_BASE_SIZE]; 31 }; 32}; 33 34/* Number of bytes left in base struct flex_array, excluding metadata */ 35#define FLEX_ARRAY_BASE_BYTES_LEFT \ 36 (FLEX_ARRAY_BASE_SIZE - offsetof(struct flex_array, parts)) 37 38/* Number of pointers in base to struct flex_array_part pages */ 39#define FLEX_ARRAY_NR_BASE_PTRS \ 40 (FLEX_ARRAY_BASE_BYTES_LEFT / sizeof(struct flex_array_part *)) 41 42/* Number of elements of size that fit in struct flex_array_part */ 43#define FLEX_ARRAY_ELEMENTS_PER_PART(size) \ 44 (FLEX_ARRAY_PART_SIZE / size) 45 46/* 47 * Defines a statically allocated flex array and ensures its parameters are 48 * valid. 49 */ 50#define DEFINE_FLEX_ARRAY(__arrayname, __element_size, __total) \ 51 struct flex_array __arrayname = { { { \ 52 .element_size = (__element_size), \ 53 .total_nr_elements = (__total), \ 54 } } }; \ 55 static inline void __arrayname##_invalid_parameter(void) \ 56 { \ 57 BUILD_BUG_ON((__total) > FLEX_ARRAY_NR_BASE_PTRS * \ 58 FLEX_ARRAY_ELEMENTS_PER_PART(__element_size)); \ 59 } 60 61struct flex_array *flex_array_alloc(int element_size, unsigned int total, 62 gfp_t flags); 63int flex_array_prealloc(struct flex_array *fa, unsigned int start, 64 unsigned int end, gfp_t flags); 65void flex_array_free(struct flex_array *fa); 66void flex_array_free_parts(struct flex_array *fa); 67int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, 68 gfp_t flags); 69int flex_array_clear(struct flex_array *fa, unsigned int element_nr); 70void *flex_array_get(struct flex_array *fa, unsigned int element_nr); 71int flex_array_shrink(struct flex_array *fa); 72 73#define flex_array_put_ptr(fa, nr, src, gfp) \ 74 flex_array_put(fa, nr, &(void *)(src), gfp) 75 76void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr); 77 78#endif /* _FLEX_ARRAY_H */