write.c, lookup table.c: cleanup
authorEric Biggers <ebiggers3@gmail.com>
Sun, 7 Apr 2013 00:21:48 +0000 (19:21 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 7 Apr 2013 00:21:48 +0000 (19:21 -0500)
src/add_image.c
src/list.h
src/lookup_table.c
src/resource.c
src/wimlib.h
src/wimlib_internal.h
src/write.c

index c4c1033..923d361 100644 (file)
@@ -1004,8 +1004,7 @@ wimlib_add_image_multisource(WIMStruct *w,
        }
 
        imd = w->image_metadata[w->hdr.image_count - 1];
-       INIT_LIST_HEAD(&imd->unhashed_streams);
-       list_splice(&unhashed_streams, &imd->unhashed_streams);
+       list_transfer(&unhashed_streams, &imd->unhashed_streams);
 
 #ifdef WITH_NTFS_3G
        imd->ntfs_vol = ntfs_vol;
index 889097b..ff39710 100644 (file)
@@ -145,6 +145,24 @@ static inline void list_splice(const struct list_head *list,
                __list_splice(list, head, head->next);
 }
 
+/* Move the entire list @old to the list @new, overwriting it. */
+static inline void list_transfer(struct list_head *old,
+                                struct list_head *new)
+{
+       struct list_head *prev, *next;
+
+       if (list_empty(old)) {
+               INIT_LIST_HEAD(new);
+       } else {
+               prev = old->prev;
+               next = old->next;
+               new->next = next;
+               new->prev = prev;
+               prev->next = new;
+               next->prev = new;
+       }
+}
+
 /**
  * list_splice_tail - join two lists, each list being a queue
  * @list: the new list to add.
index 4fbcf7e..214e6db 100644 (file)
@@ -914,6 +914,19 @@ retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
        return NULL;
 }
 
+/* Calculate the SHA1 message digest of a stream and move it from the list of
+ * unhashed streams to the stream lookup table, possibly joining it with an
+ * existing lookup table entry for an identical stream.
+ *
+ * @lte:  An unhashed lookup table entry.
+ * @lookup_table:  Lookup table for the WIM.
+ * @lte_ret:  On success, write a pointer to the resulting lookup table
+ *            entry to this location.  This will be the same as @lte
+ *            if it was inserted into the lookup table, or different if
+ *            a duplicate stream was found.
+ *
+ * Returns 0 on success; nonzero if there is an error reading the stream.
+ */
 int
 hash_unhashed_stream(struct wim_lookup_table_entry *lte,
                     struct wim_lookup_table *lookup_table,
@@ -952,9 +965,7 @@ hash_unhashed_stream(struct wim_lookup_table_entry *lte,
                /* No duplicate stream, so we need to insert
                 * this stream into the lookup table and treat
                 * it as a hashed stream. */
-               list_del(&lte->unhashed_list);
                lookup_table_insert(lookup_table, lte);
-               lte->out_refcnt = lte->refcnt;
                lte->unhashed = 0;
        }
        if (lte_ret)
index 8af9225..a7a8319 100644 (file)
@@ -850,6 +850,7 @@ sha1_chunk(const void *buf, size_t len, void *ctx)
        return 0;
 }
 
+/* Calculate the SHA1 message digest of a stream. */
 int
 sha1_resource(struct wim_lookup_table_entry *lte)
 {
index 974fba7..08d74b2 100644 (file)
@@ -431,6 +431,7 @@ union wimlib_progress_info {
                 * ::WIMLIB_COMPRESSION_TYPE_LZX. */
                int      compression_type;
 
+               /** Library internal use only. */
                uint64_t _private;
        } write_streams;
 
index 44a2314..0442aaa 100644 (file)
@@ -363,28 +363,41 @@ resource_is_compressed(const struct resource_entry *entry)
        return (entry->flags & WIM_RESHDR_FLAG_COMPRESSED);
 }
 
+/* Iterate over each inode in a WIM image that has not yet been hashed */
 #define image_for_each_inode(inode, imd) \
        list_for_each_entry(inode, &imd->inode_list, i_list)
 
+/* Iterate over each stream in a WIM image that has not yet been hashed */
 #define image_for_each_unhashed_stream(lte, imd) \
        list_for_each_entry(lte, &imd->unhashed_streams, unhashed_list)
 
+/* Iterate over each stream in a WIM image that has not yet been hashed (safe
+ * against stream removal) */
 #define image_for_each_unhashed_stream_safe(lte, tmp, imd) \
        list_for_each_entry_safe(lte, tmp, &imd->unhashed_streams, unhashed_list)
 
 #if 1
 #  define copy_resource_entry(dst, src) memcpy(dst, src, sizeof(struct resource_entry))
+#  define zero_resource_entry(entry) memset(entry, 0, sizeof(struct resource_entry))
 #else
 static inline void
 copy_resource_entry(struct resource_entry *dst,
                    const struct resource_entry *src)
 {
-       memcpy(dst, src, sizeof(struct resource_entry));
        BUILD_BUG_ON(sizeof(struct resource_entry) != 24);
        ((u64*)dst)[0] = ((u64*)src)[0];
        ((u64*)dst)[1] = ((u64*)src)[1];
        ((u64*)dst)[2] = ((u64*)src)[2];
 }
+
+static inline void
+zero_resource_entry(struct resource_entry *entry)
+{
+       BUILD_BUG_ON(sizeof(struct resource_entry) != 24);
+       ((u64*)entry)[0] = 0;
+       ((u64*)entry)[1] = 0;
+       ((u64*)entry)[2] = 0;
+}
 #endif
 
 /* add_image.c */
@@ -678,8 +691,7 @@ wim_checksum_unhashed_streams(WIMStruct *w);
 #define WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE      0x80000000
 #define WIMLIB_WRITE_FLAG_REUSE_INTEGRITY_TABLE 0x40000000
 #define WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML  0x20000000
-//#define WIMLIB_WRITE_FLAG_OVERWRITE_INPLACE     0x10000000
-#define WIMLIB_WRITE_MASK_PUBLIC               0x0fffffff
+#define WIMLIB_WRITE_MASK_PUBLIC               0x1fffffff
 
 /* We are capturing a tree to be placed in the root of the WIM image */
 #define WIMLIB_ADD_IMAGE_FLAG_ROOT     0x80000000
index 43e81b6..03b6c1e 100644 (file)
@@ -621,11 +621,11 @@ do_write_stream_list(struct list_head *stream_list,
                     struct wim_lookup_table *lookup_table,
                     FILE *out_fp,
                     int out_ctype,
+                    int write_resource_flags,
                     wimlib_progress_func_t progress_func,
-                    union wimlib_progress_info *progress,
-                    int write_resource_flags)
+                    union wimlib_progress_info *progress)
 {
-       int ret;
+       int ret = 0;
        struct wim_lookup_table_entry *lte;
 
        /* For each stream in @stream_list ... */
@@ -645,7 +645,7 @@ do_write_stream_list(struct list_head *stream_list,
                                                   lookup_table,
                                                   &tmp);
                        if (ret)
-                               return ret;
+                               break;
                        if (tmp != lte) {
                                lte = tmp;
                                /* We found a duplicate stream. */
@@ -674,7 +674,7 @@ do_write_stream_list(struct list_head *stream_list,
                                         &lte->output_resource_entry,
                                         write_resource_flags);
                if (ret)
-                       return ret;
+                       break;
                if (lte->unhashed) {
                        list_del(&lte->unhashed_list);
                        lookup_table_insert(lookup_table, lte);
@@ -685,7 +685,7 @@ do_write_stream_list(struct list_head *stream_list,
                                          progress_func,
                                          wim_resource_size(lte));
        }
-       return 0;
+       return ret;
 }
 
 static int
@@ -707,8 +707,10 @@ write_stream_list_serial(struct list_head *stream_list,
        return do_write_stream_list(stream_list,
                                    lookup_table,
                                    out_fp,
-                                   out_ctype, progress_func,
-                                   progress, write_resource_flags);
+                                   out_ctype,
+                                   write_resource_flags,
+                                   progress_func,
+                                   progress);
 }
 
 #ifdef ENABLE_MULTITHREADED_COMPRESSION
