X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=include%2Fwimlib%2Finode.h;h=733d3847f8082fc12e0a204c443ecc46f8d50247;hb=9a20d1f99bd5dcd22e55300a5e29748486e585d7;hp=c869f8417561500ad2227458110375be65636de2;hpb=00ae9e9cf11e1f7a108b63db0fc538180a81880a;p=wimlib diff --git a/include/wimlib/inode.h b/include/wimlib/inode.h index c869f841..733d3847 100644 --- a/include/wimlib/inode.h +++ b/include/wimlib/inode.h @@ -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 @@ -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,17 +98,26 @@ 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; + /* Cached value */ + u8 i_can_externally_back : 1; + /* Pointer to a malloc()ed array of i_num_ads alternate data stream * 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 @@ -116,9 +128,10 @@ struct wim_inode { /* Corresponds to 'security_id' in `struct wim_dentry_on_disk': The * index of this inode's security descriptor in the WIM image's table of - * security descriptors, or -1. Note: in verify_inode(), called - * whenever a WIM image is loaded, out-of-bounds indices are set to -1, - * so the extraction code does not need to do bounds checks. */ + * security descriptors, or -1. Note: when a WIM image is loaded, + * wimlib sets out-of-bounds indices and values less than -1 in this + * field to -1. So the extraction code need not do an upper bound check + * after checking for -1 (or equivalently < 0). */ int32_t i_security_id; /* Identity of a reparse point. See @@ -149,26 +162,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_remaining_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 +262,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 +333,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 +343,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 +356,19 @@ 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); -} - +/* + * Does the specified alternate data stream entry correspond to a named stream? + * + * See inode_needs_dummy_stream() for explanation of why an alternate data + * stream entry might, in fact, not be named... + */ 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 +407,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 !rb_empty_root(&inode->i_children); + return inode->i_children != NULL; } extern int @@ -478,6 +503,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,14 +530,18 @@ 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); +extern void +check_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);