void *flex_array_get_base(struct flex_array *fa, unsigned int element_nr) { int part_nr = 0; struct flex_array_part *part; if (!elements_fit_in_base(fa)) return NULL; part = (struct flex_array_part *)&fa->parts[0]; return &part->elements[index_inside_part(fa, element_nr, part_nr)]; }
/** * flex_array_get - pull data back out of the array * @fa: the flex array from which to extract data * @element_nr: index of the element to fetch from the array * * Returns a pointer to the data at index @element_nr. Note * that this is a copy of the data that was passed in. If you * are using this to store pointers, you'll get back &ptr. You * may instead wish to use the flex_array_get_ptr helper. * * Locking must be provided by the caller. */ void *flex_array_get(struct flex_array *fa, unsigned int element_nr) { int part_nr = fa_element_to_part_nr(fa, element_nr); struct flex_array_part *part; if (element_nr >= fa->total_nr_elements) return NULL; if (elements_fit_in_base(fa)) part = (struct flex_array_part *)&fa->parts[0]; else { part = fa->parts[part_nr]; if (!part) return NULL; } return &part->elements[index_inside_part(fa, element_nr)]; }
/** * flex_array_clear - clear element in array at @element_nr * @fa: the flex array of the element. * @element_nr: index of the position to clear. * * Locking must be provided by the caller. */ int flex_array_clear(struct flex_array *fa, unsigned int element_nr) { int part_nr = fa_element_to_part_nr(fa, element_nr); struct flex_array_part *part; void *dst; if (element_nr >= fa->total_nr_elements) return -ENOSPC; if (elements_fit_in_base(fa)) part = (struct flex_array_part *)&fa->parts[0]; else { part = fa->parts[part_nr]; if (!part) return -EINVAL; } dst = &part->elements[index_inside_part(fa, element_nr)]; memset(dst, FLEX_ARRAY_FREE, fa->element_size); return 0; }
/** * flex_array_put - copy data into the array at @element_nr * @fa: the flex array to copy data into * @element_nr: index of the position in which to insert * the new element. * @src: address of data to copy into the array * @flags: page allocation flags to use for array expansion * * * Note that this *copies* the contents of @src into * the array. If you are trying to store an array of * pointers, make sure to pass in &ptr instead of ptr. * You may instead wish to use the flex_array_put_ptr() * helper function. * * Locking must be provided by the caller. */ int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, gfp_t flags) { int part_nr = fa_element_to_part_nr(fa, element_nr); struct flex_array_part *part; void *dst; if (element_nr >= fa->total_nr_elements) return -ENOSPC; if (elements_fit_in_base(fa)) part = (struct flex_array_part *)&fa->parts[0]; else { part = __fa_get_part(fa, part_nr, flags); if (!part) return -ENOMEM; } dst = &part->elements[index_inside_part(fa, element_nr)]; memcpy(dst, src, fa->element_size); return 0; }
inline void* flex_array_get_from_part(struct flex_array_part* part, int part_nr, struct flex_array* fa, unsigned int element_nr) { return &part->elements[index_inside_part(fa, element_nr, part_nr)]; }