Skip to content

Commit

Permalink
6525 nlm_unexport() should not call nlm_vhold_clean() with g->lock held
Browse files Browse the repository at this point in the history
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Approved by: Dan McDonald <danmcd@omniti.com>
  • Loading branch information
mtelka authored and Dan McDonald committed Dec 28, 2015
1 parent 043552b commit b2b464a
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions usr/src/uts/common/klm/nlm_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1788,20 +1788,18 @@ nlm_host_find_by_sysid(struct nlm_globals *g, sysid_t sysid)
* any, it removes them.
* NOTE: only unused hosts can be in idle state.
*/
void
nlm_host_release(struct nlm_globals *g, struct nlm_host *hostp)
static void
nlm_host_release_locked(struct nlm_globals *g, struct nlm_host *hostp)
{
if (hostp == NULL)
return;

mutex_enter(&g->lock);
ASSERT(MUTEX_HELD(&g->lock));
ASSERT(hostp->nh_refs > 0);

hostp->nh_refs--;
if (hostp->nh_refs != 0) {
mutex_exit(&g->lock);
if (hostp->nh_refs != 0)
return;
}

/*
* The very last reference to the host was dropped,
Expand All @@ -1814,6 +1812,16 @@ nlm_host_release(struct nlm_globals *g, struct nlm_host *hostp)
ASSERT((hostp->nh_flags & NLM_NH_INIDLE) == 0);
TAILQ_INSERT_TAIL(&g->nlm_idle_hosts, hostp, nh_link);
hostp->nh_flags |= NLM_NH_INIDLE;
}

void
nlm_host_release(struct nlm_globals *g, struct nlm_host *hostp)
{
if (hostp == NULL)
return;

mutex_enter(&g->lock);
nlm_host_release_locked(g, hostp);
mutex_exit(&g->lock);
}

Expand Down Expand Up @@ -2074,7 +2082,7 @@ nlm_slock_grant(struct nlm_globals *g,
*/
int
nlm_slreq_register(struct nlm_host *hostp, struct nlm_vhold *nvp,
struct flock64 *flp)
struct flock64 *flp)
{
struct nlm_slreq *slr, *new_slr = NULL;
int ret = EEXIST;
Expand Down Expand Up @@ -2115,7 +2123,7 @@ nlm_slreq_register(struct nlm_host *hostp, struct nlm_vhold *nvp,
*/
int
nlm_slreq_unregister(struct nlm_host *hostp, struct nlm_vhold *nvp,
struct flock64 *flp)
struct flock64 *flp)
{
struct nlm_slreq *slr;

Expand Down Expand Up @@ -2566,6 +2574,14 @@ nlm_unexport(struct exportinfo *exi)
while (hostp != NULL) {
struct nlm_vhold *nvp;

if (hostp->nh_flags & NLM_NH_INIDLE) {
TAILQ_REMOVE(&g->nlm_idle_hosts, hostp, nh_link);
hostp->nh_flags &= ~NLM_NH_INIDLE;
}
hostp->nh_refs++;

mutex_exit(&g->lock);

mutex_enter(&hostp->nh_lock);
TAILQ_FOREACH(nvp, &hostp->nh_vholds_list, nv_link) {
vnode_t *vp;
Expand All @@ -2590,8 +2606,11 @@ nlm_unexport(struct exportinfo *exi)
mutex_enter(&hostp->nh_lock);
nvp->nv_refcnt--;
}

mutex_exit(&hostp->nh_lock);

mutex_enter(&g->lock);
nlm_host_release_locked(g, hostp);

hostp = AVL_NEXT(&g->nlm_hosts_tree, hostp);
}

Expand Down

0 comments on commit b2b464a

Please sign in to comment.