]> sourceware.org Git - lvm2.git/commitdiff
lv_manip: enhance for_each_sub_lv
authorZdenek Kabelac <zkabelac@redhat.com>
Wed, 28 Feb 2018 16:00:33 +0000 (17:00 +0100)
committerZdenek Kabelac <zkabelac@redhat.com>
Wed, 28 Feb 2018 20:08:38 +0000 (21:08 +0100)
Fix missing 'externalLV' traversing for thins with external origins.

Replace extra for_each_sub_lv_except_pools() with better
internal logic allowing selectively to cut of processed subLV tree.

Extend error code for function 'fn()' when it returns -1 it will
stop futher tree scan for given LV.

Also a bit simplify code to have only one place that
is calling 'fn()' and use level counter to know
depth of traversing.

Update renaming travering to skip trees for pools
and external origins.

WHATS_NEW
lib/metadata/lv_manip.c
lib/metadata/metadata.h

index 57919306b232c073ec419349cc5b26ff523e0205..6a0a0dcde267bf7b93d49720e530c24b8b843d77 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.178 - 
 =====================================
+  Add external_origin visiting in for_each_sub_lv().
   Ensure cluster commands drop their device cache before locking VG.
   Do not report LV as remotely active when it's locally exclusive in cluster.
   Add deprecate messages for usage of mirrors with mirrorlog.
index ac30dadeba62217d6a16bcde5914bef2b88f06df..35c805ce327d353882c602e9c0313a736f3c6861 100644 (file)
@@ -4341,53 +4341,62 @@ static int _rename_cb(struct logical_volume *lv, void *data)
        return _rename_sub_lv(lv, lv_names->old, lv_names->new);
 }
 
+static int _rename_skip_pools_externals_cb(struct logical_volume *lv, void *data)
+{
+       if (lv_is_pool(lv) || lv_is_external_origin(lv))
+               return -1; /* and skip subLVs */
+
+       return _rename_cb(lv, data);
+}
+
 /*
  * Loop down sub LVs and call fn for each.
  * fn is responsible to log necessary information on failure.
+ * Return value '0' stops whole traversal.
+ * Return value '-1' stops subtree traversal.
  */
-static int _for_each_sub_lv(struct logical_volume *lv, int skip_pools,
+static int _for_each_sub_lv(struct logical_volume *lv, int level,
                            int (*fn)(struct logical_volume *lv, void *data),
                            void *data)
 {
        struct logical_volume *org;
        struct lv_segment *seg;
        uint32_t s;
+       int r;
 
-       if (lv_is_cow(lv) && lv_is_virtual_origin(org = origin_from_cow(lv))) {
-               if (!fn(org, data))
+       if (!lv)
+               return 1;
+
+       if (level++) {
+               if (!(r = fn(lv, data)))
                        return_0;
-               if (!_for_each_sub_lv(org, skip_pools, fn, data))
+               /* Only r == 1 lets you run for_each... */
+               if (r == -1)
+                       return 1;
+       }
+
+       if (lv_is_cow(lv) && lv_is_virtual_origin(org = origin_from_cow(lv))) {
+               if (!_for_each_sub_lv(org, level, fn, data))
                        return_0;
        }
 
        dm_list_iterate_items(seg, &lv->segments) {
-               if (seg->log_lv) {
-                       if (!fn(seg->log_lv, data))
-                               return_0;
-                       if (!_for_each_sub_lv(seg->log_lv, skip_pools, fn, data))
-                               return_0;
-               }
+               if (!_for_each_sub_lv(seg->external_lv, level, fn, data))
+                       return_0;
 
-               if (seg->metadata_lv) {
-                       if (!fn(seg->metadata_lv, data))
-                               return_0;
-                       if (!_for_each_sub_lv(seg->metadata_lv, skip_pools, fn, data))
-                               return_0;
-               }
+               if (!_for_each_sub_lv(seg->log_lv, level, fn, data))
+                       return_0;
 
-               if (seg->pool_lv && !skip_pools) {
-                       if (!fn(seg->pool_lv, data))
-                               return_0;
-                       if (!_for_each_sub_lv(seg->pool_lv, skip_pools, fn, data))
-                               return_0;
-               }
+               if (!_for_each_sub_lv(seg->metadata_lv, level, fn, data))
+                       return_0;
+
+               if (!_for_each_sub_lv(seg->pool_lv, level, fn, data))
+                       return_0;
 
                for (s = 0; s < seg->area_count; s++) {
                        if (seg_type(seg, s) != AREA_LV)
                                continue;
-                       if (!fn(seg_lv(seg, s), data))
-                               return_0;
-                       if (!_for_each_sub_lv(seg_lv(seg, s), skip_pools, fn, data))
+                       if (!_for_each_sub_lv(seg_lv(seg, s), level, fn, data))
                                return_0;
                }
 
@@ -4398,9 +4407,7 @@ static int _for_each_sub_lv(struct logical_volume *lv, int skip_pools,
                for (s = 0; s < seg->area_count; s++) {
                        if ((seg_metatype(seg, s) != AREA_LV) || !seg_metalv(seg, s))
                                continue;
-                       if (!fn(seg_metalv(seg, s), data))
-                               return_0;
-                       if (!_for_each_sub_lv(seg_metalv(seg, s), skip_pools, fn, data))
+                       if (!_for_each_sub_lv(seg_metalv(seg, s), level, fn, data))
                                return_0;
                }
        }
@@ -4415,13 +4422,6 @@ int for_each_sub_lv(struct logical_volume *lv,
        return _for_each_sub_lv(lv, 0, fn, data);
 }
 
-int for_each_sub_lv_except_pools(struct logical_volume *lv,
-                                int (*fn)(struct logical_volume *lv, void *data),
-                                void *data)
-{
-       return _for_each_sub_lv(lv, 1, fn, data);
-}
-
 /*
  * Core of LV renaming routine.
  * VG must be locked by caller.
@@ -4475,7 +4475,7 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
                }
 
                /* rename sub LVs */
-               if (!for_each_sub_lv_except_pools(lv, _rename_cb, (void *) &lv_names))
+               if (!for_each_sub_lv(lv, _rename_skip_pools_externals_cb, (void *) &lv_names))
                        return_0;
 
                /* rename main LV */
index df660a73be595961765528e4cf5a542234d3ccf1..f6b19f44b9381983fae058108f958335e59c715b 100644 (file)
@@ -444,9 +444,6 @@ int add_glv_to_indirect_glvs(struct dm_pool *mem,
 int remove_glv_from_indirect_glvs(struct generic_logical_volume *origin_glv,
                                  struct generic_logical_volume *glv);
 
-int for_each_sub_lv_except_pools(struct logical_volume *lv,
-                                int (*fn)(struct logical_volume *lv, void *data),
-                                void *data);
 int for_each_sub_lv(struct logical_volume *lv,
                    int (*fn)(struct logical_volume *lv, void *data),
                    void *data);
This page took 1.796994 seconds and 5 git commands to generate.