]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsblk: fix devtree deallocation
authorKarel Zak <kzak@redhat.com>
Mon, 15 Oct 2018 12:14:33 +0000 (14:14 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 7 Dec 2018 11:32:57 +0000 (12:32 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/lsblk-devtree.c
misc-utils/lsblk.c

index c84ccde73d395aa45991bc40c65842a42ab98fe9..cc0134d03a65fa83687660c4a59a5b2854527d1d 100644 (file)
@@ -23,7 +23,6 @@ struct lsblk_device *lsblk_new_device(struct lsblk_devtree *tree)
        dev->refcount = 1;
 
        dev->tree = tree;
-       lsblk_ref_devtree(dev->tree);
 
         INIT_LIST_HEAD(&dev->deps);
        INIT_LIST_HEAD(&dev->ls_roots);
@@ -68,7 +67,7 @@ static int device_remove_dependences(struct lsblk_device *dev)
 
 void lsblk_unref_device(struct lsblk_device *dev)
 {
-       if (dev)
+       if (!dev)
                return;
 
        if (--dev->refcount <= 0) {
@@ -77,16 +76,12 @@ void lsblk_unref_device(struct lsblk_device *dev)
                device_remove_dependences(dev);
                lsblk_device_free_properties(dev->properties);
 
-               if (dev->tree)
-                       lsblk_devtree_remove_device(dev->tree, dev);
-
                free(dev->name);
                free(dev->dm_name);
                free(dev->filename);
                free(dev->mountpoint);
 
                ul_unref_path(dev->sysfs);
-               lsblk_ref_devtree(dev->tree);
 
                free(dev);
        }
@@ -165,21 +160,16 @@ void lsblk_ref_devtree(struct lsblk_devtree *tr)
 
 void lsblk_unref_devtree(struct lsblk_devtree *tr)
 {
-       if (tr)
+       if (!tr)
                return;
 
        if (--tr->refcount <= 0) {
                DBG(TREE, ul_debugobj(tr, "dealloc"));
 
-               while (!list_empty(&tr->roots)) {
-                       struct lsblk_device *dev = list_entry(tr->roots.next,
-                                               struct lsblk_device, ls_roots);
-                       lsblk_unref_device(dev);
-               }
                while (!list_empty(&tr->devices)) {
                        struct lsblk_device *dev = list_entry(tr->devices.next,
                                                struct lsblk_device, ls_devices);
-                       lsblk_unref_device(dev);
+                       lsblk_devtree_remove_device(tr, dev);
                }
                free(tr);
        }
index 748e3cc341e42b869887bb7f8c32a5c7befeddc9..edc9a20e085272a4f58b2e52595931060cb37aa0 100644 (file)
@@ -1301,7 +1301,7 @@ static int iterate_block_devices(struct lsblk_devtree *tr)
                                continue;
                        }
                        lsblk_devtree_add_device(tr, dev);
-                       lsblk_unref_device(dev);
+                       lsblk_unref_device(dev);                /* keep it referenced by devtree only */
                } else
                        DBG(DEV, ul_debug(" %s: already processed", d->d_name));
 
@@ -1525,7 +1525,7 @@ static void check_sysdevblock(void)
 int main(int argc, char *argv[])
 {
        struct lsblk _ls = { .sort_id = -1, .flags = LSBLK_TREE };
-       struct lsblk_devtree *tr;
+       struct lsblk_devtree *tr = NULL;
        int c, status = EXIT_FAILURE;
        char *outarg = NULL;
        size_t i;
@@ -1850,6 +1850,7 @@ leave:
 
        lsblk_mnt_deinit();
        lsblk_properties_deinit();
+       lsblk_unref_devtree(tr);
 
        return status;
 }