brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 681b350 Raw
141 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * VMware VMCI Driver4 *5 * Copyright (C) 2012 VMware, Inc. All rights reserved.6 */7 8#include <linux/slab.h>9#include "vmci_handle_array.h"10 11struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity)12{13	struct vmci_handle_arr *array;14 15	if (max_capacity == 0 || capacity > max_capacity)16		return NULL;17 18	if (capacity == 0)19		capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY,20			       max_capacity);21 22	array = kmalloc(struct_size(array, entries, capacity), GFP_ATOMIC);23	if (!array)24		return NULL;25 26	array->capacity = capacity;27	array->max_capacity = max_capacity;28	array->size = 0;29 30	return array;31}32 33void vmci_handle_arr_destroy(struct vmci_handle_arr *array)34{35	kfree(array);36}37 38int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,39				 struct vmci_handle handle)40{41	struct vmci_handle_arr *array = *array_ptr;42 43	if (unlikely(array->size >= array->capacity)) {44		/* reallocate. */45		struct vmci_handle_arr *new_array;46		u32 capacity_bump = min(array->max_capacity - array->capacity,47					array->capacity);48		size_t new_size = struct_size(array, entries,49					      size_add(array->capacity, capacity_bump));50 51		if (array->size >= array->max_capacity)52			return VMCI_ERROR_NO_MEM;53 54		new_array = krealloc(array, new_size, GFP_ATOMIC);55		if (!new_array)56			return VMCI_ERROR_NO_MEM;57 58		new_array->capacity += capacity_bump;59		*array_ptr = array = new_array;60	}61 62	array->entries[array->size] = handle;63	array->size++;64 65	return VMCI_SUCCESS;66}67 68/*69 * Handle that was removed, VMCI_INVALID_HANDLE if entry not found.70 */71struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array,72						struct vmci_handle entry_handle)73{74	struct vmci_handle handle = VMCI_INVALID_HANDLE;75	u32 i;76 77	for (i = 0; i < array->size; i++) {78		if (vmci_handle_is_equal(array->entries[i], entry_handle)) {79			handle = array->entries[i];80			array->size--;81			array->entries[i] = array->entries[array->size];82			array->entries[array->size] = VMCI_INVALID_HANDLE;83			break;84		}85	}86 87	return handle;88}89 90/*91 * Handle that was removed, VMCI_INVALID_HANDLE if array was empty.92 */93struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array)94{95	struct vmci_handle handle = VMCI_INVALID_HANDLE;96 97	if (array->size) {98		array->size--;99		handle = array->entries[array->size];100		array->entries[array->size] = VMCI_INVALID_HANDLE;101	}102 103	return handle;104}105 106/*107 * Handle at given index, VMCI_INVALID_HANDLE if invalid index.108 */109struct vmci_handle110vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index)111{112	if (unlikely(index >= array->size))113		return VMCI_INVALID_HANDLE;114 115	return array->entries[index];116}117 118bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array,119			       struct vmci_handle entry_handle)120{121	u32 i;122 123	for (i = 0; i < array->size; i++)124		if (vmci_handle_is_equal(array->entries[i], entry_handle))125			return true;126 127	return false;128}129 130/*131 * NULL if the array is empty. Otherwise, a pointer to the array132 * of VMCI handles in the handle array.133 */134struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array)135{136	if (array->size)137		return array->entries;138 139	return NULL;140}141