This huge patch revamps almost everything under dat, and merges the three layers of external API, dynamic registry and dictinary into a single one, greatly streamlining all of the code.
Note that I don't have any RDMA hardware to actually takes this, so it probably needs some testing first. Signed-off-by: Christoph Hellwig <[EMAIL PROTECTED]> Index: linux-kernel/dat/dr.c =================================================================== --- linux-kernel/dat/dr.c (revision 2647) +++ linux-kernel/dat/dr.c (working copy) @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - */ - -/* - * Dynamic Registry (DR) functions and data structures - * - * $Id$ - */ - -#include "core.h" -#include "dictionary.h" -#include "dr.h" - -struct dat_dr_entry { - int ref_count; - struct dat_provider_info info; - DAT_IA_OPEN_FUNC ia_open_func; -}; - -static spinlock_t g_dr_lock = SPIN_LOCK_UNLOCKED; -static struct dat_dictionary g_dr_dictionary = - DAT_DICTIONARY_INIT(g_dr_dictionary); - -void dat_dr_fini(void) -{ - dat_dictionary_destroy(&g_dr_dictionary); -} - -u32 dat_dr_insert(const struct dat_provider_info *info, - const DAT_IA_OPEN_FUNC ia_open_func) -{ - struct dat_dr_entry *data; - struct dat_dictionary_entry *dict_entry; - unsigned long flags; - u32 status; - - data = kmalloc(sizeof *data, GFP_ATOMIC); - if (!data) { - status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, - DAT_RESOURCE_MEMORY); - goto bail; - } - - data->ref_count = 0; - data->info = *info; - data->ia_open_func = ia_open_func; - - dict_entry = NULL; - status = dat_dictionary_entry_create(&dict_entry); - if (DAT_SUCCESS != status) - goto bail; - - spin_lock_irqsave(&g_dr_lock, flags); - - status = dat_dictionary_insert(&g_dr_dictionary, info, dict_entry, - data); - - spin_unlock_irqrestore(&g_dr_lock, flags); - -bail: - if (DAT_SUCCESS != status) { - if (NULL != data) - kfree(data); - - if (NULL != dict_entry) - dat_dictionary_entry_destroy(dict_entry); - } - - return status; -} - -u32 dat_dr_remove(const struct dat_provider_info *info) -{ - struct dat_dr_entry *data; - struct dat_dictionary_entry *dict_entry; - unsigned long flags; - u32 status; - - dict_entry = NULL; - spin_lock_irqsave(&g_dr_lock, flags); - - status = dat_dictionary_search(&g_dr_dictionary, info, (void **) &data); - - if (DAT_SUCCESS != status) - goto bail; /* return status from dat_dictionary_search() */ - - if (0 != data->ref_count) { - status = DAT_ERROR(DAT_PROVIDER_IN_USE, 0); - goto bail; - } - - status = dat_dictionary_remove(&g_dr_dictionary, info, &dict_entry, - (void **) &data); - if (DAT_SUCCESS != status) - goto bail; /* return status from dat_dictionary_remove() */ - - kfree(data); - -bail: - spin_unlock_irqrestore(&g_dr_lock, flags); - - if (NULL != dict_entry) - dat_dictionary_entry_destroy(dict_entry); - - return status; -} - -u32 dat_dr_provider_open(const struct dat_provider_info *info, - DAT_IA_OPEN_FUNC *p_ia_open_func) -{ - struct dat_dr_entry *data; - unsigned long flags; - u32 status; - - spin_lock_irqsave(&g_dr_lock, flags); - - status = dat_dictionary_search(&g_dr_dictionary, info, (void **) &data); - - spin_unlock_irqrestore(&g_dr_lock, flags); - - if (DAT_SUCCESS == status) { - data->ref_count++; - *p_ia_open_func = data->ia_open_func; - } - - return status; -} - -u32 dat_dr_provider_close(const struct dat_provider_info *info) -{ - struct dat_dr_entry *data; - unsigned long flags; - u32 status; - - spin_lock_irqsave(&g_dr_lock, flags); - - status = dat_dictionary_search(&g_dr_dictionary, info, (void **) &data); - - spin_unlock_irqrestore(&g_dr_lock, flags); - - if (DAT_SUCCESS == status) - data->ref_count--; - - return status; -} - -u32 dat_dr_size(int *size) -{ - return dat_dictionary_size(&g_dr_dictionary, size); -} - -u32 dat_dr_list(int max_to_return, int *entries_returned, - struct dat_provider_info *(dat_provider_list[])) -{ - struct dat_dr_entry **array = NULL; - int i, array_size; - unsigned long flags; - u32 status = DAT_SUCCESS; - - /* - * The dictionary size may increase between the call to - * dat_dictionary_size() and dat_dictionary_enumerate(). - * Therefore we loop until a successful enumeration is made. - */ - *entries_returned = 0; - for (;;) { - status = dat_dictionary_size(&g_dr_dictionary, &array_size); - if (DAT_SUCCESS != status) - goto bail; - - if (0 == array_size) { - status = DAT_SUCCESS; - goto bail; - } - - array = kmalloc(array_size * sizeof *array, GFP_ATOMIC); - if (!array) { - status = - DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, - DAT_RESOURCE_MEMORY); - goto bail; - } - - spin_lock_irqsave(&g_dr_lock, flags); - - status = dat_dictionary_enumerate(&g_dr_dictionary, - (void **) array, array_size); - - spin_unlock_irqrestore(&g_dr_lock, flags); - - if (DAT_SUCCESS == status) - break; - else { - kfree(array); - array = NULL; - continue; - } - } - - for (i = 0; (i < max_to_return) && (i < array_size); i++) { - if (NULL == dat_provider_list[i]) { - status = - DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3); - goto bail; - } - - *dat_provider_list[i] = array[i]->info; - } - - *entries_returned = i; - -bail: - if (NULL != array) - kfree(array); - - return status; -} Index: linux-kernel/dat/dictionary.c =================================================================== --- linux-kernel/dat/dictionary.c (revision 2647) +++ linux-kernel/dat/dictionary.c (working copy) @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - */ - -/* - * A dictionary data structure implemented with a linked list - * - * $Id$ - */ - -#include "dictionary.h" - -static u32 dat_dictionary_key_dup(const struct dat_provider_info *old_key, - struct dat_provider_info *new_key); - -static boolean_t dat_dictionary_key_is_equal(const struct dat_provider_info *a, - const struct dat_provider_info *b); - -void dat_dictionary_destroy(struct dat_dictionary *dictionary) -{ - struct list_head *cur_list, *next_list; - struct dat_dictionary_entry *cur_entry; - - BUG_ON(NULL == dictionary); - - list_for_each_safe(cur_list, next_list, &dictionary->list) { - cur_entry = list_entry(cur_list, struct dat_dictionary_entry, - list); - list_del(&cur_entry->list); - kfree(cur_entry); - } -} - -u32 dat_dictionary_size(const struct dat_dictionary *dictionary, int *size) -{ - BUG_ON(NULL == dictionary); - BUG_ON(NULL == size); - - *size = dictionary->size; - - return DAT_SUCCESS; -} - -u32 dat_dictionary_entry_create(struct dat_dictionary_entry **p_entry) -{ - struct dat_dictionary_entry *entry; - u32 status = DAT_SUCCESS; - - BUG_ON(NULL == p_entry); - - entry = kmalloc(sizeof *entry, GFP_ATOMIC); - if (!entry) { - status = - DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); - goto bail; - } - - *p_entry = entry; - -bail: - return status; -} - -void dat_dictionary_entry_destroy(const struct dat_dictionary_entry *entry) -{ - kfree(entry); -} - -u32 dat_dictionary_insert(struct dat_dictionary *dictionary, - const struct dat_provider_info *key, - struct dat_dictionary_entry *entry, void *data) -{ - u32 status; - - BUG_ON(NULL == dictionary); - BUG_ON(NULL == entry); - - if (DAT_SUCCESS == dat_dictionary_search(dictionary, key, NULL)) { - status = DAT_ERROR(DAT_PROVIDER_ALREADY_REGISTERED, 0); - goto bail; - } - - status = dat_dictionary_key_dup(key, &entry->key); - if (DAT_SUCCESS != status) - goto bail; - - entry->data = data; - - /* insert node at end of list to preserve registration order */ - list_add_tail(&entry->list, &dictionary->list); - - dictionary->size++; - -bail: - return status; -} - -u32 dat_dictionary_search(struct dat_dictionary *dictionary, - const struct dat_provider_info *key, void **p_data) -{ - struct dat_dictionary_entry *cur_entry; - u32 status; - - BUG_ON(NULL == dictionary); - BUG_ON(NULL == key); - - status = DAT_ERROR(DAT_PROVIDER_NOT_FOUND, DAT_NAME_NOT_REGISTERED); - - list_for_each_entry(cur_entry, &dictionary->list, list) { - if (TRUE == dat_dictionary_key_is_equal(&cur_entry->key, key)) { - if (NULL != p_data) - *p_data = cur_entry->data; - - status = DAT_SUCCESS; - goto bail; - } - } - -bail: - return status; -} - -u32 dat_dictionary_enumerate(struct dat_dictionary *dictionary, void *array[], - int array_size) -{ - struct dat_dictionary_entry *cur_entry; - int i; - u32 status; - - BUG_ON(NULL == dictionary); - BUG_ON(NULL == array); - - status = DAT_SUCCESS; - - if (array_size < dictionary->size) { - status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0); - goto bail; - } - - i = 0; - list_for_each_entry(cur_entry, &dictionary->list, list) - array[i++] = cur_entry->data; - -bail: - return status; -} - -u32 dat_dictionary_remove(struct dat_dictionary *dictionary, - const struct dat_provider_info *key, - struct dat_dictionary_entry **p_entry, void **p_data) -{ - struct list_head *cur_list, *next_list; - struct dat_dictionary_entry *cur_entry; - u32 status; - - BUG_ON(NULL == dictionary); - BUG_ON(NULL == key); - BUG_ON(NULL == p_entry); - - status = DAT_ERROR(DAT_PROVIDER_NOT_FOUND, DAT_NAME_NOT_REGISTERED); - - list_for_each_safe(cur_list, next_list, &dictionary->list) { - cur_entry = list_entry(cur_list, struct dat_dictionary_entry, - list); - if (TRUE == dat_dictionary_key_is_equal(&cur_entry->key, key)) { - if (NULL != p_data) - *p_data = cur_entry->data; - - list_del(&cur_entry->list); - - *p_entry = cur_entry; - - dictionary->size--; - - status = DAT_SUCCESS; - goto bail; - } - } - -bail: - return status; -} - -static u32 dat_dictionary_key_dup(const struct dat_provider_info *old_key, - struct dat_provider_info *new_key) -{ - BUG_ON(NULL == old_key); - BUG_ON(NULL == new_key); - - strncpy(new_key->ia_name, old_key->ia_name, DAT_NAME_MAX_LENGTH); - return DAT_SUCCESS; -} - -static boolean_t dat_dictionary_key_is_equal(const struct dat_provider_info *a, - const struct dat_provider_info *b) -{ - BUG_ON(NULL == a); - BUG_ON(NULL == b); - - if ((strlen(a->ia_name) == strlen(b->ia_name)) && - (!strncmp(a->ia_name, b->ia_name, strlen(a->ia_name)))) - return TRUE; - else - return FALSE; -} Index: linux-kernel/dat/core.c =================================================================== --- linux-kernel/dat/core.c (revision 2647) +++ linux-kernel/dat/core.c (working copy) @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - */ - -/* - * Core DAT registry functions and data structures - * - * $Id$ - */ - -#include "core.h" -#include "dr.h" - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("Direct Access Transport (DAT) API"); -MODULE_AUTHOR("James Lentini"); - -static DAT_DBG_MASK g_dbg_mask = DAT_DBG_TYPE_ERROR; -module_param_named(dbg_mask, g_dbg_mask, int, 0644); -MODULE_PARM_DESC(dbg_mask, "Bitmask to enable debug message types."); - -void dat_dbg_print(DAT_DBG_TYPE type, const char *fmt, ...) -{ - static char buf[1024]; - - if (type & g_dbg_mask) { - va_list args; - - va_start(args, fmt); - vsnprintf(buf, sizeof buf, fmt, args); - printk(KERN_ALERT "DAT: %s", buf); - va_end(args); - } -} - -static int __init dat_init(void) -{ - dat_dbg_print(DAT_DBG_TYPE_GENERIC, "registry started\n"); - return 0; -} - -module_init(dat_init); - -static void __exit dat_fini(void) -{ - dat_dr_fini(); - - dat_dbg_print(DAT_DBG_TYPE_GENERIC, "registry stopped\n"); -} - -module_exit(dat_fini); Index: linux-kernel/dat/api.c =================================================================== --- linux-kernel/dat/api.c (revision 2647) +++ linux-kernel/dat/api.c (working copy) @@ -26,15 +26,53 @@ * and/or other materials provided with the distribution. */ -/* - * DAT functions for consumers - * - * $Id: consumer.c 2251 2005-05-04 05:57:41Z jlentini $ - */ +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/spinlock.h> -#include "core.h" -#include "dr.h" +#include <dat.h> + +enum dat_dbg_type { + DAT_DBG_TYPE_ERROR = (1 << 0), + DAT_DBG_TYPE_GENERIC = (1 << 1), + DAT_DBG_TYPE_DR = (1 << 2), + DAT_DBG_TYPE_PROVIDER_API = (1 << 3), + DAT_DBG_TYPE_CONSUMER_API = (1 << 4), + DAT_DBG_TYPE_ALL = 0x1f +}; + +static int dat_dbg_mask = DAT_DBG_TYPE_ERROR; +module_param_named(dbg_mask, dat_dbg_mask, int, 0644); +MODULE_PARM_DESC(dbg_mask, "Bitmask to enable debug message types."); + +struct dat_dictionary_entry { + struct list_head list; + struct dat_provider_info info; + DAT_IA_OPEN_FUNC ia_open_func; + int ref_count; +}; + +static LIST_HEAD(dat_provider_list); +static int dat_provider_list_size; +static DEFINE_SPINLOCK(dat_provider_list_lock); + +static void dat_dbg_print(enum dat_dbg_type type, const char *fmt, ...) +{ + static char buf[1024]; + + if (type & dat_dbg_mask) { + va_list args; + + va_start(args, fmt); + vsnprintf(buf, sizeof buf, fmt, args); + printk(KERN_ALERT "DAT: %s", buf); + va_end(args); + } +} + static u32 dat_strerror_major(u32 value, const char **message) { switch (DAT_GET_TYPE(value)) { @@ -350,21 +388,39 @@ } } +static boolean_t dat_dictionary_key_is_equal(const struct dat_provider_info *a, + const struct dat_provider_info *b) +{ + if (strlen(a->ia_name) == strlen(b->ia_name) && + !strncmp(a->ia_name, b->ia_name, strlen(a->ia_name))) + return 1; + return 0; +} + +static struct dat_dictionary_entry *dat_dictionary_search( + struct list_head *list, const struct dat_provider_info *key) +{ + struct dat_dictionary_entry *entry; + + list_for_each_entry(entry, list, list) + if (dat_dictionary_key_is_equal(&entry->info, key)) + return entry; + + return NULL; +} + u32 dat_ia_open(const char *name, int async_event_qlen, struct dat_evd **async_event_handle, struct dat_ia **ia) { - DAT_IA_OPEN_FUNC ia_open_func; struct dat_provider_info info; - u32 status; + struct dat_dictionary_entry *data; + unsigned long flags; size_t len; dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, "%s(name:%s, async_qlen:%i, ver:%x.%x, thrd_safe:%x)\n", __func__, name, async_event_qlen); - if (DAT_IS_BAD_POINTER(name)) - return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); - len = strlen(name); if (DAT_NAME_MAX_LENGTH < len) @@ -373,62 +429,67 @@ strncpy(info.ia_name, name, len); info.ia_name[len] = '\0'; - status = dat_dr_provider_open(&info, &ia_open_func); - if (status != DAT_SUCCESS) { + spin_lock_irqsave(&dat_provider_list_lock, flags); + data = dat_dictionary_search(&dat_provider_list, &info); + spin_unlock_irqrestore(&dat_provider_list_lock, flags); + + if (!data) { dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, "%s: IA [%s] not found in dynamic registry\n", __func__, name); - return status; + return DAT_ERROR(DAT_PROVIDER_NOT_FOUND, + DAT_NAME_NOT_REGISTERED); } - return ia_open_func(name, async_event_qlen, async_event_handle, ia); + data->ref_count++; + return data->ia_open_func(name, async_event_qlen, async_event_handle, + ia); } - EXPORT_SYMBOL(dat_ia_open); -u32 dat_ia_close(struct dat_ia *ia, enum dat_close_flags flags) +u32 dat_ia_close(struct dat_ia *ia, enum dat_close_flags close_flags) { struct dat_provider *provider; - struct dat_provider_attr provider_attr; - u32 status; + struct dat_provider_info info; + u32 status = DAT_SUCCESS; const char *ia_name; + struct dat_dictionary_entry *data; + unsigned long flags; + size_t len; dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, - "%s(ia:%x, flags:%x)\n", __func__, ia, flags); + "%s(ia:%x, flags:%x)\n", __func__, ia, close_flags); provider = ia->common.provider; ia_name = provider->device_name; - if (DAT_SUCCESS != (status = dat_ia_query(ia, NULL, NULL, - &provider_attr))) + status = provider->ia_close_func(ia, close_flags); + if (status != DAT_SUCCESS) { dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, - "dat_ia_query for IA %s failed\n", ia_name); - else if (DAT_SUCCESS != (status = provider->ia_close_func(ia, flags))) - dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, "close function for IA %s failed\n", ia_name); - else { - struct dat_provider_info info; - size_t len; + return status; + } - len = strlen(ia_name); + len = strlen(ia_name); - BUG_ON(DAT_NAME_MAX_LENGTH < len); + BUG_ON(DAT_NAME_MAX_LENGTH < len); - strncpy(info.ia_name, ia_name, len); - info.ia_name[len] = '\0'; + strncpy(info.ia_name, ia_name, len); + info.ia_name[len] = '\0'; - status = dat_dr_provider_close(&info); - if (DAT_SUCCESS != status) - dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, - "dynamic registry unable to close " - "provider for IA %s\n", - ia_name); + spin_lock_irqsave(&dat_provider_list_lock, flags); + data = dat_dictionary_search(&dat_provider_list, &info); + if (data) { + data->ref_count--; + } else { + status = DAT_ERROR(DAT_PROVIDER_NOT_FOUND, + DAT_NAME_NOT_REGISTERED); } + spin_unlock_irqrestore(&dat_provider_list_lock, flags); return status; } - EXPORT_SYMBOL(dat_ia_close); u32 dat_strerror(u32 value, const char **major_message, @@ -454,69 +515,138 @@ return DAT_SUCCESS; } - EXPORT_SYMBOL(dat_strerror); u32 dat_registry_add_provider(const struct dat_provider *provider, - const struct dat_provider_info *provider_info) + const struct dat_provider_info *info) { - dat_dbg_print(DAT_DBG_TYPE_PROVIDER_API, - "%s(ia:%s, ver:%x.%x, thrd_safe:%x)\n", - __func__, provider_info->ia_name); + struct dat_dictionary_entry *entry; + unsigned long flags; + u32 status = DAT_SUCCESS; - if (DAT_IS_BAD_POINTER(provider)) - return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); + entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + if (!entry) { + status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, + DAT_RESOURCE_MEMORY); + goto out; + } - if (DAT_IS_BAD_POINTER(provider_info)) - return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2); + entry->ref_count = 0; + entry->info = *info; + entry->ia_open_func = provider->ia_open_func; - return dat_dr_insert(provider_info, provider->ia_open_func); + spin_lock_irqsave(&dat_provider_list_lock, flags); + if (dat_dictionary_search(&dat_provider_list, info)) { + status = DAT_ERROR(DAT_PROVIDER_ALREADY_REGISTERED, 0); + goto out_unlock; + } + + strncpy(entry->info.ia_name, info->ia_name, DAT_NAME_MAX_LENGTH); + + /* insert node at end of list to preserve registration order */ + list_add_tail(&entry->list, &dat_provider_list); + dat_provider_list_size++; + + out_unlock: + spin_unlock_irqrestore(&dat_provider_list_lock, flags); + out: + if (status != DAT_SUCCESS) + kfree(entry); + return status; } +EXPORT_SYMBOL(dat_registry_add_provider); -EXPORT_SYMBOL(dat_registry_remove_provider); - u32 dat_registry_remove_provider(const struct dat_provider *provider, - const struct dat_provider_info *provider_info) + const struct dat_provider_info *info) { - dat_dbg_print(DAT_DBG_TYPE_PROVIDER_API, "%s(ia:%s)\n", __func__, - provider_info->ia_name); + struct dat_dictionary_entry *cur, *next; + unsigned long flags; + u32 status = DAT_SUCCESS; - if (DAT_IS_BAD_POINTER(provider)) - return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); + spin_lock_irqsave(&dat_provider_list_lock, flags); + list_for_each_entry_safe(cur, next, &dat_provider_list, list) { + if (dat_dictionary_key_is_equal(&cur->info, info)) { + if (cur->ref_count) { + status = DAT_ERROR(DAT_PROVIDER_IN_USE, 0); + goto out; + } - return dat_dr_remove(provider_info); + list_del(&cur->list); + dat_provider_list_size--; + + kfree(cur); + goto out; + } + } + + status = DAT_ERROR(DAT_PROVIDER_NOT_FOUND, DAT_NAME_NOT_REGISTERED); + out: + spin_unlock_irqrestore(&dat_provider_list_lock, flags); + return status; } +EXPORT_SYMBOL(dat_registry_remove_provider); -EXPORT_SYMBOL(dat_registry_add_provider); - u32 dat_registry_list_providers(int max_to_return, int *entries_returned, - struct dat_provider_info *(dat_provider_list[])) + struct dat_provider_info *provider_list[]) { + struct dat_dictionary_entry *cur; + unsigned long flags; + int i = 0; u32 status = DAT_SUCCESS; - dat_dbg_print(DAT_DBG_TYPE_CONSUMER_API, - "%s(max_to_return:%i, entries_rtrn:%p, prvdr_list:%p)\n", - __func__, max_to_return, entries_returned, - dat_provider_list); - - if ((DAT_IS_BAD_POINTER(entries_returned))) - return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2); - - if (0 != max_to_return && (DAT_IS_BAD_POINTER(dat_provider_list))) - return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3); - - if (0 == max_to_return) { + if (!max_to_return) { /* the user is allowed to call with max_to_return set to zero. * in which case we simply return (in *entries_returned) the * number of providers currently installed. We must also * (per spec) return an error */ - (void)dat_dr_size(entries_returned); + *entries_returned = dat_provider_list_size; return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); - } else - status = dat_dr_list(max_to_return, entries_returned, - dat_provider_list); + } + + *entries_returned = 0; + + spin_lock_irqsave(&dat_provider_list_lock, flags); + if (!dat_provider_list_size) + goto out_unlock; + + list_for_each_entry(cur, &dat_provider_list, list) { + if (i >= max_to_return) + break; + if (!provider_list[i]) { + status = + DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3); + goto out_unlock; + } + provider_list[i++] = &cur->info; + } + *entries_returned = i; + + out_unlock: + spin_unlock_irqrestore(&dat_provider_list_lock, flags); return status; } +EXPORT_SYMBOL(dat_registry_list_providers); -EXPORT_SYMBOL(dat_registry_list_providers); +static int __init dat_init(void) +{ + dat_dbg_print(DAT_DBG_TYPE_GENERIC, "registry started\n"); + return 0; +} + +static void __exit dat_fini(void) +{ + struct dat_dictionary_entry *cur, *next; + + list_for_each_entry_safe(cur, next, &dat_provider_list, list) { + list_del(&cur->list); + kfree(cur); + } +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Direct Access Transport (DAT) API"); +MODULE_AUTHOR("James Lentini"); + +module_init(dat_init); +module_exit(dat_fini); Index: linux-kernel/dat/dictionary.h =================================================================== --- linux-kernel/dat/dictionary.h (revision 2647) +++ linux-kernel/dat/dictionary.h (working copy) @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - */ - -/* - * dictionary data structure - * - * $Id$ - */ - -#ifndef DICTIONARY_H -#define DICTIONARY_H - -#include "core.h" - -/********************************************************************* - * * - * Structures * - * * - *********************************************************************/ - -struct dat_dictionary_entry { - struct list_head list; - struct dat_provider_info key; - void *data; -}; - -struct dat_dictionary { - struct list_head list; - int size; -}; - -/********************************************************************* - * * - * Macros * - * * - *********************************************************************/ - -#define DAT_DICTIONARY_INIT(name) { LIST_HEAD_INIT((name).list), 0 } - -/********************************************************************* - * * - * Function Prototypes * - * * - *********************************************************************/ - -extern void dat_dictionary_destroy(struct dat_dictionary *dictionary); - -extern u32 dat_dictionary_size(const struct dat_dictionary *dictionary, - int *size); - -extern u32 dat_dictionary_entry_create(struct dat_dictionary_entry **p_entry); - -extern void dat_dictionary_entry_destroy( - const struct dat_dictionary_entry *entry); - -extern u32 dat_dictionary_insert(struct dat_dictionary *dictionary, - const struct dat_provider_info *key, - struct dat_dictionary_entry *entry, - void *data); - -extern u32 dat_dictionary_search(struct dat_dictionary *dictionary, - const struct dat_provider_info *key, - void **p_data); - -extern u32 dat_dictionary_enumerate(struct dat_dictionary *dictionary, - void *array[], const int array_size); - -extern u32 dat_dictionary_remove(struct dat_dictionary *dictionary, - const struct dat_provider_info *key, - struct dat_dictionary_entry **p_entry, - void **p_data); - -#endif /* DICTIONARY_H */ Index: linux-kernel/dat/dr.h =================================================================== --- linux-kernel/dat/dr.h (revision 2647) +++ linux-kernel/dat/dr.h (working copy) @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - */ - -/* - * Dynamic Registry (DR) functions and data stucture - * - * $Id$ - */ - -#ifndef DR_H -#define DR_H - -#include <dat.h> - -extern void dat_dr_fini(void); - -extern u32 dat_dr_insert(const struct dat_provider_info *info, - const DAT_IA_OPEN_FUNC ia_open_func); - -extern u32 dat_dr_remove(const struct dat_provider_info *info); - -extern u32 dat_dr_provider_open(const struct dat_provider_info *info, - DAT_IA_OPEN_FUNC *p_ia_open_func); - -extern u32 dat_dr_provider_close(const struct dat_provider_info *info); - -extern u32 dat_dr_size(int *size); - -extern u32 dat_dr_list(int max_to_return, int *entries_returned, - struct dat_provider_info *(dat_provider_list[])); - -#endif /* DR_H */ Index: linux-kernel/dat/Makefile =================================================================== --- linux-kernel/dat/Makefile (revision 2647) +++ linux-kernel/dat/Makefile (working copy) @@ -5,8 +5,4 @@ obj-$(CONFIG_DAT) += dat.o -dat-y := \ - api.o \ - core.o \ - dictionary.o \ - dr.o +dat-y += api.o Index: linux-kernel/dat/core.h =================================================================== --- linux-kernel/dat/core.h (revision 2647) +++ linux-kernel/dat/core.h (working copy) @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - */ - -/* - * core DAT registry functions and data structures - * - * $Id$ - */ - -#ifndef CORE_H -#define CORE_H - -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/spinlock.h> - -#include <dat.h> - -#define DAT_IS_BAD_POINTER(p) ( NULL == (p) ) - -typedef enum { - DAT_DBG_TYPE_ERROR = (1 << 0), - DAT_DBG_TYPE_GENERIC = (1 << 1), - DAT_DBG_TYPE_DR = (1 << 2), - DAT_DBG_TYPE_PROVIDER_API = (1 << 3), - DAT_DBG_TYPE_CONSUMER_API = (1 << 4), - DAT_DBG_TYPE_ALL = 0x1f -} DAT_DBG_TYPE; - -typedef int DAT_DBG_MASK; - -extern void dat_dbg_print(DAT_DBG_TYPE type, const char *fmt, ...); - -#endif /* CORE_H */ _______________________________________________ openib-general mailing list [email protected] http://openib.org/mailman/listinfo/openib-general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general
