From bb7de6d7e27fe7aa5dd861206bea491bac231f4a Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 26 Oct 2005 14:08:24 +0000 Subject: [PATCH] check parents suspended --- lib/libdm-deptree.c | 66 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/libdm-deptree.c b/lib/libdm-deptree.c index 2612896..2b05823 100644 --- a/lib/libdm-deptree.c +++ b/lib/libdm-deptree.c @@ -362,6 +362,51 @@ int dm_deptree_node_num_children(struct deptree_node *node, uint32_t inverted) return list_size(&node->uses); } +/* + * Returns 1 if no children. + */ +static int _children_suspended(struct deptree_node *node, + uint32_t inverted, + const char *uuid_prefix, + size_t uuid_prefix_len) +{ + struct list *list; + struct deptree_link *dlink; + const struct dm_info *dinfo; + const char *uuid; + + if (inverted) { + if (_nodes_are_linked(&node->deptree->root, node)) + return 1; + list = &node->used_by; + } else { + if (_nodes_are_linked(node, &node->deptree->root)) + return 1; + list = &node->uses; + } + + list_iterate_items(dlink, list) { + if (!(uuid = dm_deptree_node_get_uuid(dlink->node))) { + stack; + continue; + } + + /* Ignore if it doesn't belong to this VG */ + if (uuid_prefix && strncmp(uuid, uuid_prefix, uuid_prefix_len)) + continue; + + if (!(dinfo = dm_deptree_node_get_info(dlink->node))) { + stack; + return 0; + } + + if (!dinfo->suspended) + return 0; + } + + return 1; +} + /* * Set major and minor to zero for root of tree. */ @@ -540,7 +585,6 @@ int dm_deptree_deactivate_children(struct deptree_node *dnode, return 1; } -/* FIXME Walk breadth first? */ int dm_deptree_suspend_children(struct deptree_node *dnode, const char *uuid_prefix, size_t uuid_prefix_len) @@ -552,6 +596,7 @@ int dm_deptree_suspend_children(struct deptree_node *dnode, const char *name; const char *uuid; + /* Suspend nodes at this level of the tree */ while ((child = dm_deptree_next_child(&handle, dnode, 0))) { if (!(dinfo = dm_deptree_node_get_info(child))) { stack; @@ -572,7 +617,10 @@ int dm_deptree_suspend_children(struct deptree_node *dnode, if (uuid_prefix && strncmp(uuid, uuid_prefix, uuid_prefix_len)) continue; - /* FIXME Ensure parents are already suspended */ + /* Ensure immediate parents are already suspended */ + if (!_children_suspended(child, 1, uuid_prefix, uuid_prefix_len)) + continue; + if (!_info_by_dev(dinfo->major, dinfo->minor, 0, &info) || !info.exists) continue; @@ -586,6 +634,20 @@ int dm_deptree_suspend_children(struct deptree_node *dnode, /* Update cached info */ child->info = newinfo; + } + + /* Then suspend any child nodes */ + handle = NULL; + + while ((child = dm_deptree_next_child(&handle, dnode, 0))) { + if (!(uuid = dm_deptree_node_get_uuid(child))) { + stack; + continue; + } + + /* Ignore if it doesn't belong to this VG */ + if (uuid_prefix && strncmp(uuid, uuid_prefix, uuid_prefix_len)) + continue; if (dm_deptree_node_num_children(child, 0)) dm_deptree_suspend_children(child, uuid_prefix, uuid_prefix_len); -- 2.43.5