int mdeg_unregister(mdeg_handle_t hdl) { mdeg_clnt_t *clnt; mdeg_handle_t mdh; /* should never be called from a callback */ ASSERT(!taskq_member(mdeg.taskq, curthread)); rw_enter(&mdeg.rwlock, RW_WRITER); /* lookup the client */ if ((clnt = mdeg_get_client(hdl)) == NULL) { rw_exit(&mdeg.rwlock); return (MDEG_FAILURE); } MDEG_DBG("client unregistered (0x%lx):\n", hdl); MDEG_DUMP_CLNT(clnt); /* save the handle to prevent reuse */ mdh = clnt->hdl; bzero(clnt, sizeof (mdeg_clnt_t)); clnt->hdl = mdh; mdeg.nclnts--; rw_exit(&mdeg.rwlock); return (MDEG_SUCCESS); }
/* * issue a empty sync op to help empty the delta/log map or the log */ static void top_issue_sync(void *arg) { ufsvfs_t *ufsvfsp = (ufsvfs_t *)arg; ml_unit_t *ul = (ml_unit_t *)ufsvfsp->vfs_log; mt_map_t *mtm = ul->un_logmap; int error = 0; if ((curthread->t_flag & T_DONTBLOCK) == 0) curthread->t_flag |= T_DONTBLOCK; top_begin_sync(ufsvfsp, TOP_COMMIT_ASYNC, 0, &error); if (!error) { top_end_sync(ufsvfsp, &error, TOP_COMMIT_ASYNC, 0); } /* * If we are a taskq thread, decrement mtm_taskq_sync_count and * wake up the thread waiting on the mtm_cv if the mtm_taskq_sync_count * hits zero. */ if (taskq_member(system_taskq, curthread)) { mutex_enter(&mtm->mtm_lock); mtm->mtm_taskq_sync_count--; if (mtm->mtm_taskq_sync_count == 0) { cv_signal(&mtm->mtm_cv); } mutex_exit(&mtm->mtm_lock); } }
/* * Register to receive an event notification when the system * machine description is updated. * * Passing NULL for the node specification parameter is valid * as long as the match specification is also NULL. In this * case, the client will receive a notification when the MD * has been updated, but the callback will not include any * information. The client is then responsible for obtaining * its own copy of the system MD and performing any processing * manually. */ int mdeg_register(mdeg_node_spec_t *pspecp, mdeg_node_match_t *nmatchp, mdeg_cb_t cb, void *cb_arg, mdeg_handle_t *hdlp) { mdeg_clnt_t *clnt; /* should never be called from a callback */ ASSERT(!taskq_member(mdeg.taskq, curthread)); /* node spec and node match must both be valid, or both NULL */ if (((pspecp != NULL) && (nmatchp == NULL)) || ((pspecp == NULL) && (nmatchp != NULL))) { MDEG_DBG("mdeg_register: invalid parameters\n"); return (MDEG_FAILURE); } rw_enter(&mdeg.rwlock, RW_WRITER); clnt = mdeg_alloc_clnt(); ASSERT(clnt); /* * Fill in the rest of the data */ clnt->nmatch = nmatchp; clnt->pspec = pspecp; clnt->cb = cb; clnt->cb_arg = cb_arg; clnt->magic = MDEG_MAGIC; /* do this last */ clnt->valid = B_TRUE; MDEG_DBG("client registered (0x%lx):\n", clnt->hdl); MDEG_DUMP_CLNT(clnt); mdeg.nclnts++; if (mdeg_notify_client_reg(clnt) != MDEG_SUCCESS) { bzero(clnt, sizeof (mdeg_clnt_t)); rw_exit(&mdeg.rwlock); return (MDEG_FAILURE); } rw_exit(&mdeg.rwlock); *hdlp = clnt->hdl; return (MDEG_SUCCESS); }