From fc02b46117fdcbe17774fbe7a38bdac7483ebdb5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 19 Aug 2012 02:32:33 -0500 Subject: [PATCH] hardlink fixes --- src/dentry.h | 8 ++++---- src/hardlink.c | 30 +++++++++++++++++------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/dentry.h b/src/dentry.h index f684a7a0..251e86f6 100644 --- a/src/dentry.h +++ b/src/dentry.h @@ -215,12 +215,12 @@ static inline const u8 *dentry_hash(const struct dentry *dentry) static inline size_t dentry_link_group_size(const struct dentry *dentry) { + const struct list_head *cur = &dentry->link_group_list; size_t size = 0; - struct list_head *list; - list_for_each(list, &dentry->link_group_list) + do { size++; - if (size == 0) - size = 1; + cur = cur->next; + } while (cur != &dentry->link_group_list); return size; } diff --git a/src/hardlink.c b/src/hardlink.c index a5d8b9fa..81eb10d4 100644 --- a/src/hardlink.c +++ b/src/hardlink.c @@ -6,7 +6,7 @@ struct link_group { u64 link_group_id; struct link_group *next; - struct list_head dentry_list; + struct list_head *dentry_list; }; struct link_group_table { @@ -46,7 +46,7 @@ int link_group_table_insert(struct dentry *dentry, struct link_group_table *tabl group = table->array[pos]; while (group) { if (group->link_group_id == dentry->hard_link) { - list_add(&dentry->link_group_list, &group->dentry_list); + list_add(&dentry->link_group_list, group->dentry_list); return 0; } group = group->next; @@ -59,8 +59,8 @@ int link_group_table_insert(struct dentry *dentry, struct link_group_table *tabl return WIMLIB_ERR_NOMEM; group->link_group_id = dentry->hard_link; group->next = table->array[pos]; - INIT_LIST_HEAD(&group->dentry_list); - list_add(&dentry->link_group_list, &group->dentry_list); + INIT_LIST_HEAD(&dentry->link_group_list); + group->dentry_list = &dentry->link_group_list; table->array[pos] = group; /* XXX Make the table grow when too many entries have been inserted. */ @@ -100,26 +100,30 @@ u64 assign_link_groups(struct link_group_table *table) struct dentry *dentry; while (group) { next_group = group->next; - if (list_is_singular(&group->dentry_list)) { + 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->dentry_list.next, - 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->dentry_list, - 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; } } -- 2.43.0