remove_map() should just do what the name says, remove the map.
It is unexpected that it also frees the paths of the map, which
can happen if these paths are in INIT_PARTIAL or INIT_REMOVED
state. This is particularly wrong if remove_map is called from a code path
where other data structures are still holding references to the paths in
question, in particular configure() -> coalesce_paths().

Don't free paths in orphan_paths(). A follow-up patch will make sure
that these paths are freed from the checker loop.

Signed-off-by: Martin Wilck <[email protected]>
---
 libmultipath/structs.c     |  4 ++++
 libmultipath/structs_vec.c | 15 +++------------
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/libmultipath/structs.c b/libmultipath/structs.c
index e6e673f..7df5562 100644
--- a/libmultipath/structs.c
+++ b/libmultipath/structs.c
@@ -139,6 +139,10 @@ alloc_path (void)
        return pp;
 }
 
+/*
+ * we don't set pp->initialized here.
+ * check_removed_path() relies on it being preserved.
+ */
 void
 uninitialize_path(struct path *pp)
 {
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
index 7f5da21..3344005 100644
--- a/libmultipath/structs_vec.c
+++ b/libmultipath/structs_vec.c
@@ -383,18 +383,9 @@ static void orphan_paths(vector pathvec, struct multipath 
*mpp, const char *reas
        struct path * pp;
 
        vector_foreach_slot (pathvec, pp, i) {
-               if (pp->mpp == mpp) {
-                       if (pp->initialized == INIT_REMOVED ||
-                           pp->initialized == INIT_PARTIAL) {
-                               condlog(3, "%s: freeing path in %s state",
-                                       pp->dev,
-                                       pp->initialized == INIT_REMOVED ?
-                                       "removed" : "partial");
-                               vector_del_slot(pathvec, i--);
-                               free_path(pp);
-                       } else
-                               orphan_path(pp, reason);
-               } else if (pp->add_when_online &&
+               if (pp->mpp == mpp)
+                       orphan_path(pp, reason);
+               else if (pp->add_when_online &&
                           strncmp(mpp->wwid, pp->wwid, WWID_SIZE) == 0) {
                        pp->add_when_online = false;
                }
-- 
2.52.0


Reply via email to