]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/device.c
core/device: rewrite how device unit is removed from Manager.devices_by_sysfs
[thirdparty/systemd.git] / src / core / device.c
index 4f6ecf4d7f9a1e537caf0f4a013de961a25c59ec..1449867e357225644abc0b9f6385e46033591907 100644 (file)
@@ -55,24 +55,31 @@ static int device_by_path(Manager *m, const char *path, Unit **ret) {
 
 static void device_unset_sysfs(Device *d) {
         Hashmap *devices;
-        Device *first;
 
         assert(d);
 
         if (!d->sysfs)
                 return;
 
-        /* Remove this unit from the chain of devices which share the
-         * same sysfs path. */
+        /* Remove this unit from the chain of devices which share the same sysfs path. */
+
         devices = UNIT(d)->manager->devices_by_sysfs;
-        first = hashmap_get(devices, d->sysfs);
-        LIST_REMOVE(same_sysfs, first, d);
 
-        if (first)
-                hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
+        if (d->same_sysfs_prev)
+                /* If this is not the first unit, then simply remove this unit. */
+                d->same_sysfs_prev->same_sysfs_next = d->same_sysfs_next;
+        else if (d->same_sysfs_next)
+                /* If this is the first unit, replace with the next unit. */
+                assert_se(hashmap_replace(devices, d->same_sysfs_next->sysfs, d->same_sysfs_next) >= 0);
         else
+                /* Otherwise, remove the entry. */
                 hashmap_remove(devices, d->sysfs);
 
+        if (d->same_sysfs_next)
+                d->same_sysfs_next->same_sysfs_prev = d->same_sysfs_prev;
+
+        d->same_sysfs_prev = d->same_sysfs_next = NULL;
+
         d->sysfs = mfree(d->sysfs);
 }