-/*
- * Removes open file descriptors from a lookup table entry @old_lte where the
- * file descriptors have opened the corresponding file resource in the context
- * of the hard link group @link_group; these file descriptors are extracted and
- * placed in a new lookup table entry, which is returned.
- */
-static struct lookup_table_entry *
-lte_extract_fds(struct lookup_table_entry *old_lte, u64 link_group)
-{
- int ret;
- u16 num_transferred_fds;
- struct lookup_table_entry *new_lte;
-
- new_lte = new_lookup_table_entry();
- if (!new_lte)
- return NULL;
-
- num_transferred_fds = 0;
- for (u16 i = 0; i < old_lte->num_allocated_fds; i++)
- if (old_lte->fds[i] && old_lte->fds[i]->dentry &&
- old_lte->fds[i]->dentry->hard_link == link_group)
- num_transferred_fds++;
- DEBUG("Transferring %u file descriptors",
- num_transferred_fds);
- new_lte->fds = MALLOC(num_transferred_fds * sizeof(new_lte->fds[0]));
- if (!new_lte->fds) {
- FREE(new_lte);
- return NULL;
- }
- for (u16 i = 0, j = 0; ; i++) {
- if (old_lte->fds[i] && old_lte->fds[i]->dentry &&
- old_lte->fds[i]->dentry->hard_link == link_group) {
- struct wimlib_fd *fd = old_lte->fds[i];
- old_lte->fds[i] = NULL;
- fd->lte = new_lte;
- fd->idx = j;
- new_lte->fds[j] = fd;
- if (++j == num_transferred_fds)
- break;
- }
- }
- DEBUG("old_lte: %u fds open; new_lte: %u fds open",
- old_lte->num_opened_fds, new_lte->num_opened_fds);
- old_lte->num_opened_fds -= num_transferred_fds;
- new_lte->num_opened_fds = num_transferred_fds;
- new_lte->num_allocated_fds = num_transferred_fds;
- return new_lte;
-}
-
-/*
- * Transfers an alternate data stream entry to a new lookup table entry
- */
-static void lte_transfer_ads_entry(struct lookup_table_entry *new_lte,
- struct ads_entry *ads_entry)
-{
- list_del(&ads_entry->lte_group_list.list);
- list_add(&ads_entry->lte_group_list.list, &new_lte->lte_group_list);
- ads_entry->lte = new_lte;
-}
-
-/*
- * Transfers a dentry to a new lookup table entry
- */
-static void lte_transfer_dentry(struct lookup_table_entry *new_lte,
- struct dentry *dentry)
-{
- wimlib_assert(dentry->lte_group_list.list.next);
- wimlib_assert(new_lte->lte_group_list.next);
- list_del(&dentry->lte_group_list.list);
- list_add(&dentry->lte_group_list.list, &new_lte->lte_group_list);
- dentry->lte = new_lte;
-}
-
-static void lte_transfer_stream_entries(struct lookup_table_entry *new_lte,
- struct dentry *dentry,
- unsigned stream_idx)
-{
- INIT_LIST_HEAD(&new_lte->lte_group_list);
- if (stream_idx == 0) {
- struct list_head *pos = &dentry->link_group_list;
- do {
- struct dentry *d;
- d = container_of(pos, struct dentry, link_group_list);
- wimlib_assert(d->hard_link == dentry->hard_link);
- lte_transfer_dentry(new_lte, d);
- pos = pos->next;
- } while (pos != &dentry->link_group_list);
- } else {
- struct ads_entry *ads_entry;
- wimlib_assert(stream_idx <= dentry->num_ads);
- ads_entry = &dentry->ads_entries[stream_idx - 1];
- lte_transfer_ads_entry(new_lte, ads_entry);
- }
-}
-