If prin_do_scsi_ioctl() fails in update_map_pr() for some reason other than Persistent Reservations not being supported, It shouldn't clear the number of registered keys, since there's no reason to think that it has changed. Similarly, if update_map_pr() fails in mpath_pr_event_handle(), don't assume that the nr_keys_needed was cleared. Just return whatever the value is now. This saves multipathd from doing pointless calls to update_map_pr(), if one of the paths is failing.
Signed-off-by: Benjamin Marzinski <[email protected]> --- multipathd/main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/multipathd/main.c b/multipathd/main.c index 4c86f31e..a7650639 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -4278,7 +4278,9 @@ void unset_pr(struct multipath *mpp) * The number of found keys must be at least as large as *nr_keys, * and if MPATH_PR_SUCCESS is returned and mpp->prflag is PR_SET after * the call, *nr_keys will be set to the number of found keys. Otherwise - * it will be set to 0. + * if mpp->prflag is PR_UNSET it will be set to 0. If MPATH_PR_SUCCESS + * is not returned and mpp->prflag is not PR_UNSET, nr_keys will not be + * changed. */ static int update_map_pr(struct multipath *mpp, struct path *pp, unsigned int *nr_keys) { @@ -4307,11 +4309,12 @@ static int update_map_pr(struct multipath *mpp, struct path *pp, unsigned int *n ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, &resp, 0); if (ret != MPATH_PR_SUCCESS) { - if (ret == MPATH_PR_ILLEGAL_REQ) + if (ret == MPATH_PR_ILLEGAL_REQ) { unset_pr(mpp); + *nr_keys = 0; + } condlog(0, "%s : pr in read keys service action failed Error=%d", mpp->alias, ret); - *nr_keys = 0; return ret; } @@ -4427,7 +4430,7 @@ retry: clear_reg ? "Clearing" : "Setting", pp->dev, ret); } else if (!clear_reg) { if (update_map_pr(mpp, pp, &nr_keys_needed) != MPATH_PR_SUCCESS) - return 0; + return nr_keys_needed; if (mpp->prflag != PR_SET) { memset(¶m, 0, sizeof(param)); clear_reg = true; -- 2.50.1
