]> wimlib.net Git - wimlib/blobdiff - include/wimlib/inode.h
Add experimental support for WIMLIB_PROGRESS_MSG_DONE_WITH_FILE
[wimlib] / include / wimlib / inode.h
index 5d04427fd605d3ebd80ee1db198992769221924b..3b0222990bf77a8476766b1fda097990e5a4740d 100644 (file)
@@ -4,9 +4,7 @@
 #include "wimlib/assert.h"
 #include "wimlib/list.h"
 #include "wimlib/lookup_table.h"
-#include "wimlib/rbtree.h"
 #include "wimlib/sha1.h"
-#include "wimlib/unix_data.h"
 
 #include <string.h>
 
@@ -15,11 +13,12 @@ struct wim_dentry;
 struct wim_security_data;
 struct wim_lookup_table;
 struct wimfs_fd;
+struct avl_tree_node;
 
 /*
  * WIM inode.
  *
- * As mentioned in the comment above `struct wim_dentry', in the WIM file that
+ * As mentioned in the comment above `struct wim_dentry', in WIM files there
  * is no on-disk analogue of a real inode, as most of these fields are
  * duplicated in the dentries.  Instead, a `struct wim_inode' is something we
  * create ourselves to simplify the handling of hard links.
@@ -47,13 +46,17 @@ struct wim_inode {
         * this inode. */
        u32 i_attributes;
 
-       /* Root of a red-black tree storing the child dentries of this inode, if
-        * any.  Keyed by wim_dentry->file_name, case sensitively. */
-       struct rb_root i_children;
+       /* Root of a balanced binary search tree storing the child directory
+        * entries of this inode, if any.  Keyed by wim_dentry->file_name, case
+        * sensitively.  If this inode is not a directory or if it has no
+        * children then this will be an empty tree (NULL).  */
+       struct avl_tree_node *i_children;
 
-       /* Root of a red-black tree storing the children of this inode, if any.
-        * Keyed by wim_dentry->file_name, case insensitively. */
-       struct rb_root i_children_case_insensitive;
+       /* Root of a balanced binary search tree storing the child directory
+        * entries of this inode, if any.  Keyed by wim_dentry->file_name, case
+        * insensitively.  If this inode is not a directory or if it has no
+        * children then this will be an empty tree (NULL).  */
+       struct avl_tree_node *i_children_ci;
 
        /* List of dentries that are aliases for this inode.  There will be
         * i_nlink dentries in this list.  */
@@ -95,9 +98,6 @@ struct wim_inode {
         * error paths.  */
        u8 i_visited : 1;
 
-       /* Set if the DOS name of an inode has already been extracted.  */
-       u8 i_dos_name_extracted : 1;
-
        /* 1 iff all ADS entries of this inode are named or if this inode
         * has no ADS entries  */
        u8 i_canonical_streams : 1;
@@ -106,6 +106,15 @@ struct wim_inode {
         * entries for this inode.  */
        struct wim_ads_entry *i_ads_entries;
 
+       /* If not NULL, a pointer to the extra data that was read from the
+        * dentry.  This should be a series of tagged items, each of which
+        * represents a bit of extra metadata, such as the file's object ID.
+        * See tagged_items.c for more information.  */
+       void *i_extra;
+
+       /* Size of @i_extra buffer in bytes.  If 0, there is no extra data.  */
+       size_t i_extra_size;
+
        /* Creation time, last access time, and last write time for this inode, in
         * 100-nanosecond intervals since 12:00 a.m UTC January 1, 1601.  They
         * should correspond to the times gotten by calling GetFileTime() on
@@ -149,26 +158,42 @@ struct wim_inode {
                 * to 0 otherwise.  */
                u64 i_devno;
 
+               /* Fields used only during extraction  */
                struct {
-
-                       /* Used only during image extraction: pointer to the first path
-                        * (malloc()ed buffer) at which this inode has been extracted.
-                        * Freed and set to NULL after the extraction is done (either
-                        * success or failure).  */
-                       tchar *i_extracted_file;
-
-                       /** Used only during image extraction: "cookie" that
-                        * identifies this extracted file (inode), for example
-                        * an inode number.  Only used if supported by the
-                        * extraction mode.  */
-                       u64 extract_cookie;
+                       /* List of aliases of this dentry that are being
+                        * extracted in the current extraction operation.  This
+                        * will be a (possibly nonproper) subset of the dentries
+                        * in the i_dentry list.  This list will be constructed
+                        * regardless of whether the extraction backend supports
+                        * hard links or not.  */
+                       struct list_head i_extraction_aliases;
+
+               #ifdef WITH_NTFS_3G
+                       /* In NTFS-3g extraction mode, this is set to the Master
+                        * File Table (MFT) number of the NTFS file that was
+                        * created for this inode.  */
+                       u64 i_mft_no;
+               #endif
                };
 
+               /* Used during WIM writing with
+                * WIMLIB_WRITE_FLAG_SEND_DONE_WITH_FILE_MESSAGES:  the number
+                * of data streams this inode has that have not yet been fully
+                * read.  */
+               u32 num_unread_streams;
+
 #ifdef WITH_FUSE
-               /* Used only during image mount:  Table of file descriptors that
-                * have been opened to this inode.  The table is automatically
-                * freed when the last file descriptor is closed.  */
-               struct wimfs_fd **i_fds;
+               struct {
+                       /* Used only during image mount:  Table of file
+                        * descriptors that have been opened to this inode.
+                        * This table is freed when the last file descriptor is
+                        * closed.  */
+                       struct wimfs_fd **i_fds;
+
+                       /* Lower bound on the index of the next available entry
+                        * in 'i_fds'.  */
+                       u16 i_next_fd;
+               };
 #endif
        };
 
@@ -233,7 +258,7 @@ struct wim_ads_entry_on_disk {
        le16 stream_name_nbytes;
 
        /* Stream name in UTF-16LE.  It is @stream_name_nbytes bytes long,
-        * excluding the the null terminator.  There is a null terminator
+        * excluding the null terminator.  There is a null terminator
         * character if @stream_name_nbytes != 0; i.e., if this stream is named.
         * */
        utf16lechar stream_name[];
@@ -304,8 +329,7 @@ free_inode(struct wim_inode *inode);
                dentry_full_path(inode_first_dentry(inode))
 
 extern struct wim_ads_entry *
-inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name,
-                   u16 *idx_ret);
+inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name);
 
 extern struct wim_ads_entry *
 inode_add_ads_utf16le(struct wim_inode *inode,
@@ -315,7 +339,7 @@ inode_add_ads_utf16le(struct wim_inode *inode,
 extern struct wim_ads_entry *
 inode_add_ads(struct wim_inode *dentry, const tchar *stream_name);
 
-extern int
+extern struct wim_ads_entry *
 inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
                        const void *value, size_t size,
                        struct wim_lookup_table *lookup_table);
@@ -328,22 +352,13 @@ inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
                         struct wim_lookup_table *lookup_table);
 
 extern void
