static u64 __dentry_total_length(const struct dentry *dentry, u64 length)
{
- const struct inode *inode = dentry->inode;
+ const struct inode *inode = dentry->d_inode;
for (u16 i = 0; i < inode->num_ads; i++)
length += ads_entry_total_length(&inode->ads_entries[i]);
return (length + 7) & ~7;
if (ret != 0)
return ret;
- child = root->inode->children;
+ child = root->d_inode->children;
if (!child)
return 0;
if (ret != 0)
return ret;
child = child->next;
- } while (child != root->inode->children);
+ } while (child != root->d_inode->children);
return 0;
}
struct dentry *child;
struct dentry *next;
- child = root->inode->children;
+ child = root->d_inode->children;
if (child) {
do {
next = child->next;
if (ret != 0)
return ret;
child = next;
- } while (child != root->inode->children);
+ } while (child != root->d_inode->children);
}
return visitor(root, arg);
}
{
struct dentry *child;
- child = dentry->inode->children;
+ child = dentry->d_inode->children;
dentry->subdir_offset = *subdir_offset_p;
if (child) {
do {
*subdir_offset_p += dentry_correct_total_length(child);
child = child->next;
- } while (child != dentry->inode->children);
+ } while (child != dentry->d_inode->children);
/* End-of-directory dentry on disk. */
*subdir_offset_p += 8;
do {
calculate_subdir_offsets(child, subdir_offset_p);
child = child->next;
- } while (child != dentry->inode->children);
+ } while (child != dentry->d_inode->children);
} else {
/* On disk, childless directories have a valid subdir_offset
* that points to an 8-byte end-of-directory dentry. Regular
struct dentry *child;
size_t name_len;
- child = dentry->inode->children;
+ child = dentry->d_inode->children;
if (child) {
name_len = strlen(name);
do {
if (dentry_has_name(child, name, name_len))
return child;
child = child->next;
- } while (child != dentry->inode->children);
+ } while (child != dentry->d_inode->children);
}
return NULL;
}
if (*path == '\0')
return cur_dir;
- child = cur_dir->inode->children;
+ child = cur_dir->d_inode->children;
if (child) {
new_path = path_next_part(path, &base_len);
do {
if (dentry_has_name(child, path, base_len))
return get_dentry_relative_path(child, new_path);
child = child->next;
- } while (child != cur_dir->inode->children);
+ } while (child != cur_dir->d_inode->children);
}
return NULL;
}
if (!dentry)
return NULL;
else
- return dentry->inode;
+ return dentry->d_inode;
}
/* Returns the dentry that corresponds to the parent directory of @path, or NULL
{
const u8 *hash;
struct lookup_table_entry *lte;
- const struct inode *inode = dentry->inode;
+ const struct inode *inode = dentry->d_inode;
time_t time;
char *p;
puts("\"");
printf("Short Name Length = %hu\n", dentry->short_name_len);
printf("Full Path (UTF-8) = \"%s\"\n", dentry->full_path_utf8);
- lte = inode_stream_lte(dentry->inode, 0, lookup_table);
+ lte = inode_stream_lte(dentry->d_inode, 0, lookup_table);
if (lte) {
print_lookup_table_entry(lte);
} else {
dentry = new_dentry(name);
if (dentry) {
if (timeless)
- dentry->inode = new_timeless_inode();
+ dentry->d_inode = new_timeless_inode();
else
- dentry->inode = new_inode();
- if (dentry->inode) {
- inode_add_dentry(dentry, dentry->inode);
+ dentry->d_inode = new_inode();
+ if (dentry->d_inode) {
+ inode_add_dentry(dentry, dentry->d_inode);
} else {
free_dentry(dentry);
dentry = NULL;
}
+static int init_ads_entry(struct ads_entry *ads_entry, const char *name)
+{
+ int ret = 0;
+ memset(ads_entry, 0, sizeof(*ads_entry));
+ if (name && *name)
+ ret = change_ads_name(ads_entry, name);
+ return ret;
+}
+
+static void destroy_ads_entry(struct ads_entry *ads_entry)
+{
+ FREE(ads_entry->stream_name);
+ FREE(ads_entry->stream_name_utf8);
+}
+
+
/* Frees an inode. */
void free_inode(struct inode *inode)
{
if (inode) {
- inode_free_ads_entries(inode);
+ if (inode->ads_entries) {
+ for (u16 i = 0; i < inode->num_ads; i++)
+ destroy_ads_entry(&inode->ads_entries[i]);
+ FREE(inode->ads_entries);
+ }
#ifdef WITH_FUSE
wimlib_assert(inode->num_opened_fds == 0);
FREE(inode->fds);
FREE(dentry->file_name_utf8);
FREE(dentry->short_name);
FREE(dentry->full_path_utf8);
- put_inode(dentry->inode);
+ put_inode(dentry->d_inode);
FREE(dentry);
}
static int do_free_dentry(struct dentry *dentry, void *__lookup_table)
{
struct lookup_table *lookup_table = __lookup_table;
- struct lookup_table_entry *lte;
- struct inode *inode = dentry->inode;
unsigned i;
if (lookup_table) {
+ struct lookup_table_entry *lte;
+ struct inode *inode = dentry->d_inode;
wimlib_assert(inode->link_count);
for (i = 0; i <= inode->num_ads; i++) {
lte = inode_stream_lte(inode, i, lookup_table);
- lte_decrement_refcnt(lte, lookup_table);
+ if (lte)
+ lte_decrement_refcnt(lte, lookup_table);
}
}
- wimlib_assert(dentry->refcnt != 0);
- if (--dentry->refcnt == 0)
- free_dentry(dentry);
+ put_dentry(dentry);
return 0;
}
{
wimlib_assert(dentry_is_directory(parent));
dentry->parent = parent;
- if (parent->inode->children) {
+ if (parent->d_inode->children) {
/* Not an only child; link to siblings. */
- dentry->next = parent->inode->children;
- dentry->prev = parent->inode->children->prev;
+ dentry->next = parent->d_inode->children;
+ dentry->prev = parent->d_inode->children->prev;
dentry->next->prev = dentry;
dentry->prev->next = dentry;
} else {
/* Only child; link to parent. */
- parent->inode->children = dentry;
+ parent->d_inode->children = dentry;
dentry->next = dentry;
dentry->prev = dentry;
}
}
+#ifdef WITH_FUSE
/*
* Unlink a dentry from the directory tree.
*
if (dentry_is_root(dentry))
return;
if (dentry_is_only_child(dentry)) {
- dentry->parent->inode->children = NULL;
+ dentry->parent->d_inode->children = NULL;
} else {
if (dentry_is_first_sibling(dentry))
- dentry->parent->inode->children = dentry->next;
+ dentry->parent->d_inode->children = dentry->next;
dentry->next->prev = dentry->prev;
dentry->prev->next = dentry->next;
}
}
-
+#endif
/* Parameters for calculate_dentry_statistics(). */
struct image_statistics {
else
++*stats->file_count;
- for (unsigned i = 0; i <= dentry->inode->num_ads; i++) {
- lte = inode_stream_lte(dentry->inode, i, stats->lookup_table);
+ for (unsigned i = 0; i <= dentry->d_inode->num_ads; i++) {
+ lte = inode_stream_lte(dentry->d_inode, i, stats->lookup_table);
if (lte) {
*stats->total_bytes += wim_resource_size(lte);
if (++lte->out_refcnt == 1)
int verify_dentry(struct dentry *dentry, void *wim)
{
const WIMStruct *w = wim;
- const struct inode *inode = dentry->inode;
+ const struct inode *inode = dentry->d_inode;
int ret = WIMLIB_ERR_INVALID_DENTRY;
- if (!dentry->inode->verified) {
- ret = verify_inode(dentry->inode, w);
+ if (!dentry->d_inode->verified) {
+ ret = verify_inode(dentry->d_inode, w);
if (ret != 0)
goto out;
}
}
#endif
-
-static int init_ads_entry(struct ads_entry *ads_entry, const char *name)
-{
- int ret = 0;
- memset(ads_entry, 0, sizeof(*ads_entry));
- if (name && *name)
- ret = change_ads_name(ads_entry, name);
- return ret;
-}
-
-static void destroy_ads_entry(struct ads_entry *ads_entry)
-{
- FREE(ads_entry->stream_name);
- FREE(ads_entry->stream_name_utf8);
-}
-
-
-void inode_free_ads_entries(struct inode *inode)
-{
- if (inode->ads_entries) {
- for (u16 i = 0; i < inode->num_ads; i++)
- destroy_ads_entry(&inode->ads_entries[i]);
- FREE(inode->ads_entries);
- }
-}
-
#if defined(WITH_FUSE) || defined(WITH_NTFS_3G)
/*
* Add an alternate stream entry to an inode and return a pointer to it, or NULL
/* We've read all the data for this dentry. Set the names and their
* lengths, and we've done. */
- dentry->inode = inode;
+ dentry->d_inode = inode;
dentry->file_name = file_name;
dentry->file_name_utf8 = file_name_utf8;
dentry->short_name = short_name;
child->parent = dentry;
prev_child = child;
- inode_add_dentry(child, child->inode);
+ inode_add_dentry(child, child->d_inode);
/* If there are children of this child, call this procedure
* recursively. */
prev_child->next = first_child;
first_child->prev = prev_child;
}
- dentry->inode->children = first_child;
+ dentry->d_inode->children = first_child;
return ret;
}
{
u8 *orig_p = p;
const u8 *hash;
- const struct inode *inode = dentry->inode;
+ const struct inode *inode = dentry->d_inode;
/* We calculate the correct length of the dentry ourselves because the
* dentry->length field may been set to an unexpected value from when we
* recursively writing the directory trees rooted at each of the child
* dentries, since the on-disk dentries for a dentry's children are
* always located at consecutive positions in the metadata resource! */
- child = parent->inode->children;
+ child = parent->d_inode->children;
if (child) {
do {
p = write_dentry(child, p);
child = child->next;
- } while (child != parent->inode->children);
+ } while (child != parent->d_inode->children);
}
/* write end of directory entry */
do {
p = write_dentry_tree_recursive(child, p);
child = child->next;
- } while (child != parent->inode->children);
+ } while (child != parent->d_inode->children);
}
return p;
}
*/
struct dentry {
/* The inode for this dentry */
- struct inode *inode;
+ struct inode *d_inode;
/* The parent of this directory entry. */
struct dentry *parent;
extern struct ads_entry *inode_get_ads_entry(struct inode *inode,
const char *stream_name,
u16 *idx_ret);
-extern void inode_free_ads_entries(struct inode *inode);
-
extern struct ads_entry *inode_add_ads(struct inode *dentry,
const char *stream_name);
static inline bool dentry_is_first_sibling(const struct dentry *dentry)
{
- return dentry_is_root(dentry) || dentry->parent->inode->children == dentry;
+ return dentry_is_root(dentry) || dentry->parent->d_inode->children == dentry;
}
static inline bool dentry_is_only_child(const struct dentry *dentry)
static inline bool dentry_is_directory(const struct dentry *dentry)
{
- return inode_is_directory(dentry->inode);
+ return inode_is_directory(dentry->d_inode);
}
/* For our purposes, we consider "real" symlinks and "junction points" to both
static inline bool dentry_is_symlink(const struct dentry *dentry)
{
- return inode_is_symlink(dentry->inode);
+ return inode_is_symlink(dentry->d_inode);
}
static inline bool inode_is_regular_file(const struct inode *inode)
static inline bool dentry_is_regular_file(const struct dentry *dentry)
{
- return inode_is_regular_file(dentry->inode);
+ return inode_is_regular_file(dentry->d_inode);
}
static inline bool dentry_is_empty_directory(const struct dentry *dentry)
{
- return dentry_is_directory(dentry) && dentry->inode->children == NULL;
+ return dentry_is_directory(dentry) && dentry->d_inode->children == NULL;
}
#endif
int out_fd;
int ret;
- struct inode *inode = dentry->inode;
+ struct inode *inode = dentry->d_inode;
if (!((extract_flags & WIMLIB_EXTRACT_FLAG_MULTI_IMAGE)
&& (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
int extract_flags)
{
struct lookup_table_entry *lte;
- const struct inode *inode = dentry->inode;
+ const struct inode *inode = dentry->d_inode;
lte = inode_unnamed_lte(inode, w->lookup_table);
const WIMStruct *w)
{
char target[4096];
- ssize_t ret = inode_readlink(dentry->inode, target, sizeof(target), w);
+ ssize_t ret = inode_readlink(dentry->d_inode, target, sizeof(target), w);
if (ret <= 0) {
ERROR("Could not read the symbolic link from dentry `%s'",
dentry->full_path_utf8);
output_path[len + dentry->full_path_utf8_len] = '\0';
struct timeval tv[2];
- wim_timestamp_to_timeval(dentry->inode->last_access_time, &tv[0]);
- wim_timestamp_to_timeval(dentry->inode->last_write_time, &tv[1]);
+ wim_timestamp_to_timeval(dentry->d_inode->last_access_time, &tv[0]);
+ wim_timestamp_to_timeval(dentry->d_inode->last_write_time, &tv[1]);
if (lutimes(output_path, tv) != 0) {
WARNING("Failed to set timestamp on file `%s': %s",
output_path, strerror(errno));
int inode_table_insert(struct dentry *dentry, void *__table)
{
struct inode_table *table = __table;
- struct inode *d_inode = dentry->inode;
+ struct inode *d_inode = dentry->d_inode;
if (d_inode->ino == 0) {
/* Single inode--- Add to the list of extra inodes (we can't put
u64 last_atime = 0;
inode_for_each_dentry(dentry, inode) {
- if (!ref_dentry || dentry->inode->num_ads > ref_dentry->inode->num_ads)
+ if (!ref_dentry || dentry->d_inode->num_ads > ref_dentry->d_inode->num_ads)
ref_dentry = dentry;
- if (dentry->inode->creation_time > last_ctime)
- last_ctime = dentry->inode->creation_time;
- if (dentry->inode->last_write_time > last_mtime)
- last_mtime = dentry->inode->last_write_time;
- if (dentry->inode->last_access_time > last_atime)
- last_atime = dentry->inode->last_access_time;
+ if (dentry->d_inode->creation_time > last_ctime)
+ last_ctime = dentry->d_inode->creation_time;
+ if (dentry->d_inode->last_write_time > last_mtime)
+ last_mtime = dentry->d_inode->last_write_time;
+ if (dentry->d_inode->last_access_time > last_atime)
+ last_atime = dentry->d_inode->last_access_time;
}
- ref_inode = ref_dentry->inode;
+ ref_inode = ref_dentry->d_inode;
ref_inode->link_count = 1;
list_del(&inode->dentry_list);
inode_for_each_dentry(dentry, ref_inode) {
if (dentry != ref_dentry) {
- if (!inodes_consistent(ref_inode, dentry->inode)) {
+ if (!inodes_consistent(ref_inode, dentry->d_inode)) {
inconsistent_inode(ref_inode);
return WIMLIB_ERR_INVALID_DENTRY;
}
/* Free the unneeded `struct inode'. */
- free_inode(dentry->inode);
- dentry->inode = ref_inode;
+ free_inode(dentry->d_inode);
+ dentry->d_inode = ref_inode;
ref_inode->link_count++;
}
}
* least one data stream with a non-zero hash, and another list that
* contains the dentries that have a zero hash for all data streams. */
inode_for_each_dentry(dentry, inode) {
- for (unsigned i = 0; i <= dentry->inode->num_ads; i++) {
+ for (unsigned i = 0; i <= dentry->d_inode->num_ads; i++) {
const u8 *hash;
- hash = inode_stream_hash(dentry->inode, i);
+ hash = inode_stream_hash(dentry->d_inode, i);
if (!is_zero_hash(hash)) {
list_add(&dentry->tmp_list,
&dentries_with_data_streams);
* consistent with this dentry, add a new one (if that happens,
* we have split the hard link group). */
hlist_for_each_entry(inode, cur, &true_inodes, hlist) {
- if (ref_inodes_consistent(inode, dentry->inode)) {
+ if (ref_inodes_consistent(inode, dentry->d_inode)) {
inode_add_dentry(dentry, inode);
goto next_dentry_2;
}
}
num_true_inodes++;
- INIT_LIST_HEAD(&dentry->inode->dentry_list);
- inode_add_dentry(dentry, dentry->inode);
- hlist_add_head(&dentry->inode->hlist, &true_inodes);
+ INIT_LIST_HEAD(&dentry->d_inode->dentry_list);
+ inode_add_dentry(dentry, dentry->d_inode);
+ hlist_add_head(&dentry->d_inode->hlist, &true_inodes);
next_dentry_2:
;
}
if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
unlink(lte->staging_file_name);
wimlib_assert(lte->staging_list.next);
+ wimlib_assert(lte->staging_list.prev);
list_del(<e->staging_list);
}
#endif
struct lookup_table_entry *
lte_decrement_refcnt(struct lookup_table_entry *lte, struct lookup_table *table)
{
- if (lte) {
- wimlib_assert(lte->refcnt);
- if (--lte->refcnt == 0) {
- lookup_table_unlink(table, lte);
- #ifdef WITH_FUSE
- if (lte->num_opened_fds == 0)
- #endif
- {
- finalize_lte(lte);
- lte = NULL;
- }
+ wimlib_assert(lte);
+ wimlib_assert(lte->refcnt);
+ if (--lte->refcnt == 0) {
+ lookup_table_unlink(table, lte);
+ #ifdef WITH_FUSE
+ if (lte->num_opened_fds == 0)
+ #endif
+ {
+ finalize_lte(lte);
+ lte = NULL;
}
}
return lte;
struct lookup_table_entry *lte;
struct hlist_node *pos;
+ wimlib_assert(table);
+
i = *(size_t*)hash % table->capacity;
hlist_for_each_entry(lte, pos, &table->array[i], hash_list)
if (hashes_equal(hash, lte->hash))
if (!dentry)
return -ENOENT;
- inode = dentry->inode;
+ inode = dentry->d_inode;
wimlib_assert(inode->resolved);
*/
int dentry_resolve_ltes(struct dentry *dentry, void *table)
{
- if (!dentry->inode->resolved)
- inode_resolve_ltes(dentry->inode, table);
+ if (!dentry->d_inode->resolved)
+ inode_resolve_ltes(dentry->d_inode, table);
return 0;
}
/* Pointer to inode that contains the opened file descriptors to
* this stream (valid iff resource_location ==
* RESOURCE_IN_STAGING_FILE) */
- struct inode *inode;
+ struct inode *lte_inode;
};
#ifdef WITH_FUSE
u16 num_opened_fds;
if (!root)
return WIMLIB_ERR_NOMEM;
- stbuf_to_inode(&root_stbuf, root->inode);
+ stbuf_to_inode(&root_stbuf, root->d_inode);
add_flags &= ~WIMLIB_ADD_IMAGE_FLAG_ROOT;
- root->inode->resolved = true;
+ root->d_inode->resolved = true;
if (dentry_is_directory(root)) {
/* Open the directory on disk */
}
deref_name_buf[deref_name_len] = '\0';
DEBUG("Read symlink `%s'", deref_name_buf);
- ret = inode_set_symlink(root->inode, deref_name_buf,
+ ret = inode_set_symlink(root->d_inode, deref_name_buf,
lookup_table, NULL);
} else {
/* Regular file */
copy_hash(lte->hash, hash);
lookup_table_insert(lookup_table, lte);
}
- root->inode->lte = lte;
+ root->d_inode->lte = lte;
}
out:
*root_ret = root;
src_wim = ((struct wim_pair*)arg)->src_wim;
dest_wim = ((struct wim_pair*)arg)->dest_wim;
- inode = dentry->inode;
+ inode = dentry->d_inode;
wimlib_assert(!inode->resolved);
/* File descriptor to a file open on the WIM filesystem. */
struct wimlib_fd {
- struct inode *inode;
+ struct inode *f_inode;
struct lookup_table_entry *lte;
int staging_fd;
u16 idx;
return open_flags & (O_RDWR | O_WRONLY);
}
+/*
+ * Allocate a file descriptor for a stream.
+ *
+ * @inode: inode containing the stream we're opening
+ * @stream_id: ID of the stream we're opening
+ * @lte: Lookup table entry for the stream (may be NULL)
+ * @fd_ret: Return the allocated file descriptor if successful.
+ *
+ * Return 0 iff successful or error code if unsuccessful.
+ */
static int alloc_wimlib_fd(struct inode *inode,
u32 stream_id,
struct lookup_table_entry *lte,
if (inode->num_allocated_fds == max_fds)
return -EMFILE;
- num_new_fds = min(fds_per_alloc, max_fds - inode->num_allocated_fds);
+ num_new_fds = min(fds_per_alloc,
+ max_fds - inode->num_allocated_fds);
- fds = REALLOC(inode->fds, (inode->num_allocated_fds + num_new_fds) *
- sizeof(inode->fds[0]));
+ fds = REALLOC(inode->fds,
+ (inode->num_allocated_fds + num_new_fds) *
+ sizeof(inode->fds[0]));
if (!fds)
return -ENOMEM;
memset(&fds[inode->num_allocated_fds], 0,
struct wimlib_fd *fd = CALLOC(1, sizeof(*fd));
if (!fd)
return -ENOMEM;
- fd->inode = inode;
+ fd->f_inode = inode;
fd->lte = lte;
fd->staging_fd = -1;
fd->idx = i;
{
wimlib_assert(fd);
wimlib_assert(inode);
- wimlib_assert(fd->inode == inode);
+ wimlib_assert(fd->f_inode == inode);
wimlib_assert(inode->num_opened_fds);
wimlib_assert(fd->idx < inode->num_opened_fds);
wimlib_assert(inode->fds[fd->idx] == fd);
if (!lte) /* Empty stream with no lookup table entry */
return 0;
+ /* Close staging file descriptor if needed. */
wimlib_assert(lte->num_opened_fds);
if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
return 0;
}
+/* Close a file descriptor. */
static int close_wimlib_fd(struct wimlib_fd *fd)
{
int ret;
+ wimlib_assert(fd);
DEBUG("Closing fd (inode = %lu, opened = %u, allocated = %u)",
- fd->inode->ino, fd->inode->num_opened_fds,
- fd->inode->num_allocated_fds);
+ fd->f_inode->ino, fd->f_inode->num_opened_fds,
+ fd->f_inode->num_allocated_fds);
ret = lte_put_fd(fd->lte, fd);
if (ret != 0)
return ret;
- inode_put_fd(fd->inode, fd);
+ inode_put_fd(fd->f_inode, fd);
return 0;
}
-/* Remove a dentry; i.e. remove a reference to the inode.
+/* Remove a dentry; i.e. remove a reference to the corresponding inode.
*
- * If there are no remaining references to the inode either through detnries or
- * open file descriptors, the inode is freed.
+ * If there are no remaining references to the inode either through dentries or
+ * open file descriptors, the inode is freed. Otherwise, the inode is not
+ * removed, but the dentry is unlinked and freed.
*
- * All lookup table entries referenced by the inode have their reference count
- * decremented. If a lookup table entry has no open file descriptors and no
- * references remaining, it is freed, and the staging file is unlinked.
- *
- * Otherwise, the inode is not removed, but the dentry is unlinked and freed. */
+ * Either way, all lookup table entries referenced by the inode have their
+ * reference count decremented. If a lookup table entry has no open file
+ * descriptors and no references remaining, it is freed, and the staging file is
+ * unlinked.
+ */
static void remove_dentry(struct dentry *dentry,
struct lookup_table *lookup_table)
{
- struct inode *inode = dentry->inode;
+ struct inode *inode = dentry->d_inode;
struct lookup_table_entry *lte;
unsigned i;
new_lte->refcnt = inode->link_count;
new_lte->staging_file_name = staging_file_name;
new_lte->resource_location = RESOURCE_IN_STAGING_FILE;
- new_lte->inode = inode;
+ new_lte->lte_inode = inode;
random_hash(new_lte->hash);
if (stream_id == 0)
copy_hash(lte->hash, hash);
lte->resource_entry.original_size = stbuf.st_size;
lte->resource_entry.size = stbuf.st_size;
- lte->inode = NULL;
+ lte->lte_inode = NULL;
lookup_table_insert(table, lte);
}
for (u16 i = 0, j = 0; j < inode->num_opened_fds; i++) {
struct wimlib_fd *fd = inode->fds[i];
if (fd) {
- wimlib_assert(fd->inode == inode);
+ wimlib_assert(fd->f_inode == inode);
int ret = close_wimlib_fd(fd);
if (ret != 0)
return ret;
/*static int dentry_close_fds(struct dentry *dentry, void *ignore)*/
/*{*/
- /*return inode_close_fds(dentry->inode);*/
+ /*return inode_close_fds(dentry->d_inode);*/
/*}*/
/* Overwrites the WIM file, with changes saved. */
DEBUG("Closing all staging file descriptors.");
list_for_each_entry(lte, &staging_list, staging_list) {
- ret = inode_close_fds(lte->inode);
+ ret = inode_close_fds(lte->lte_inode);
if (ret != 0)
return ret;
}
struct fuse_file_info *fi)
{
struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh;
- return inode_to_stbuf(fd->inode, fd->lte, stbuf);
+ return inode_to_stbuf(fd->f_inode, fd->lte, stbuf);
}
static int wimfs_ftruncate(const char *path, off_t size,
&dentry, <e, NULL);
if (ret != 0)
return ret;
- return inode_to_stbuf(dentry->inode, lte, stbuf);
+ return inode_to_stbuf(dentry->d_inode, lte, stbuf);
}
#ifdef ENABLE_XATTR
dentry = get_dentry(w, path);
if (!dentry)
return -ENOENT;
- ads_entry = inode_get_ads_entry(dentry->inode, name, NULL);
+ ads_entry = inode_get_ads_entry(dentry->d_inode, name, NULL);
if (!ads_entry)
return -ENOATTR;
/* Create a hard link */
static int wimfs_link(const char *to, const char *from)
{
- struct dentry *to_dentry, *from_dentry, *from_dentry_parent;
+ struct dentry *from_dentry, *from_dentry_parent;
const char *link_name;
struct inode *inode;
- unsigned i;
struct lookup_table_entry *lte;
- to_dentry = get_dentry(w, to);
- if (!to_dentry)
+ inode = wim_pathname_to_inode(w, to);
+ if (!inode)
return -ENOENT;
- inode = to_dentry->inode;
-
if (!inode_is_regular_file(inode))
return -EPERM;
inode_add_dentry(from_dentry, inode);
- from_dentry->inode = inode;
+ from_dentry->d_inode = inode;
inode->link_count++;
- for (i = 0; i <= inode->num_ads; i++) {
+ for (unsigned i = 0; i <= inode->num_ads; i++) {
lte = inode_stream_lte_resolved(inode, i);
if (lte)
lte->refcnt++;
ret = lookup_resource(w, path, get_lookup_flags(), &dentry, NULL, NULL);
if (ret != 0)
return ret;
- inode = dentry->inode;
+ inode = dentry->d_inode;
if (size == 0) {
needed_size = 0;
return -EEXIST;
newdir = new_dentry_with_inode(basename);
- newdir->inode->attributes |= FILE_ATTRIBUTE_DIRECTORY;
- newdir->inode->resolved = true;
- newdir->inode->ino = next_ino++;
+ newdir->d_inode->attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ newdir->d_inode->resolved = true;
+ newdir->d_inode->ino = next_ino++;
link_dentry(newdir, parent);
return 0;
}
dentry = get_dentry(w, path);
if (!dentry || !dentry_is_regular_file(dentry))
return -ENOENT;
- if (inode_get_ads_entry(dentry->inode, stream_name, NULL))
+ if (inode_get_ads_entry(dentry->d_inode, stream_name, NULL))
return -EEXIST;
- new_entry = inode_add_ads(dentry->inode, stream_name);
+ new_entry = inode_add_ads(dentry->d_inode, stream_name);
if (!new_entry)
return -ENOENT;
} else {
dentry = new_dentry_with_inode(basename);
if (!dentry)
return -ENOMEM;
- dentry->inode->resolved = true;
- dentry->inode->ino = next_ino++;
+ dentry->d_inode->resolved = true;
+ dentry->d_inode->ino = next_ino++;
link_dentry(dentry, parent);
}
return 0;
if (ret != 0)
return ret;
- inode = dentry->inode;
+ inode = dentry->d_inode;
if (stream_idx == 0)
stream_id = 0;
* we can read the file resource directly from the WIM file if we are
* opening it read-only, but we need to extract the resource to the
* staging directory if we are opening it writable. */
+
if (flags_writable(fi->flags) &&
(!lte || lte->resource_location != RESOURCE_IN_STAGING_FILE)) {
u64 size = (lte) ? wim_resource_size(lte) : 0;
if (!fd)
return -EBADF;
- inode = fd->inode;
+ inode = fd->f_inode;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
if (!dentry_is_symlink(dentry))
return -EINVAL;
- ret = inode_readlink(dentry->inode, buf, buf_len, w);
+ ret = inode_readlink(dentry->d_inode, buf, buf_len, w);
if (ret > 0)
ret = 0;
return ret;
static int wimfs_release(const char *path, struct fuse_file_info *fi)
{
struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh;
- wimlib_assert(fd);
return close_wimlib_fd(fd);
}
+/* Close a directory */
static int wimfs_releasedir(const char *path, struct fuse_file_info *fi)
{
struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh;
- wimlib_assert(fd);
return close_wimlib_fd(fd);
}
if (!dentry)
return -ENOENT;
- ads_entry = inode_get_ads_entry(dentry->inode, name, &ads_idx);
+ ads_entry = inode_get_ads_entry(dentry->d_inode, name, &ads_idx);
if (!ads_entry)
return -ENOATTR;
- inode_remove_ads(dentry->inode, ads_idx, w->lookup_table);
+ inode_remove_ads(dentry->d_inode, ads_idx, w->lookup_table);
return 0;
}
#endif
* directory */
if (!dentry_is_directory(dst))
return -ENOTDIR;
- if (dst->inode->children != NULL)
+ if (dst->d_inode->children != NULL)
return -ENOTEMPTY;
}
parent_of_dst = dst->parent;
dentry = new_dentry_with_inode(link_name);
if (!dentry)
return -ENOMEM;
- inode = dentry->inode;
+ inode = dentry->d_inode;
inode->attributes = FILE_ATTRIBUTE_REPARSE_POINT;
inode->reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK;
if (!lte) /* Already a zero-length file */
return 0;
- inode = dentry->inode;
+ inode = dentry->d_inode;
if (stream_idx == 0)
stream_id = 0;
if (stream_idx == 0)
remove_dentry(dentry, w->lookup_table);
else
- inode_remove_ads(dentry->inode, stream_idx - 1, w->lookup_table);
+ inode_remove_ads(dentry->d_inode, stream_idx - 1, w->lookup_table);
return 0;
}
dentry = get_dentry(w, path);
if (!dentry)
return -ENOENT;
- inode = dentry->inode;
+ inode = dentry->d_inode;
if (tv[0].tv_nsec != UTIME_OMIT) {
if (tv[0].tv_nsec == UTIME_NOW)
dentry = get_dentry(w, path);
if (!dentry)
return -ENOENT;
- inode = dentry->inode;
+ inode = dentry->d_inode;
inode->last_write_time = unix_timestamp_to_wim(times->modtime);
inode->last_access_time = unix_timestamp_to_wim(times->actime);
wimlib_assert(fd->lte);
wimlib_assert(fd->lte->staging_file_name);
wimlib_assert(fd->staging_fd != -1);
- wimlib_assert(fd->inode);
+ wimlib_assert(fd->f_inode);
/* Seek to the requested position */
if (lseek(fd->staging_fd, offset, SEEK_SET) == -1)
return -errno;
now = get_wim_timestamp();
- fd->inode->last_write_time = now;
- fd->inode->last_access_time = now;
+ fd->f_inode->last_write_time = now;
+ fd->f_inode->last_access_time = now;
return ret;
}
unsigned stream_idx = 0;
ntfschar *stream_name = AT_UNNAMED;
u32 stream_name_len = 0;
- const struct inode *inode = dentry->inode;
+ const struct inode *inode = dentry->d_inode;
DEBUG("Writing %u NTFS data stream%s for `%s'",
inode->num_ads + 1,
const WIMStruct *w)
{
DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32,
- dentry->full_path_utf8, dentry->inode->attributes);
+ dentry->full_path_utf8, dentry->d_inode->attributes);
int ret;
struct SECURITY_CONTEXT ctx;
u32 attributes_le32;
- attributes_le32 = cpu_to_le32(dentry->inode->attributes);
+ attributes_le32 = cpu_to_le32(dentry->d_inode->attributes);
memset(&ctx, 0, sizeof(ctx));
ctx.vol = ni->vol;
ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ATTRIB,
dentry->full_path_utf8);
return WIMLIB_ERR_NTFS_3G;
}
- if (dentry->inode->security_id != -1) {
+ if (dentry->d_inode->security_id != -1) {
const struct wim_security_data *sd;
const char *descriptor;
sd = wim_const_security_data(w);
- wimlib_assert(dentry->inode->security_id < sd->num_entries);
- descriptor = sd->descriptors[dentry->inode->security_id];
+ wimlib_assert(dentry->d_inode->security_id < sd->num_entries);
+ descriptor = sd->descriptors[dentry->d_inode->security_id];
DEBUG("Applying security descriptor %d to `%s'",
- dentry->inode->security_id, dentry->full_path_utf8);
+ dentry->d_inode->security_id, dentry->full_path_utf8);
ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL,
ni, dir_ni, descriptor,
- sd->sizes[dentry->inode->security_id], 0);
+ sd->sizes[dentry->d_inode->security_id], 0);
if (ret != 0) {
ERROR_WITH_ERRNO("Failed to set security data on `%s'",
struct lookup_table_entry *lte;
int ret = 0;
- wimlib_assert(dentry->inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT);
+ wimlib_assert(dentry->d_inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT);
- lte = inode_unnamed_lte(dentry->inode, w->lookup_table);
+ lte = inode_unnamed_lte(dentry->d_inode, w->lookup_table);
DEBUG("Applying reparse data to `%s'", dentry->full_path_utf8);
u8 reparse_data_buf[8 + wim_resource_size(lte)];
u8 *p = reparse_data_buf;
- p = put_u32(p, dentry->inode->reparse_tag); /* ReparseTag */
+ p = put_u32(p, dentry->d_inode->reparse_tag); /* ReparseTag */
p = put_u16(p, wim_resource_size(lte)); /* ReparseDataLength */
p = put_u16(p, 0); /* Reserved */
struct dentry *dentry_with_dos_name;
dentry_with_dos_name = NULL;
- inode_for_each_dentry(other, dentry->inode) {
+ inode_for_each_dentry(other, dentry->d_inode) {
if (other != dentry && (dentry->parent == other->parent)
&& other->short_name_len)
{
ntfs_inode *ni = NULL;
bool is_hardlink = false;
ntfs_volume *vol = dir_ni->vol;
- struct inode *inode = dentry->inode;
+ struct inode *inode = dentry->d_inode;
dentry->is_extracted = true;
if (inode->attributes & FILE_ATTRIBUTE_DIRECTORY) {
}
p = buf;
- p = put_u64(p, dentry->inode->creation_time);
- p = put_u64(p, dentry->inode->last_write_time);
- p = put_u64(p, dentry->inode->last_access_time);
+ p = put_u64(p, dentry->d_inode->creation_time);
+ p = put_u64(p, dentry->d_inode->last_write_time);
+ p = put_u64(p, dentry->d_inode->last_access_time);
ret = ntfs_inode_set_times(ni, (const char*)buf, 3 * sizeof(u64), 0);
if (ret != 0) {
ERROR_WITH_ERRNO("Failed to set NTFS timestamps on `%s'",
lte->ntfs_loc = ntfs_loc;
lte->resource_location = RESOURCE_IN_NTFS_VOLUME;
if (type == AT_REPARSE_POINT) {
- dentry->inode->reparse_tag = reparse_tag;
+ dentry->d_inode->reparse_tag = reparse_tag;
ntfs_loc->is_reparse_point = true;
lte->resource_entry.original_size = data_size - 8;
lte->resource_entry.size = data_size - 8;
if (name_length == 0) {
/* Unnamed data stream. Put the reference to it in the
* dentry's inode. */
- if (dentry->inode->lte) {
+ if (dentry->d_inode->lte) {
ERROR("Found two un-named data streams for "
"`%s'", path);
ret = WIMLIB_ERR_NTFS_3G;
goto out_free_lte;
}
- dentry->inode->lte = lte;
+ dentry->d_inode->lte = lte;
} else {
/* Named data stream. Put the reference to it in the
* alternate data stream entries */
&stream_name_utf8_len);
if (!stream_name_utf8)
goto out_free_lte;
- new_ads_entry = inode_add_ads(dentry->inode, stream_name_utf8);
+ new_ads_entry = inode_add_ads(dentry->d_inode, stream_name_utf8);
FREE(stream_name_utf8);
if (!new_ads_entry)
goto out_free_lte;
}
}
- root->inode->creation_time = le64_to_cpu(ni->creation_time);
- root->inode->last_write_time = le64_to_cpu(ni->last_data_change_time);
- root->inode->last_access_time = le64_to_cpu(ni->last_access_time);
- root->inode->attributes = le32_to_cpu(attributes);
- root->inode->ino = ni->mft_no;
- root->inode->resolved = true;
+ root->d_inode->creation_time = le64_to_cpu(ni->creation_time);
+ root->d_inode->last_write_time = le64_to_cpu(ni->last_data_change_time);
+ root->d_inode->last_access_time = le64_to_cpu(ni->last_access_time);
+ root->d_inode->attributes = le32_to_cpu(attributes);
+ root->d_inode->ino = ni->mft_no;
+ root->d_inode->resolved = true;
if (attributes & FILE_ATTR_REPARSE_POINT) {
/* Junction point, symbolic link, or other reparse point */
ni, dir_ni, sd, ret);
}
if (ret > 0) {
- root->inode->security_id = sd_set_add_sd(sd_set, sd, ret);
- if (root->inode->security_id == -1) {
+ root->d_inode->security_id = sd_set_add_sd(sd_set, sd, ret);
+ if (root->d_inode->security_id == -1) {
ERROR("Out of memory");
return WIMLIB_ERR_NOMEM;
}
DEBUG("Added security ID = %u for `%s'",
- root->inode->security_id, path);
+ root->d_inode->security_id, path);
ret = 0;
} else if (ret < 0) {
ERROR_WITH_ERRNO("Failed to get security information from "
"`%s'", path);
ret = WIMLIB_ERR_NTFS_3G;
} else {
- root->inode->security_id = -1;
+ root->d_inode->security_id = -1;
DEBUG("No security ID for `%s'", path);
}
return ret;
printf("Writing streams for `%s'\n", dentry->full_path_utf8);
}
- for (unsigned i = 0; i <= dentry->inode->num_ads; i++) {
- lte = inode_stream_lte(dentry->inode, i, w->lookup_table);
+ for (unsigned i = 0; i <= dentry->d_inode->num_ads; i++) {
+ lte = inode_stream_lte(dentry->d_inode, i, w->lookup_table);
if (lte && ++lte->out_refcnt == 1) {
ret = write_wim_resource(lte, w->out_fp, ctype,
<e->output_resource_entry);
dentry->prev = dentry;
if (ret != 0)
goto out_free_dentry_tree;
- inode_add_dentry(dentry, dentry->inode);
+ inode_add_dentry(dentry, dentry->d_inode);
/* Now read the entire directory entry tree into memory. */
DEBUG("Reading dentry tree");
DEBUG("Done reading image metadata");
- imd->root_dentry = dentry;
- imd->inode_list = inode_list;
+ imd->root_dentry = dentry;
+ imd->inode_list = inode_list;
goto out_free_buf;
out_free_dentry_tree:
free_dentry_tree(dentry, NULL);