#include <stdbool.h>
#include <stddef.h>
-struct list_head {
- struct list_head *next, *prev;
-};
-struct hlist_head {
- struct hlist_node *first;
-};
+/* Simple doubly linked list implementation. */
-struct hlist_node {
- struct hlist_node *next, **pprev;
+struct list_head {
+ struct list_head *next;
+ struct list_head *prev;
};
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
#define LIST_HEAD_INIT(name) { &(name), &(name) }
-#ifdef LIST_HEAD /* BSD sys/queue.h defines this... */
-# undef LIST_HEAD
-#endif
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
+#undef LIST_HEAD /* BSD sys/queue.h defines this... */
+#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
static inline void
INIT_LIST_HEAD(struct list_head *list)
static inline void
__list_splice(const struct list_head *list,
- struct list_head *prev,
- struct list_head *next)
+ struct list_head *prev, struct list_head *next)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
* You lose the ability to access the tail in O(1).
*/
-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next;
+ struct hlist_node **pprev;
+};
+
+static inline void
+INIT_HLIST_HEAD(struct hlist_head *h)
+{
+ h->first = NULL;
+}
static inline bool
hlist_unhashed(const struct hlist_node *h)
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+#define hlist_entry_safe(ptr, type, member) \
+ ({ typeof(ptr) ____ptr = (ptr); \
+ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+ })
+
/**
* hlist_for_each_entry - iterate over list of given type
- * @tpos: the type * to use as a loop cursor.
- * @pos: the &struct hlist_node to use as a loop cursor.
+ * @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
-#define hlist_for_each_entry(tpos, pos, head, member) \
- for (pos = (head)->first; \
- pos && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
+#define hlist_for_each_entry(pos, head, member) \
+ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
+ pos; \
+ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
/**
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @tpos: the type * to use as a loop cursor.
- * @pos: the &struct hlist_node to use as a loop cursor.
+ * @pos: the type * to use as a loop cursor.
* @n: another &struct hlist_node to use as temporary storage
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
- for (pos = (head)->first; \
- pos && ({ n = pos->next; 1; }) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = n)
+#define hlist_for_each_entry_safe(pos, n, head, member) \
+ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
+ pos && ({ n = pos->member.next; 1; }); \
+ pos = hlist_entry_safe(n, typeof(*pos), member))
#endif /* _WIMLIB_LIST_H */
size_t old_capacity, new_capacity;
struct hlist_head *old_array, *new_array;
struct blob_descriptor *blob;
- struct hlist_node *cur, *tmp;
+ struct hlist_node *tmp;
size_t i;
old_capacity = table->capacity;
table->capacity = new_capacity;
for (i = 0; i < old_capacity; i++) {
- hlist_for_each_entry_safe(blob, cur, tmp, &old_array[i], hash_list) {
+ hlist_for_each_entry_safe(blob, tmp, &old_array[i], hash_list) {
hlist_del(&blob->hash_list);
blob_table_insert_raw(table, blob);
}
{
size_t i;
struct blob_descriptor *blob;
- struct hlist_node *pos;
i = load_size_t_unaligned(hash) % table->capacity;
- hlist_for_each_entry(blob, pos, &table->array[i], hash_list)
+ hlist_for_each_entry(blob, &table->array[i], hash_list)
if (hashes_equal(hash, blob->hash))
return blob;
return NULL;
int (*visitor)(struct blob_descriptor *, void *), void *arg)
{
struct blob_descriptor *blob;
- struct hlist_node *pos, *tmp;
+ struct hlist_node *tmp;
int ret;
for (size_t i = 0; i < table->capacity; i++) {
- hlist_for_each_entry_safe(blob, pos, tmp, &table->array[i],
+ hlist_for_each_entry_safe(blob, tmp, &table->array[i],
hash_list)
{
ret = visitor(blob, arg);
struct wim_inode *d_inode = dentry->d_inode;
size_t pos;
struct wim_inode *inode;
- struct hlist_node *cur;
if (d_inode->i_ino == 0) {
list_add_tail(&d_inode->i_list, &table->extra_inodes);
/* Try adding this dentry to an existing inode. */
pos = d_inode->i_ino % table->capacity;
- hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
+ hlist_for_each_entry(inode, &table->array[pos], i_hlist) {
if (inode->i_ino != d_inode->i_ino) {
continue;
}
list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes);
} else {
size_t pos;
- struct hlist_node *cur;
/* File that can be hardlinked--- search the table for an
* existing inode matching the inode number and device. */
pos = hash_u64(hash_u64(ino) + hash_u64(devno)) % table->capacity;
- hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
+ hlist_for_each_entry(inode, &table->array[pos], i_hlist) {
if (inode->i_ino == ino && inode->i_devno == devno) {
/* Found; use the existing inode. */
return new_dentry_with_existing_inode(name, inode,
struct list_head *head)
{
struct wim_inode *inode, *tmp_inode;
- struct hlist_node *cur, *tmp;
+ struct hlist_node *tmp;
u64 cur_ino = 1;
/* Re-assign inode numbers in the existing list to avoid duplicates. */
/* Assign inode numbers to the new inodes and move them to the image's
* inode list. */
for (size_t i = 0; i < table->capacity; i++) {
- hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist)
- {
+ hlist_for_each_entry_safe(inode, tmp, &table->array[i], i_hlist) {
inode->i_ino = cur_ino++;
inode->i_devno = 0;
list_add_tail(&inode->i_list, head);
const struct wim_inode *inode = dentry->d_inode;
const u8 *hash;
struct hlist_head *head;
- struct hlist_node *cur;
struct blob_descriptor *blob;
hash = inode_get_hash_of_unnamed_data_stream(inode);
head = &blob_table->table[load_size_t_unaligned(hash) %
blob_table->capacity];
- hlist_for_each_entry(blob, cur, head, hash_list_2) {
+ hlist_for_each_entry(blob, head, hash_list_2) {
if (hashes_equal(hash, blob->hash)) {
blob_set_solid_sort_name_from_inode(blob, inode);
break;
struct blob_size_table *tab = _tab;
size_t pos;
struct blob_descriptor *same_size_blob;
- struct hlist_node *tmp;
pos = hash_u64(blob->size) % tab->capacity;
blob->unique_size = 1;
- hlist_for_each_entry(same_size_blob, tmp, &tab->array[pos], hash_list_2) {
+ hlist_for_each_entry(same_size_blob, &tab->array[pos], hash_list_2) {
if (same_size_blob->size == blob->size) {
blob->unique_size = 0;
same_size_blob->unique_size = 0;