Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision 07525cdba517a318677cef4eb379adaea132443a)
+++ uspace/lib/c/include/adt/list.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
@@ -38,4 +38,5 @@
 
 #include <assert.h>
+#include <stdbool.h>
 #include <unistd.h>
 
@@ -72,4 +73,10 @@
 	    iterator = list_get_instance(_link, itype, member), \
 	    _link != &(list).head; _link = _link->next)
+
+#define list_foreach_rev(list, member, itype, iterator) \
+	for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
+	    for (link_t *_link = (list).head.prev; \
+	    iterator = list_get_instance(_link, itype, member), \
+	    _link != &(list).head; _link = _link->prev)
 
 /** Unlike list_foreach(), allows removing items while traversing a list.
@@ -105,5 +112,5 @@
 
 #define assert_link_not_used(link) \
-	assert(((link)->prev == NULL) && ((link)->next == NULL))
+	assert(!link_used(link))
 
 /** Returns true if the link is definitely part of a list. False if not sure. */
@@ -357,4 +364,18 @@
 }
 
+/** Determine if link is used.
+ *
+ * @param link Link
+ * @return @c true if link is used, @c false if not.
+ */
+static inline bool link_used(link_t *link)
+{
+	if (link->prev == NULL && link->next == NULL)
+		return false;
+
+	assert(link->prev != NULL && link->next != NULL);
+	return true;
+}
+
 extern int list_member(const link_t *, const list_t *);
 extern void list_concat(list_t *, list_t *);
