* *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;
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;
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
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
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)
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;
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);
*/
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++) {
}
}
- 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);
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;