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(&param, 0, sizeof(param));
                        clear_reg = true;
-- 
2.50.1


Reply via email to