summaryrefslogtreecommitdiffstats
path: root/misc-utils
diff options
context:
space:
mode:
authorKarel Zak2018-10-15 13:53:19 +0200
committerKarel Zak2018-12-07 12:32:57 +0100
commit21d4a48c9cf304e771a7554b54f75df8e8565e34 (patch)
tree3264c07157410288c55b65d264bbdac7aee8afbc /misc-utils
parentlsblk: remove badly named debug interface name (diff)
downloadkernel-qcow2-util-linux-21d4a48c9cf304e771a7554b54f75df8e8565e34.tar.gz
kernel-qcow2-util-linux-21d4a48c9cf304e771a7554b54f75df8e8565e34.tar.xz
kernel-qcow2-util-linux-21d4a48c9cf304e771a7554b54f75df8e8565e34.zip
lsblk: cleanup device reference in the tree
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils')
-rw-r--r--misc-utils/lsblk-devtree.c38
-rw-r--r--misc-utils/lsblk.h3
2 files changed, 37 insertions, 4 deletions
diff --git a/misc-utils/lsblk-devtree.c b/misc-utils/lsblk-devtree.c
index 3c71d24e4..c84ccde73 100644
--- a/misc-utils/lsblk-devtree.c
+++ b/misc-utils/lsblk-devtree.c
@@ -77,8 +77,8 @@ void lsblk_unref_device(struct lsblk_device *dev)
device_remove_dependences(dev);
lsblk_device_free_properties(dev->properties);
- list_del_init(&dev->ls_roots);
- list_del_init(&dev->ls_devices);
+ if (dev->tree)
+ lsblk_devtree_remove_device(dev->tree, dev);
free(dev->name);
free(dev->dm_name);
@@ -187,7 +187,11 @@ void lsblk_unref_devtree(struct lsblk_devtree *tr)
int lsblk_devtree_add_root(struct lsblk_devtree *tr, struct lsblk_device *dev)
{
- lsblk_ref_device(dev);
+ if (!lsblk_devtree_has_device(tr, dev))
+ lsblk_devtree_add_device(tr, dev);
+
+ /* We don't increment reference counter for tr->roots list. The primary
+ * reference is tr->devices */
DBG(TREE, ul_debugobj(tr, "add root device 0x%p [%s]", dev, dev->name));
list_add_tail(&dev->ls_roots, &tr->roots);
@@ -239,6 +243,21 @@ int lsblk_devtree_next_device(struct lsblk_devtree *tr,
return rc;
}
+int lsblk_devtree_has_device(struct lsblk_devtree *tr, struct lsblk_device *dev)
+{
+ struct lsblk_device *x = NULL;
+ struct lsblk_iter itr;
+
+ lsblk_reset_iter(&itr, LSBLK_ITER_FORWARD);
+
+ while (lsblk_devtree_next_device(tr, &itr, &x) == 0) {
+ if (x == dev)
+ return 1;
+ }
+
+ return 0;
+}
+
struct lsblk_device *lsblk_devtree_get_device(struct lsblk_devtree *tr, const char *name)
{
struct lsblk_device *dev = NULL;
@@ -254,4 +273,17 @@ struct lsblk_device *lsblk_devtree_get_device(struct lsblk_devtree *tr, const ch
return NULL;
}
+int lsblk_devtree_remove_device(struct lsblk_devtree *tr, struct lsblk_device *dev)
+{
+ DBG(TREE, ul_debugobj(tr, "remove device 0x%p [%s]", dev, dev->name));
+
+ if (!lsblk_devtree_has_device(tr, dev))
+ return 1;
+
+ list_del_init(&dev->ls_roots);
+ list_del_init(&dev->ls_devices);
+ lsblk_unref_device(dev);
+
+ return 0;
+}
diff --git a/misc-utils/lsblk.h b/misc-utils/lsblk.h
index e2cafb529..6c095246d 100644
--- a/misc-utils/lsblk.h
+++ b/misc-utils/lsblk.h
@@ -198,7 +198,8 @@ int lsblk_devtree_add_device(struct lsblk_devtree *tr, struct lsblk_device *dev)
int lsblk_devtree_next_device(struct lsblk_devtree *tr,
struct lsblk_iter *itr,
struct lsblk_device **dev);
+int lsblk_devtree_has_device(struct lsblk_devtree *tr, struct lsblk_device *dev);
struct lsblk_device *lsblk_devtree_get_device(struct lsblk_devtree *tr, const char *name);
-
+int lsblk_devtree_remove_device(struct lsblk_devtree *tr, struct lsblk_device *dev);
#endif /* UTIL_LINUX_LSBLK_H */