+static void remove_dentry(struct dentry *dentry,
+ struct lookup_table *lookup_table)
+{
+ const u8 *hash = dentry->hash;
+ u16 i = 0;
+ struct lookup_table_entry *lte;
+ while (1) {
+ lte = lookup_table_decrement_refcnt(lookup_table, hash);
+ if (lte && lte->num_opened_fds)
+ for (u16 i = 0; i < lte->num_allocated_fds; i++)
+ if (lte->fds[i] && lte->fds[i]->dentry == dentry)
+ lte->fds[i]->dentry = NULL;
+ if (i == dentry->num_ads)
+ break;
+ hash = dentry->ads_entries[i].hash;
+ i++;
+ }
+
+ unlink_dentry(dentry);
+ put_dentry(dentry);
+}
+
+static void dentry_increment_lookup_table_refcnts(struct dentry *dentry,
+ struct lookup_table *lookup_table)
+{
+ u16 i = 0;
+ const u8 *hash = dentry->hash;
+ struct lookup_table_entry *lte;
+ while (1) {
+ lte = __lookup_resource(lookup_table, hash);
+ if (lte)
+ lte->refcnt++;
+ if (i == dentry->num_ads)
+ break;
+ hash = dentry->ads_entries[i].hash;
+ i++;
+ }
+}
+
+/* Change the hash value of the main or alternate file stream in a hard link
+ * group. This needs to be done if the hash of the corresponding lookup table
+ * entry was changed. */
+static void link_group_set_stream_hash(struct dentry *dentry,
+ unsigned stream_idx,
+ const u8 new_hash[])
+{
+ struct list_head *head, *cur;
+
+ if (stream_idx == 0) {
+ head = &dentry->link_group_list;
+ cur = head;
+ do {
+ dentry = container_of(cur, struct dentry, link_group_list);
+ memcpy(dentry->hash, new_hash, WIM_HASH_SIZE);
+ cur = cur->next;
+ } while (cur != head);
+ } else {
+ /* Dentries in the link group share their alternate stream
+ * entries. */
+ wimlib_assert(stream_idx <= dentry->num_ads);
+ memcpy(dentry->ads_entries[stream_idx - 1].hash, new_hash,
+ WIM_HASH_SIZE);
+ }
+}
+