-inode_remove_ads(struct wim_inode *inode, u16 idx,
+inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry,
                 struct wim_lookup_table *lookup_table);
 
-static inline bool
-ads_entry_is_unix_data(const struct wim_ads_entry *entry)
-{
-       return (entry->stream_name_nbytes ==
-                       WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES) &&
-               !memcmp(entry->stream_name, WIMLIB_UNIX_DATA_TAG_UTF16LE,
-                       WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES);
-}
-
 static inline bool
 ads_entry_is_named_stream(const struct wim_ads_entry *entry)
 {
-       return entry->stream_name_nbytes != 0 && !ads_entry_is_unix_data(entry);
+       return entry->stream_name_nbytes != 0;
 }
 
 /* Is the inode a directory?
@@ -382,12 +397,12 @@ inode_is_symlink(const struct wim_inode *inode)
 
 /* Does the inode have children?
  * Currently (based on read_dentry_tree()), this can only return true for inodes
- * for which inode_is_directory() returns true.  However, if a directory is
- * empty, this returns false.  */
+ * for which inode_is_directory() returns true.  (This also returns false on
+ * empty directories.)  */
 static inline bool
 inode_has_children(const struct wim_inode *inode)
 {
-       return inode->i_children.rb_node != NULL;
+       return inode->i_children != NULL;
 }
 
 extern int
@@ -478,6 +493,15 @@ inode_stream_name_nbytes(const struct wim_inode *inode, unsigned stream_idx)
                return inode->i_ads_entries[stream_idx - 1].stream_name_nbytes;
 }
 
+static inline u32
+inode_stream_idx_to_id(const struct wim_inode *inode, unsigned stream_idx)
+{
+       if (stream_idx == 0)
+               return 0;
+       else
+               return inode->i_ads_entries[stream_idx - 1].stream_id;
+}
+
 extern struct wim_lookup_table_entry *
 inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret);
 
@@ -496,7 +520,7 @@ inode_unnamed_stream_hash(const struct wim_inode *inode);
 
 extern int
 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
-                size_t nbytes_remaining);
+                size_t *nbytes_remaining_p);
 
 extern int
 verify_inode(struct wim_inode *inode, const struct wim_security_data *sd);
@@ -504,6 +528,10 @@ verify_inode(struct wim_inode *inode, const struct wim_security_data *sd);
 extern void
 inode_ref_streams(struct wim_inode *inode);
 
+extern void
+inode_unref_streams(struct wim_inode *inode,
+                   struct wim_lookup_table *lookup_table);
+
 /* inode_fixup.c  */
 extern int
 dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list);