X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fhardlink.c;h=90446f98e0a123a4a14f19a4154aa298aa692589;hb=cbd76a9a7f349b42457c290e2970c9f4ecd873c1;hp=e2f6ca0cb77fd29c867a350c4352b3d53044eb9c;hpb=c6aa9e6bfdeee0e08407d0efe02270f2ba4b62c6;p=wimlib diff --git a/src/hardlink.c b/src/hardlink.c index e2f6ca0c..90446f98 100644 --- a/src/hardlink.c +++ b/src/hardlink.c @@ -168,25 +168,32 @@ inode_ref_streams(struct wim_inode *inode) */ int inode_table_new_dentry(struct wim_inode_table *table, const tchar *name, - u64 ino, u64 devno, struct wim_dentry **dentry_ret) + u64 ino, u64 devno, bool noshare, + struct wim_dentry **dentry_ret) { struct wim_dentry *dentry; struct wim_inode *inode; int ret; - ret = new_dentry(name, &dentry); - if (ret) - return ret; - - inode = inode_table_get_inode(table, ino, devno); - if (!inode) { - free_dentry(dentry); - return WIMLIB_ERR_NOMEM; + if (noshare) { + ret = new_dentry_with_timeless_inode(name, &dentry); + if (ret) + return ret; + list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes); + } else { + ret = new_dentry(name, &dentry); + if (ret) + return ret; + inode = inode_table_get_inode(table, ino, devno); + if (!inode) { + free_dentry(dentry); + return WIMLIB_ERR_NOMEM; + } + if (inode->i_nlink > 1) + inode_ref_streams(inode); + dentry->d_inode = inode; + inode_add_dentry(dentry, inode); } - if (inode->i_nlink > 1) - inode_ref_streams(inode); - dentry->d_inode = inode; - inode_add_dentry(dentry, inode); *dentry_ret = dentry; return 0; } @@ -298,8 +305,6 @@ fix_true_inode(struct wim_inode *inode, struct list_head *inode_list) return WIMLIB_ERR_INVALID_DENTRY; } /* Free the unneeded `struct wim_inode'. */ - dentry->d_inode->i_hlist.next = NULL; - dentry->d_inode->i_hlist.pprev = NULL; free_inode(dentry->d_inode); dentry->d_inode = ref_inode; ref_inode->i_nlink++; @@ -458,6 +463,7 @@ fix_inodes(struct wim_inode_table *table, struct list_head *inode_list, INIT_LIST_HEAD(inode_list); for (u64 i = 0; i < table->capacity; i++) { hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist) { + INIT_LIST_HEAD(&inode->i_list); ret = fix_nominal_inode(inode, inode_list, ino_changes_needed); if (ret) return ret; @@ -539,7 +545,13 @@ inode_table_prepare_inode_list(struct wim_inode_table *table, struct hlist_node *cur, *tmp; u64 cur_ino = 1; - INIT_LIST_HEAD(head); + list_for_each_entry(inode, head, i_list) { + if (inode->i_nlink > 1) + inode->i_ino = cur_ino++; + else + inode->i_ino = 0; + } + for (size_t i = 0; i < table->capacity; i++) { hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist) {