X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fadd_image.c;h=c4c1033bb2de3b691313bf5c8e1f4955b623a110;hb=34a91e36924e10b924117d91acd116ade58df0b4;hp=de9a465f15d012f82065fc0ce700471e21065472;hpb=c6a1140e085f633273fcf47a6462bd9382ce118a;p=wimlib diff --git a/src/add_image.c b/src/add_image.c index de9a465f..c4c1033b 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -54,49 +54,36 @@ * Adds the dentry tree and security data for a new image to the image metadata * array of the WIMStruct. */ -int +static int add_new_dentry_tree(WIMStruct *w, struct wim_dentry *root_dentry, struct wim_security_data *sd) { - struct wim_lookup_table_entry *metadata_lte; - struct wim_image_metadata *imd; struct wim_image_metadata *new_imd; - - wimlib_assert(root_dentry != NULL); - - DEBUG("Reallocating image metadata array for image_count = %u", - w->hdr.image_count + 1); - imd = CALLOC((w->hdr.image_count + 1), sizeof(struct wim_image_metadata)); - - if (!imd) { - ERROR("Failed to allocate memory for new image metadata array"); - goto err; - } - - memcpy(imd, w->image_metadata, - w->hdr.image_count * sizeof(struct wim_image_metadata)); + struct wim_lookup_table_entry *metadata_lte; + int ret; metadata_lte = new_lookup_table_entry(); if (!metadata_lte) - goto err_free_imd; + return WIMLIB_ERR_NOMEM; metadata_lte->resource_entry.flags = WIM_RESHDR_FLAG_METADATA; + metadata_lte->unhashed = 1; - new_imd = &imd[w->hdr.image_count]; + new_imd = new_image_metadata(); + if (!new_imd) { + free_lookup_table_entry(metadata_lte); + return WIMLIB_ERR_NOMEM; + } new_imd->root_dentry = root_dentry; new_imd->metadata_lte = metadata_lte; new_imd->security_data = sd; new_imd->modified = 1; - FREE(w->image_metadata); - w->image_metadata = imd; - w->hdr.image_count++; - return 0; -err_free_imd: - FREE(imd); -err: - return WIMLIB_ERR_NOMEM; + ret = append_image_metadata(w, new_imd); + if (ret) + put_image_metadata(new_imd, NULL); + return ret; } @@ -104,40 +91,20 @@ err: static int unix_capture_regular_file(const char *path, - uint64_t size, + u64 size, struct wim_inode *inode, struct wim_lookup_table *lookup_table) { - struct wim_lookup_table_entry *lte; - u8 hash[SHA1_HASH_SIZE]; - int ret; - inode->i_attributes = FILE_ATTRIBUTE_NORMAL; /* Empty files do not have to have a lookup table entry. */ - if (size == 0) - return 0; - - /* For each regular file, we must check to see if the file is in - * the lookup table already; if it is, we increment its refcnt; - * otherwise, we create a new lookup table entry and insert it. - * */ - - ret = sha1sum(path, hash); - if (ret) - return ret; + if (size != 0) { + struct wim_lookup_table_entry *lte; + char *file_on_disk; - lte = __lookup_resource(lookup_table, hash); - if (lte) { - lte->refcnt++; - DEBUG("Add lte reference %u for `%s'", lte->refcnt, - path); - } else { - char *file_on_disk = STRDUP(path); - if (!file_on_disk) { - ERROR("Failed to allocate memory for file path"); + file_on_disk = STRDUP(path); + if (!file_on_disk) return WIMLIB_ERR_NOMEM; - } lte = new_lookup_table_entry(); if (!lte) { FREE(file_on_disk); @@ -146,11 +113,9 @@ unix_capture_regular_file(const char *path, lte->file_on_disk = file_on_disk; lte->resource_location = RESOURCE_IN_FILE_ON_DISK; lte->resource_entry.original_size = size; - lte->resource_entry.size = size; - copy_hash(lte->hash, hash); - lookup_table_insert(lookup_table, lte); + lookup_table_insert_unhashed(lookup_table, lte, inode, 0); + inode->i_lte = lte; } - inode->i_lte = lte; return 0; } @@ -869,8 +834,12 @@ wimlib_add_image_multisource(WIMStruct *w, struct wim_security_data *sd; struct wim_image_metadata *imd; struct wim_inode_table inode_table; + struct list_head unhashed_streams; int ret; struct sd_set sd_set; +#ifdef WITH_NTFS_3G + struct _ntfs_volume *ntfs_vol = NULL; +#endif if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NTFS) { #ifdef WITH_NTFS_3G @@ -884,7 +853,7 @@ wimlib_add_image_multisource(WIMStruct *w, return WIMLIB_ERR_INVALID_PARAM; } capture_tree = build_dentry_tree_ntfs; - extra_arg = &w->ntfs_vol; + extra_arg = &ntfs_vol; #else ERROR("wimlib was compiled without support for NTFS-3g, so\n" " cannot capture a WIM image directly from a NTFS volume!"); @@ -950,7 +919,6 @@ wimlib_add_image_multisource(WIMStruct *w, goto out_destroy_inode_table; } sd->total_length = 8; - sd->refcnt = 1; sd_set.sd = sd; sd_set.rb_root.rb_node = NULL; @@ -965,10 +933,9 @@ wimlib_add_image_multisource(WIMStruct *w, goto out_free_security_data; } - - DEBUG("Building dentry tree."); + INIT_LIST_HEAD(&unhashed_streams); + w->lookup_table->unhashed_streams = &unhashed_streams; root_dentry = NULL; - for (size_t i = 0; i < num_sources; i++) { int flags; union wimlib_progress_info progress; @@ -1026,32 +993,39 @@ wimlib_add_image_multisource(WIMStruct *w, goto out_free_dentry_tree; } - DEBUG("Calculating full paths of dentries."); - ret = for_dentry_in_tree(root_dentry, calculate_dentry_full_path, NULL); - if (ret) - goto out_free_dentry_tree; - ret = add_new_dentry_tree(w, root_dentry, sd); - if (ret) + + if (ret) { +#ifdef WITH_NTFS_3G + if (ntfs_vol) + do_ntfs_umount(ntfs_vol); +#endif goto out_free_dentry_tree; + } - imd = &w->image_metadata[w->hdr.image_count - 1]; + imd = w->image_metadata[w->hdr.image_count - 1]; + INIT_LIST_HEAD(&imd->unhashed_streams); + list_splice(&unhashed_streams, &imd->unhashed_streams); + +#ifdef WITH_NTFS_3G + imd->ntfs_vol = ntfs_vol; +#endif DEBUG("Assigning hard link group IDs"); inode_table_prepare_inode_list(&inode_table, &imd->inode_list); ret = xml_add_image(w, name); if (ret) - goto out_destroy_imd; + goto out_put_imd; if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_BOOT) wimlib_set_boot_idx(w, w->hdr.image_count); + ret = 0; goto out_destroy_inode_table; -out_destroy_imd: - destroy_image_metadata(&w->image_metadata[w->hdr.image_count - 1], - w->lookup_table); - w->hdr.image_count--; +out_put_imd: + put_image_metadata(w->image_metadata[--w->hdr.image_count], + w->lookup_table); goto out_destroy_inode_table; out_free_branch: free_dentry_tree(branch, w->lookup_table);