dentry_full_path(struct wim_dentry *dentry);
extern int
-new_dentry(const tchar *name, struct wim_dentry **dentry_ret);
+new_dentry_with_new_inode(const tchar *name, bool set_timestamps,
+ struct wim_dentry **dentry_ret);
extern int
-new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret);
-
-extern int
-new_dentry_with_timeless_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);
extern void
dentry_tree_clear_inode_visited(struct wim_dentry *root);
#define FILE_ATTRIBUTE_VIRTUAL 0x00010000
extern struct wim_inode *
-new_inode(void) _malloc_attribute;
-
-extern struct wim_inode *
-new_timeless_inode(void) _malloc_attribute;
+new_inode(struct wim_dentry *dentry, bool set_timestamps);
/* Iterate through each alias of the specified inode. */
#define inode_for_each_dentry(dentry, inode) \
* *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
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 utf16lechar NO_STREAM_NAME[1];
-/* Allocate a new inode. Set the timestamps to the current time. */
+/* Allocate a new inode and associate the specified dentry with it. */
struct wim_inode *
-new_inode(void)
+new_inode(struct wim_dentry *dentry, bool set_timestamps)
{
- struct wim_inode *inode = new_timeless_inode();
- if (inode) {
+ struct wim_inode *inode;
+
+ inode = CALLOC(1, sizeof(struct wim_inode));
+ if (!inode)
+ return NULL;
+
+ inode->i_security_id = -1;
+ /*inode->i_nlink = 0;*/
+ inode->i_not_rpfixed = 1;
+ INIT_LIST_HEAD(&inode->i_list);
+ INIT_LIST_HEAD(&inode->i_dentry);
+ if (set_timestamps) {
u64 now = now_as_wim_timestamp();
inode->i_creation_time = now;
inode->i_last_access_time = now;
inode->i_last_write_time = now;
}
- return inode;
-}
-
-/* Allocate a new inode. Leave the timestamps zeroed out. */
-struct wim_inode *
-new_timeless_inode(void)
-{
- struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
- if (inode) {
- inode->i_security_id = -1;
- /*inode->i_nlink = 0;*/
- inode->i_not_rpfixed = 1;
- INIT_LIST_HEAD(&inode->i_list);
- INIT_LIST_HEAD(&inode->i_dentry);
- }
+ d_associate(dentry, inode);
return inode;
}
if (noshare) {
/* File that cannot be hardlinked--- Return a new inode with its
* inode and device numbers left at 0. */
- ret = new_dentry_with_timeless_inode(name, &dentry);
+ ret = new_dentry_with_new_inode(name, false, &dentry);
if (ret)
return ret;
list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes);
struct hlist_node *cur;
/* File that can be hardlinked--- search the table for an
- * existing inode matching the inode number and device;
- * otherwise create a new inode. */
- ret = new_dentry(name, &dentry);
- if (ret)
- return ret;
-
- /* Search for an existing inode having the same inode number and
- * device number. */
+ * existing inode matching the inode number and device. */
pos = hash_u64(hash_u64(ino) + hash_u64(devno)) % table->capacity;
hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
if (inode->i_ino == ino && inode->i_devno == devno) {
/* Found; use the existing inode. */
- inode_ref_blobs(inode);
- goto have_inode;
+ return new_dentry_with_existing_inode(name, inode,
+ dentry_ret);
}
}
- /* Create a new inode and insert it into the table. */
- inode = new_timeless_inode();
- if (!inode) {
- free_dentry(dentry);
- return WIMLIB_ERR_NOMEM;
- }
+ /* Not found; create a new inode and add it to the table. */
+ ret = new_dentry_with_new_inode(name, false, &dentry);
+ if (ret)
+ return ret;
+ inode = dentry->d_inode;
inode->i_ino = ino;
inode->i_devno = devno;
hlist_add_head(&inode->i_hlist, &table->array[pos]);
table->num_entries++;
- have_inode:
- d_associate(dentry, inode);
}
*dentry_ret = dentry;
return 0;
if (get_dentry_child_with_name(parent, basename, WIMLIB_CASE_SENSITIVE))
return -EEXIST;
- if (new_dentry_with_inode(basename, &new_dentry))
+ if (new_dentry_with_new_inode(basename, true, &new_dentry))
return -ENOMEM;
new_inode = new_dentry->d_inode;
if (get_dentry_child_with_name(dir, new_name, WIMLIB_CASE_SENSITIVE))
return -EEXIST;
- if (new_dentry(new_name, &new_alias))
+ if (new_dentry_with_existing_inode(new_name, inode, &new_alias))
return -ENOMEM;
- inode_ref_blobs(inode);
- d_associate(new_alias, inode);
dentry_add_child(dir, new_alias);
touch_inode(dir->d_inode);
return 0;