struct link_group {
u64 link_group_id;
struct link_group *next;
- struct list_head *link_group_head;
+ struct list_head *dentry_list;
};
struct link_group_table {
u64 capacity;
};
+#include <sys/mman.h>
struct link_group_table *new_link_group_table(u64 capacity)
{
size_t pos;
struct link_group *group;
- if (dentry->hard_link == 0)
+ if (dentry->hard_link == 0) {
+ INIT_LIST_HEAD(&dentry->link_group_list);
return 0;
+ }
/* Try adding to existing hard link group */
pos = dentry->hard_link % table->capacity;
group = table->array[pos];
while (group) {
if (group->link_group_id == dentry->hard_link) {
- list_add(&dentry->link_group_list, group->link_group_head);
+ list_add(&dentry->link_group_list, group->dentry_list);
return 0;
}
group = group->next;
group = MALLOC(sizeof(struct link_group));
if (!group)
return WIMLIB_ERR_NOMEM;
+ group->link_group_id = dentry->hard_link;
+ group->next = table->array[pos];
INIT_LIST_HEAD(&dentry->link_group_list);
- group->link_group_id = dentry->hard_link;
- group->next = table->array[pos];
- group->link_group_head = &dentry->link_group_list;
- table->array[pos] = group;
+ group->dentry_list = &dentry->link_group_list;
+ table->array[pos] = group;
/* XXX Make the table grow when too many entries have been inserted. */
table->num_entries++;
struct dentry *dentry;
while (group) {
next_group = group->next;
- if (list_empty(group->link_group_head)) {
+ u64 cur_id;
+ struct list_head *dentry_list = group->dentry_list;
+ if (dentry_list->next == dentry_list) {
/* Hard link group of size 1. Change the hard
* link ID to 0 and discard the link_group */
- dentry = container_of(group->link_group_head,
- struct dentry,
- link_group_list);
- dentry->hard_link = 0;
+ cur_id = 0;
FREE(group);
} else {
/* Hard link group of size > 1. Assign the
* dentries in the group the next available hard
* link IDs and queue the group to be
* re-inserted into the table. */
- list_for_each_entry(dentry, group->link_group_head,
- link_group_list)
- dentry->hard_link = id;
+ cur_id = id++;
group->next = remaining_groups;
remaining_groups = group;
- id++;
}
+ struct list_head *cur = dentry_list;
+ do {
+ dentry = container_of(cur,
+ struct dentry,
+ link_group_list);
+ dentry->hard_link = cur_id;
+ cur = cur->next;
+ } while (cur != dentry_list);
group = next_group;
}
}