X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fdentry.c;h=a19e02c8f3df54dde88ad1b563d491dd1c5f309f;hp=55da50cff6834063df67cae38477f8db0b6215d2;hb=f50557a7095444c554a066b3837c2999ecd1be31;hpb=3de1ec66f778edda19865482d685bc6f4e17faf7 diff --git a/src/dentry.c b/src/dentry.c index 55da50cf..a19e02c8 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -347,7 +347,7 @@ stream_out_total_length(const struct wim_inode_stream *strm) len += utf16le_len_bytes(strm->stream_name) + 2; /* Account for any necessary padding to the next 8-byte boundary. */ - return (len + 7) & ~7; + return ALIGN(len, 8); } /* @@ -364,12 +364,9 @@ dentry_out_total_length(const struct wim_dentry *dentry) len = dentry_min_len_with_names(dentry->file_name_nbytes, dentry->short_name_nbytes); - len = (len + 7) & ~7; + len = ALIGN(len, 8); - if (inode->i_extra_size) { - len += inode->i_extra_size; - len = (len + 7) & ~7; - } + len += ALIGN(inode->i_extra_size, 8); if (!(inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED)) { /* @@ -396,8 +393,8 @@ dentry_out_total_length(const struct wim_dentry *dentry) if (have_named_data_stream || have_reparse_point_stream) { if (have_reparse_point_stream) - len += (sizeof(struct wim_extra_stream_entry_on_disk) + 7) & ~7; - len += (sizeof(struct wim_extra_stream_entry_on_disk) + 7) & ~7; + len += ALIGN(sizeof(struct wim_extra_stream_entry_on_disk), 8); + len += ALIGN(sizeof(struct wim_extra_stream_entry_on_disk), 8); } } @@ -914,7 +911,7 @@ get_parent_dentry(WIMStruct *wim, const tchar *path, * *dentry_ret. On failure, returns WIMLIB_ERR_NOMEM or an error code resulting * from a failed string conversion. */ -int +static int new_dentry(const tchar *name, struct wim_dentry **dentry_ret) { struct wim_dentry *dentry; @@ -936,9 +933,12 @@ new_dentry(const tchar *name, struct wim_dentry **dentry_ret) return 0; } -static int -_new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret, - bool timeless) +/* Like new_dentry(), but also allocate an inode and associate it with the + * dentry. If set_timestamps=true, the timestamps for the inode will be set to + * the current time; otherwise, they will be left 0. */ +int +new_dentry_with_new_inode(const tchar *name, bool set_timestamps, + struct wim_dentry **dentry_ret) { struct wim_dentry *dentry; struct wim_inode *inode; @@ -948,36 +948,28 @@ _new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret, if (ret) return ret; - if (timeless) - inode = new_timeless_inode(); - else - inode = new_inode(); + inode = new_inode(dentry, set_timestamps); if (!inode) { free_dentry(dentry); return WIMLIB_ERR_NOMEM; } - d_associate(dentry, inode); - *dentry_ret = dentry; return 0; } -/* Like new_dentry(), but also allocate an inode and associate it with the - * dentry. The timestamps for the inode will be set to the current time. */ +/* Like new_dentry(), but also associate the new dentry with the specified inode + * and acquire a reference to each of the inode's blobs. */ int -new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret) +new_dentry_with_existing_inode(const tchar *name, struct wim_inode *inode, + struct wim_dentry **dentry_ret) { - return _new_dentry_with_inode(name, dentry_ret, false); -} - -/* Like new_dentry_with_inode(), but don't bother setting the timestamps for the - * new inode; instead, just leave them as 0, under the presumption that the - * caller will set them itself. */ -int -new_dentry_with_timeless_inode(const tchar *name, struct wim_dentry **dentry_ret) -{ - return _new_dentry_with_inode(name, dentry_ret, true); + int ret = new_dentry(name, dentry_ret); + if (ret) + return ret; + d_associate(*dentry_ret, inode); + inode_ref_blobs(inode); + return 0; } /* Create an unnamed dentry with a new inode for a directory with the default @@ -988,7 +980,7 @@ new_filler_directory(struct wim_dentry **dentry_ret) int ret; struct wim_dentry *dentry; - ret = new_dentry_with_inode(NULL, &dentry); + ret = new_dentry_with_new_inode(NULL, true, &dentry); if (ret) return ret; /* Leave the inode number as 0; this is allowed for non @@ -1304,9 +1296,7 @@ setup_inode_streams(const u8 *p, const u8 *end, struct wim_inode *inode, inode->i_num_streams = 1 + num_extra_streams; - if (likely(inode->i_num_streams <= ARRAY_LEN(inode->i_embedded_streams))) { - inode->i_streams = inode->i_embedded_streams; - } else { + if (unlikely(inode->i_num_streams > ARRAY_LEN(inode->i_embedded_streams))) { inode->i_streams = CALLOC(inode->i_num_streams, sizeof(inode->i_streams[0])); if (!inode->i_streams) @@ -1338,10 +1328,7 @@ setup_inode_streams(const u8 *p, const u8 *end, struct wim_inode *inode, disk_strm = (const struct wim_extra_stream_entry_on_disk *)p; /* Read the length field */ - length = le64_to_cpu(disk_strm->length); - - /* 8-byte align the length */ - length = (length + 7) & ~7; + length = ALIGN(le64_to_cpu(disk_strm->length), 8); /* Make sure the length field is neither so small it doesn't * include all the fixed-length data nor so large it overflows @@ -1431,7 +1418,7 @@ read_dentry(const u8 * restrict buf, size_t buf_len, disk_dentry = (const struct wim_dentry_on_disk*)p; /* Get dentry length. */ - length = (le64_to_cpu(disk_dentry->length) + 7) & ~7; + length = ALIGN(le64_to_cpu(disk_dentry->length), 8); /* Check for end-of-directory. */ if (length <= 8) { @@ -1449,7 +1436,7 @@ read_dentry(const u8 * restrict buf, size_t buf_len, return WIMLIB_ERR_INVALID_METADATA_RESOURCE; /* Allocate new dentry structure, along with a preliminary inode. */ - ret = new_dentry_with_timeless_inode(NULL, &dentry); + ret = new_dentry_with_new_inode(NULL, false, &dentry); if (ret) return ret; @@ -1826,8 +1813,7 @@ write_dentry(const struct wim_dentry * restrict dentry, u8 * restrict p) const struct wim_inode_stream *efs_strm; const u8 *efs_hash; - efs_strm = inode_get_stream(inode, STREAM_TYPE_EFSRPC_RAW_DATA, - NO_STREAM_NAME); + efs_strm = inode_get_unnamed_stream(inode, STREAM_TYPE_EFSRPC_RAW_DATA); efs_hash = efs_strm ? stream_hash(efs_strm) : zero_hash; copy_hash(disk_dentry->default_hash, efs_hash); disk_dentry->num_extra_streams = cpu_to_le16(0); @@ -1843,7 +1829,6 @@ write_dentry(const struct wim_dentry * restrict dentry, u8 * restrict p) */ bool have_named_data_stream = false; bool have_reparse_point_stream = false; - u16 num_extra_streams = 0; const u8 *unnamed_data_stream_hash = zero_hash; const u8 *reparse_point_hash; for (unsigned i = 0; i < inode->i_num_streams; i++) { @@ -1859,7 +1844,9 @@ write_dentry(const struct wim_dentry * restrict dentry, u8 * restrict p) } } - if (have_reparse_point_stream || have_named_data_stream) { + if (unlikely(have_reparse_point_stream || have_named_data_stream)) { + + unsigned num_extra_streams = 0; copy_hash(disk_dentry->default_hash, zero_hash); @@ -1872,19 +1859,22 @@ write_dentry(const struct wim_dentry * restrict dentry, u8 * restrict p) p = write_extra_stream_entry(p, NO_STREAM_NAME, unnamed_data_stream_hash); num_extra_streams++; - } else { - copy_hash(disk_dentry->default_hash, unnamed_data_stream_hash); - } - for (unsigned i = 0; i < inode->i_num_streams; i++) { - const struct wim_inode_stream *strm = &inode->i_streams[i]; - if (stream_is_named_data_stream(strm)) { - p = write_extra_stream_entry(p, strm->stream_name, - stream_hash(strm)); - num_extra_streams++; + for (unsigned i = 0; i < inode->i_num_streams; i++) { + const struct wim_inode_stream *strm = &inode->i_streams[i]; + if (stream_is_named_data_stream(strm)) { + p = write_extra_stream_entry(p, strm->stream_name, + stream_hash(strm)); + num_extra_streams++; + } } + wimlib_assert(num_extra_streams <= 0xFFFF); + + disk_dentry->num_extra_streams = cpu_to_le16(num_extra_streams); + } else { + copy_hash(disk_dentry->default_hash, unnamed_data_stream_hash); + disk_dentry->num_extra_streams = cpu_to_le16(0); } - disk_dentry->num_extra_streams = cpu_to_le16(num_extra_streams); } return p;