nvmf: release the reservation when unregistering one registrant

Unregistering by a host may cause a reservation held by the host
to be released. If a host is the last remaining reservation holder
or is the only reservation holder, then the reservation is released
when the host unregisters.  This may occur with Acquire/preempt
and Register/unregister commands.

Change-Id: If59fe2fdaa69c8ad70f364618d6c281494ad6245
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446821
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Changpeng Liu 2019-02-28 19:54:52 -05:00
parent 71ac18d1ad
commit 8ccf24ed52

View File

@ -1335,11 +1335,37 @@ nvmf_ns_reservation_add_registrant(struct spdk_nvmf_ns *ns,
return 0;
}
/* release the reservation if the last registrant was removed */
static void
nvmf_ns_reservation_check_release_on_remove_registrant(struct spdk_nvmf_ns *ns,
struct spdk_nvmf_registrant *reg)
{
struct spdk_nvmf_registrant *next_reg;
/* no reservation holder */
if (!ns->holder) {
assert(ns->rtype == 0);
return;
}
next_reg = TAILQ_FIRST(&ns->registrants);
if (next_reg && nvmf_ns_reservation_all_registrants_type(ns)) {
/* the next valid registrant is the new holder now */
ns->holder = next_reg;
} else if (nvmf_ns_reservation_registrant_is_holder(ns, reg)) {
/* release the reservation */
ns->rtype = 0;
ns->crkey = 0;
ns->holder = NULL;
}
}
static void
nvmf_ns_reservation_remove_registrant(struct spdk_nvmf_ns *ns,
struct spdk_nvmf_registrant *reg)
{
TAILQ_REMOVE(&ns->registrants, reg, link);
nvmf_ns_reservation_check_release_on_remove_registrant(ns, reg);
free(reg);
ns->gen++;
return;