c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * CDDL HEADER START
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The contents of this file are subject to the terms of the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Common Development and Distribution License (the "License").
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * You may not use this file except in compliance with the License.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * or http://www.opensolaris.org/os/licensing.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * See the License for the specific language governing permissions
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * and limitations under the License.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * When distributing Covered Code, include this CDDL HEADER in each
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * If applicable, add the following below this CDDL HEADER, with the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * fields enclosed by brackets "[]" replaced with your own identifying
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * information: Portions Copyright [yyyy] [name of copyright owner]
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * CDDL HEADER END
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * User Objects.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * User objects are used to manage and protect resources that
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * have been created for a user context. Each user object
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * maintains a reference count and a read/write mutex to
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * provide the appropriate access to the object depending
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * on the operation at hand.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * For example when initializing or creating a PD user object,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the active context would hold a write lock, but to simply
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * reference the PD object as in a CQ create operation, a
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * read lock is only required.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Each user object also maintains a "live" flag. If this flag
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * is not set, then lookups on this user object will fail
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * even if it still resides in the associated user object
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * management table. This specifically handles the case
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * where a get operation blocks and does not acquire the lock
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * until after the object has been destroyed (but not yet
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * released). Destroy operations set the "live" flag to 0
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * prior to dropping their write lock on the user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * This allows the reader to realize when it receives the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * lock that the object has been destroyed so it can then
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * release it's reference to the user object, and allow it to
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * be freed (the storage will not be freed until the last reference
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * is released).
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/debug.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/kmem.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/sunddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarextern char *sol_ofs_dbg_str;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ofs_uobj_t *ofs_uobj_find(sol_ofs_uobj_table_t *,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint_t, int);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_tbl_init
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_tbl - A pointer to the user object resource management table
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * to initialize.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Initializes the specified user object resource managment table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_tbl_init(sol_ofs_uobj_table_t *uo_tbl, size_t uobj_sz)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uo_tbl != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_init(&uo_tbl->uobj_tbl_lock, NULL, RW_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_used_blks = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_num_blks = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_cnt = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_sz = uobj_sz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_root = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_tbl_fini
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_tbl - A pointer to the user object resource management table
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * to be released.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Releases any resources held by the specified user object resource
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * managment table. The table is no longer valid upon return. NOTE:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the table should be empty when this routine is called, so this
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * really is more of just a sanity check.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_tbl_fini(sol_ofs_uobj_table_t *uo_tbl)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int i, j;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t size;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_blk_t *blk;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uo_tbl != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&uo_tbl->uobj_tbl_lock, RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uo_tbl->uobj_tbl_uo_cnt > 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ TBL FINI: object count not zero (cnt=%d)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_cnt);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Go through the roots looking for blocks to free. Warn if any
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * our found (there shouldn't be any).
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar for (i = 0; i < uo_tbl->uobj_tbl_used_blks; i++) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk = uo_tbl->uobj_tbl_uo_root[i];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!blk) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar continue;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar for (j = 0; j < SOL_OFS_UO_BLKSZ; j++) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk->ofs_uoblk_blks[j]) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * This is an error, we may want to free
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ultimately sol_ofs_uobj_free
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * (blk->ofs_uoblk_blks[j]);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ TBL FINI: blk %p, slot %d non null",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk, j);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(blk, sizeof (*blk));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uo_tbl->uobj_tbl_uo_root) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar size = uo_tbl->uobj_tbl_num_blks *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ofs_uobj_blk_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(uo_tbl->uobj_tbl_uo_root, size);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_destroy(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uverbs_uob_init
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - Pointer to the user object to initialize.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * user_handle - A user space handle to associates with the object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Generally used to identify object in asynchronous
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * notifications.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uob_type - The type of user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - Initialized user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Initialize a new user object. The object will have one reference
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * placed on it.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_init(sol_ofs_uobj_t *uobj,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint64_t user_handle, sol_ofs_uobj_type_t uobj_type)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_user_handle = user_handle;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_refcnt = 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_type = uobj_type;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_id = -1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_live = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_init(&uobj->uo_lock, NULL, RW_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_init(&uobj->uo_reflock, NULL, MUTEX_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ofs_uobj_fini
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - Pointer to the user object to be cleaned up.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Performs user object cleanup prior to releasing memory.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarofs_uobj_fini(sol_ofs_uobj_t *uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_destroy(&uobj->uo_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&uobj->uo_reflock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_ref
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - Pointer to the user object
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Place a reference on the specified user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_ref(sol_ofs_uobj_t *uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&uobj->uo_reflock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_refcnt++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uobj->uo_refcnt != 0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&uobj->uo_reflock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_deref
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - Pointer to the user object
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * free_func - Pointer to release function, called if the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * last reference is removed for the user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Remove a reference to a user object. If a free function
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * was specified and the last reference is released, then the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * free function is invoked to release the user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_deref(sol_ofs_uobj_t *uobj,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void (*free_func)(sol_ofs_uobj_t *uobj))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ofs_dbg_str, "UOBJ_DEREF: uobj = %p, "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "refcnt=%d", uobj, uobj->uo_refcnt);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&uobj->uo_reflock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uobj->uo_refcnt != 0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_refcnt--;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uobj->uo_refcnt == 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&uobj->uo_reflock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (free_func)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar free_func(uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&uobj->uo_reflock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_add
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_tbl - A pointer to the user object resource management table
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * to which the object should be added.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - A pointer ot the user object to be added; a reference
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * should exist on this object prior to addition, and the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * object should be removed prior to all references being
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * removed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - The user object "uo_id" is updated and should be
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * used in subsequent lookup operations.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * DDI_SUCCESS on success, else error code.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Add a user object to the specified user object resource management
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_add(sol_ofs_uobj_table_t *uo_tbl, sol_ofs_uobj_t *uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int i, j, empty = -1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_blk_t *blk;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&uo_tbl->uobj_tbl_lock, RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Try to find an empty slot for the new user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar for (i = 0; i < uo_tbl->uobj_tbl_used_blks; i++) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk = uo_tbl->uobj_tbl_uo_root[i];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk != NULL && blk->ofs_uo_blk_avail > 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ ADD: table:%p, available blks:%d",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl, blk->ofs_uo_blk_avail);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar for (j = 0; j < SOL_OFS_UO_BLKSZ; j++) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk->ofs_uoblk_blks[j] == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk->ofs_uoblk_blks[j] = uobj;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_id = j + (i *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_UO_BLKSZ);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_uobj_sz =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_sz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk->ofs_uo_blk_avail--;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_cnt++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto obj_added;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else if (blk == NULL && empty < 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Remember the first empty blk we came across.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar empty = i;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * No entries were available, we must allocate a new block. If we did
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * not find a empty block available, then we must allocate/reallocate
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the root array (copying any existing blk pointers to it).
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (empty < 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uo_tbl->uobj_tbl_used_blks == uo_tbl->uobj_tbl_num_blks) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_blk_t **p;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint_t newsz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar newsz = uo_tbl->uobj_tbl_num_blks + SOL_OFS_UO_BLKSZ;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ ADD: Increasing uobj table size to %d",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar newsz);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar p = kmem_zalloc(newsz * sizeof (*p), KM_NOSLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!p) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ ADD: Mem alloc fail\n");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uo_tbl->uobj_tbl_uo_root) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint_t oldsz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar oldsz = (uint_t)uo_tbl->uobj_tbl_num_blks *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (int)(sizeof (*p));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(uo_tbl->uobj_tbl_uo_root, p, oldsz);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(uo_tbl->uobj_tbl_uo_root, oldsz);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_root = p;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_num_blks = newsz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar empty = uo_tbl->uobj_tbl_used_blks;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_used_blks++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * There are enough free block pointers in the root, allocate
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * a new block.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk = kmem_zalloc(sizeof (*blk), KM_NOSLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!blk) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ ADD: Mem alloc fail\n");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uo_tbl->uobj_tbl_uo_root[empty] == NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_root[empty] = blk;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk->ofs_uo_blk_avail = SOL_OFS_UO_BLKSZ - 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Use the first slot in this new block to add the new user object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_id = empty * SOL_OFS_UO_BLKSZ;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk->ofs_uoblk_blks[0] = uobj;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_uobj_sz = uo_tbl->uobj_tbl_uo_sz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_cnt++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarobj_added:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_remove
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_tbl - A pointer to the user object resource management table
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * from which the object should be removed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - A pointer ot the user object to be removed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * A pointer to the user object that was removed on success, otherwise
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * NULL.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Remove a user object from the specified user resource management
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The uobj uo_lock must be held as a writer before calling this.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_remove(sol_ofs_uobj_table_t *uo_tbl, sol_ofs_uobj_t *uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint_t i, j;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_blk_t *blk;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_t *p;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uo_tbl != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uobj != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar p = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&uo_tbl->uobj_tbl_lock, RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!uobj->uo_live) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ REMOVE: object 0x%P, already removed", (void *)uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto remove_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uo_tbl->uobj_tbl_uo_cnt == 0) || !(uo_tbl->uobj_tbl_uo_root)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The table is empty, just return not found
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Don't panic, userland app could have double free'd
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * let them deal with it.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ REMOVE: table 0x%P empty", (void *)uo_tbl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto remove_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar i = uobj->uo_id / SOL_OFS_UO_BLKSZ;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar j = uobj->uo_id % SOL_OFS_UO_BLKSZ;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (i >= uo_tbl->uobj_tbl_used_blks) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ REMOVE: object id %d exceeds table size",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto remove_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(i < uo_tbl->uobj_tbl_num_blks);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk = uo_tbl->uobj_tbl_uo_root[i];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ REMOVE: object id %d points to invalid root",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto remove_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk->ofs_uoblk_blks[j] == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ REMOVE: object id %d points to invalid block",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto remove_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Mark as dead
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj->uo_live = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar p = blk->ofs_uoblk_blks[j];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk->ofs_uoblk_blks[j] = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk->ofs_uo_blk_avail++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk->ofs_uo_blk_avail == SOL_OFS_UO_BLKSZ) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(blk, sizeof (*blk));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_root[i] = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_tbl->uobj_tbl_uo_cnt--;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarremove_done:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (p);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ofs_uobj_find
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_tbl - A pointer to the user object resource management table
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * to be used for the lookup.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_id - The user object ID to lookup. This ID was set when
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the object was added to the resource management table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * add_ref - A non zero value indicates that the user objects reference
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * count should be updated to reflect and additional
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * reference before it is returned.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * A pointer to the user object associated with the uo_id if found,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * otherwise NULL.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Lookup and return a user object from the specified user resource
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * management table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ofs_uobj_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarofs_uobj_find(sol_ofs_uobj_table_t *uo_tbl, uint32_t uo_id, int add_ref)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t i, j;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_blk_t *blk;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_t *uobj;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uo_tbl != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&uo_tbl->uobj_tbl_lock, RW_READER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uo_tbl->uobj_tbl_uo_cnt == 0) || !(uo_tbl->uobj_tbl_uo_root)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The table is empty, just return not found
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Don't panic, userland app could have double free'd
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * let them deal with it.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ FIND: id %d in tbl 0x%P - tbl empty", uo_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void *)uo_tbl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto find_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar i = uo_id / SOL_OFS_UO_BLKSZ;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar j = uo_id % SOL_OFS_UO_BLKSZ;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (i >= uo_tbl->uobj_tbl_used_blks) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ FIND: Index not valid, %d", uo_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto find_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Get the user object, and if valid perform a get (ref++).
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The caller issuing the find, must release the reference
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * when done.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar blk = uo_tbl->uobj_tbl_uo_root[i];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (blk != NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(i < uo_tbl->uobj_tbl_num_blks);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj = blk->ofs_uoblk_blks[j];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uobj == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ FIND: Index %d not found, blk = %p",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uo_id, blk->ofs_uoblk_blks[j]);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else if (add_ref) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_ref(uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ofs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "UOBJ FIND: Uobject not found, %d", uo_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto find_done;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarfind_done:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uo_tbl->uobj_tbl_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_get_read
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * tbl - Pointer to the user object managment table to
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * be used in the lookup.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_id - The ID to object mapping, assigned to the user
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * object at addition to the table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * A pointer to the user object associated with uo_id or NULL
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * if the entry does not exist.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Lookup a user object and place a reference on it. Acquires
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the object with a READ lock. The reference and lock should
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * be released using the sol_ofs_uobj_put() call.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_get_read(sol_ofs_uobj_table_t *tbl, uint32_t uo_id)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_t *uobj;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj = ofs_uobj_find(tbl, uo_id, 1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&uobj->uo_lock, RW_READER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * If object was destroyed before we got the lock, just release
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * our reference and indicate we didn't find the object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!uobj->uo_live) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_get_write
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * tbl - Pointer to the user object managment table to
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * be used in the lookup.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uo_id - The ID to object mapping, assigned to the user
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * object at addition to the table.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * A pointer to the user object associated with uo_id or NULL
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * if the entry does not exist.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Lookup a user object and place a reference on it. Acquires
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the object with a WRITE lock. The reference and lock should
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * be released using the sol_ofs_uobj_put() call.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_get_write(sol_ofs_uobj_table_t *tbl, uint32_t uo_id)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_t *uobj;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uobj = ofs_uobj_find(tbl, uo_id, 1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&uobj->uo_lock, RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * If object was destroyed before we got the lock, just release
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * our reference and indicate we didn't find the object.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!uobj->uo_live) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_free
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - A pointer to the Solaris User Verbs kernel agent user
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * object to be freed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Called when the user object is no longer referenced, it will release
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * any user object resources and free the container object memory.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * NOTE: Currently there is a stipulation that the user object be the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * first element of any user object specialization.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_free(sol_ofs_uobj_t *uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar size_t sz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Cleanup common user object and then free memory using
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * length based on associated object type.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ofs_uobj_fini(uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sz = uobj->uo_uobj_sz;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sz)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(uobj, sz);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_ofs_uobj_put
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uobj - Pointer to the user object
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Ouput:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Remove a lock associated with a user object, and decrement
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the reference held. On the last deference the user object
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * will be freed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_put(sol_ofs_uobj_t *uobj)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&uobj->uo_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_deref(uobj, sol_ofs_uobj_free);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}