@@ -1268,6 +1270,10 @@ write_stream_list(struct list_head *stream_list,
        if (list_empty(stream_list))
                return 0;
 
+       /* Calculate the total size of the streams to be written.  Note: this
+        * will be the uncompressed size, as we may not know the compressed size
+        * yet, and also this will assume that every unhashed stream will be
+        * written (which will not necessarily be the case). */
        list_for_each_entry(lte, stream_list, write_streams_list) {
                num_streams++;
                total_bytes += wim_resource_size(lte);
@@ -1448,8 +1454,7 @@ prepare_streams_for_overwrite(WIMStruct *wim, off_t end_offset,
                lte_set_output_res_entry(wim->image_metadata[i]->metadata_lte,
                                         wim);
        for_lookup_table_entry(wim->lookup_table, lte_set_output_res_entry, wim);
-       INIT_LIST_HEAD(stream_list);
-       list_splice(&args.stream_list, stream_list);
+       list_transfer(&args.stream_list, stream_list);
 out_destroy_stream_size_table:
        destroy_stream_size_table(&args.stream_size_tab);
        return ret;
@@ -1484,8 +1489,8 @@ inode_find_streams_to_write(struct wim_inode *inode,
 static int
 image_find_streams_to_write(WIMStruct *w)
 {
-       struct wim_image_metadata *imd;
        struct find_streams_ctx *ctx;
+       struct wim_image_metadata *imd;
        struct wim_inode *inode;
        struct wim_lookup_table_entry *lte;
 
@@ -1535,10 +1540,8 @@ prepare_stream_list(WIMStruct *wim, int image, struct list_head *stream_list)
        wim->private = &ctx;
        ret = for_image(wim, image, image_find_streams_to_write);
        destroy_stream_size_table(&ctx.stream_size_tab);
-       if (ret == 0) {
-               INIT_LIST_HEAD(stream_list);
-               list_splice(&ctx.stream_list, stream_list);
-       }
+       if (ret == 0)
+               list_transfer(&ctx.stream_list, stream_list);
        return ret;
 }
 
@@ -1622,13 +1625,11 @@ finish_write(WIMStruct *w, int image, int write_flags,
         * it should be a copy of the resource entry for the image that is
         * marked as bootable.  This is not well documented...  */
        if (hdr.boot_idx == 0) {
-               memset(&hdr.boot_metadata_res_entry, 0,
-                      sizeof(struct resource_entry));
+               zero_resource_entry(&hdr.boot_metadata_res_entry);
        } else {
-               memcpy(&hdr.boot_metadata_res_entry,
-                      &w->image_metadata[
-                         hdr.boot_idx - 1]->metadata_lte->output_resource_entry,
-                      sizeof(struct resource_entry));
+               copy_resource_entry(&hdr.boot_metadata_res_entry,
+                           &w->image_metadata[ hdr.boot_idx- 1
+                                       ]->metadata_lte->output_resource_entry);
        }
 
        if (!(write_flags & WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE)) {
@@ -1648,7 +1649,7 @@ finish_write(WIMStruct *w, int image, int write_flags,
                if (write_flags & WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML) {
                        struct wim_header checkpoint_hdr;
                        memcpy(&checkpoint_hdr, &hdr, sizeof(struct wim_header));
-                       memset(&checkpoint_hdr.integrity, 0, sizeof(struct resource_entry));
+                       zero_resource_entry(&checkpoint_hdr.integrity);
                        if (fseeko(out, 0, SEEK_SET)) {
                                ERROR_WITH_ERRNO("Failed to seek to beginning "
                                                 "of WIM being written");
@@ -1692,7 +1693,7 @@ finish_write(WIMStruct *w, int image, int write_flags,
                if (ret)
                        goto out_close_wim;
        } else {
-               memset(&hdr.integrity, 0, sizeof(struct resource_entry));
+               zero_resource_entry(&hdr.integrity);
        }
 
        if (fseeko(out, 0, SEEK_SET) != 0) {
@@ -2038,9 +2039,9 @@ overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
        ret = wimlib_write(w, tmpfile, WIMLIB_ALL_IMAGES,
                           write_flags | WIMLIB_WRITE_FLAG_FSYNC,
                           num_threads, progress_func);
-       if (ret != 0) {
+       if (ret) {
                ERROR("Failed to write the WIM file `%"TS"'", tmpfile);
-               goto err;
+               goto out_unlink;
        }
 
        DEBUG("Renaming `%"TS"' to `%"TS"'", tmpfile, w->filename);
@@ -2061,7 +2062,7 @@ overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
                ERROR_WITH_ERRNO("Failed to rename `%"TS"' to `%"TS"'",
                                 tmpfile, w->filename);
                ret = WIMLIB_ERR_RENAME;
-               goto err;
+               goto out_unlink;
        }
 
        if (progress_func) {
@@ -2086,11 +2087,12 @@ overwrite_wim_via_tmpfile(WIMStruct *w, int write_flags,
                FREE(w->filename);
                w->filename = NULL;
        }
-       return ret;
-err:
+       goto out;
+out_unlink:
        /* Remove temporary file. */
        if (tunlink(tmpfile) != 0)
                WARNING_WITH_ERRNO("Failed to remove `%"TS"'", tmpfile);
+out:
        return ret;
 }