From 50670821723291959a6f35442c523800d369c934 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 3 Sep 2012 22:13:47 -0500 Subject: [PATCH] ads entries --- src/dentry.c | 195 +++++++++++++++++++++----------------- src/dentry.h | 226 +++++++++++++++++++++++---------------------- src/hardlink.c | 8 +- src/lookup_table.c | 5 +- src/lookup_table.h | 8 +- src/mount.c | 84 ++--------------- src/ntfs-apply.c | 18 +--- src/ntfs-capture.c | 47 ---------- 8 files changed, 250 insertions(+), 341 deletions(-) diff --git a/src/dentry.c b/src/dentry.c index 23597110..58782eb8 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -79,7 +79,7 @@ static u64 __dentry_total_length(const struct dentry *dentry, u64 length) { const struct inode *inode = dentry->inode; for (u16 i = 0; i < inode->num_ads; i++) - length += ads_entry_total_length(inode->ads_entries[i]); + length += ads_entry_total_length(&inode->ads_entries[i]); return (length + 7) & ~7; } @@ -118,16 +118,53 @@ void stbuf_to_inode(const struct stat *stbuf, struct inode *inode) inode->last_access_time = timespec_to_wim_timestamp(&stbuf->st_atim); } - -/* Sets all the timestamp fields of the dentry to the current time. */ -void inode_update_all_timestamps(struct inode *inode) +#ifdef WITH_FUSE +/* Transfers file attributes from a struct inode to a `stat' buffer. + * + * The lookup table entry tells us which stream in the inode we are statting. + * For a named data stream, everything returned is the same as the unnamed data + * stream except possibly the size and block count. */ +int inode_to_stbuf(const struct inode *inode, struct lookup_table_entry *lte, + struct stat *stbuf) { - u64 now = get_wim_timestamp(); - inode->creation_time = now; - inode->last_access_time = now; - inode->last_write_time = now; + if (inode_is_symlink(inode)) + stbuf->st_mode = S_IFLNK | 0777; + else if (inode_is_directory(inode)) + stbuf->st_mode = S_IFDIR | 0755; + else + stbuf->st_mode = S_IFREG | 0644; + + stbuf->st_ino = (ino_t)inode->ino; + stbuf->st_nlink = inode->link_count; + stbuf->st_uid = getuid(); + stbuf->st_gid = getgid(); + + if (lte) { + if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { + wimlib_assert(lte->staging_file_name); + struct stat native_stat; + if (stat(lte->staging_file_name, &native_stat) != 0) { + DEBUG("Failed to stat `%s': %m", + lte->staging_file_name); + return -errno; + } + stbuf->st_size = native_stat.st_size; + } else { + stbuf->st_size = wim_resource_size(lte); + } + } else { + stbuf->st_size = 0; + } + + stbuf->st_atime = wim_timestamp_to_unix(inode->last_access_time); + stbuf->st_mtime = wim_timestamp_to_unix(inode->last_write_time); + stbuf->st_ctime = wim_timestamp_to_unix(inode->creation_time); + stbuf->st_blocks = (stbuf->st_size + 511) / 512; + return 0; } +#endif +#ifdef WITH_FUSE /* Returns the alternate data stream entry belonging to @inode that has the * stream name @stream_name. */ struct ads_entry *inode_get_ads_entry(struct inode *inode, @@ -141,33 +178,46 @@ struct ads_entry *inode_get_ads_entry(struct inode *inode, u16 i = 0; stream_name_len = strlen(stream_name); do { - if (ads_entry_has_name(inode->ads_entries[i], + if (ads_entry_has_name(&inode->ads_entries[i], stream_name, stream_name_len)) { if (idx_ret) *idx_ret = i; - return inode->ads_entries[i]; + return &inode->ads_entries[i]; } } while (++i != inode->num_ads); } return NULL; } +#endif -static struct ads_entry *new_ads_entry(const char *name) +static int init_ads_entry(struct ads_entry *ads_entry, const char *name) { - struct ads_entry *ads_entry = CALLOC(1, sizeof(struct ads_entry)); - if (!ads_entry) - return NULL; - if (name && *name) { - if (change_ads_name(ads_entry, name)) { - FREE(ads_entry); - return NULL; - } + 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); } - return ads_entry; } +#if defined(WITH_FUSE) || defined(WITH_NTFS_3G) /* * Add an alternate stream entry to an inode and return a pointer to it, or NULL * if memory could not be allocated. @@ -175,7 +225,7 @@ static struct ads_entry *new_ads_entry(const char *name) struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name) { u16 num_ads; - struct ads_entry **ads_entries; + struct ads_entry *ads_entries; struct ads_entry *new_entry; if (inode->num_ads >= 0xfffe) { @@ -191,17 +241,43 @@ struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name) } inode->ads_entries = ads_entries; - new_entry = new_ads_entry(stream_name); - if (!new_entry) + new_entry = &inode->ads_entries[num_ads - 1]; + if (init_ads_entry(new_entry, stream_name) != 0) return NULL; - inode->num_ads = num_ads; - ads_entries[num_ads - 1] = new_entry; #ifdef WITH_FUSE new_entry->stream_id = inode->next_stream_id++; #endif return new_entry; } +#endif +#ifdef WITH_FUSE +/* Remove an alternate data stream from the inode */ +void inode_remove_ads(struct inode *inode, u16 idx, + struct lookup_table *lookup_table) +{ + struct ads_entry *ads_entry; + struct lookup_table_entry *lte; + + ads_entry = &inode->ads_entries[idx]; + + wimlib_assert(ads_entry); + wimlib_assert(inode->resolved); + + lte = ads_entry->lte; + + if (lte) + lte_decrement_refcnt(lte, lookup_table); + + destroy_ads_entry(ads_entry); + + wimlib_assert(inode->num_ads); + memcpy(&inode->ads_entries[idx], + &inode->ads_entries[idx + 1], + (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0])); + inode->num_ads--; +} +#endif /* * Calls a function on all directory entries in a directory tree. It is called @@ -525,9 +601,9 @@ int print_dentry(struct dentry *dentry, void *lookup_table) } for (u16 i = 0; i < inode->num_ads; i++) { printf("[Alternate Stream Entry %u]\n", i); - printf("Name = \"%s\"\n", inode->ads_entries[i]->stream_name_utf8); + printf("Name = \"%s\"\n", inode->ads_entries[i].stream_name_utf8); printf("Name Length (UTF-16) = %u\n", - inode->ads_entries[i]->stream_name_len); + inode->ads_entries[i].stream_name_len); hash = inode_stream_hash(inode, i + 1); if (hash) { printf("Hash = 0x"); @@ -630,23 +706,6 @@ struct dentry *new_dentry_with_inode(const char *name) return __new_dentry_with_inode(name, false); } -void free_ads_entry(struct ads_entry *entry) -{ - if (entry) { - FREE(entry->stream_name); - FREE(entry->stream_name_utf8); - FREE(entry); - } -} - -void inode_free_ads_entries(struct inode *inode) -{ - if (inode->ads_entries) { - for (u16 i = 0; i < inode->num_ads; i++) - free_ads_entry(inode->ads_entries[i]); - FREE(inode->ads_entries); - } -} /* Frees an inode. */ void free_inode(struct inode *inode) @@ -707,30 +766,6 @@ void put_dentry(struct dentry *dentry) free_dentry(dentry); } -#if 0 -/* Partically clones a dentry. - * - * Beware: - * - memory for file names is not cloned (the pointers are all set to NULL - * and the lengths are set to zero) - * - next, prev, and children pointers and not touched - */ -struct dentry *clone_dentry(struct dentry *old) -{ - struct dentry *new = MALLOC(sizeof(struct dentry)); - if (!new) - return NULL; - memcpy(new, old, sizeof(struct dentry)); - new->file_name = NULL; - new->file_name_len = 0; - new->file_name_utf8 = NULL; - new->file_name_utf8_len = 0; - new->short_name = NULL; - new->short_name_len = 0; - return new; -} -#endif - /* * This function is passed as an argument to for_dentry_in_tree_depth() in order * to free a directory tree. __args is a pointer to a `struct free_dentry_args'. @@ -978,7 +1013,7 @@ static int read_ads_entries(const u8 *p, struct inode *inode, u64 remaining_size) { u16 num_ads; - struct ads_entry **ads_entries; + struct ads_entry *ads_entries; int ret; num_ads = inode->num_ads; @@ -997,16 +1032,10 @@ static int read_ads_entries(const u8 *p, struct inode *inode, size_t utf8_len; const u8 *p_save = p; - cur_entry = new_ads_entry(NULL); - if (!cur_entry) { - ret = WIMLIB_ERR_NOMEM; - goto out_free_ads_entries; - } - - ads_entries[i] = cur_entry; + cur_entry = &ads_entries[i]; #ifdef WITH_FUSE - ads_entries[i]->stream_id = i + 1; + ads_entries[i].stream_id = i + 1; #endif /* Read the base stream entry, excluding the stream name. */ @@ -1099,7 +1128,7 @@ static int read_ads_entries(const u8 *p, struct inode *inode, return 0; out_free_ads_entries: for (u16 i = 0; i < num_ads; i++) - free_ads_entry(ads_entries[i]); + destroy_ads_entry(&ads_entries[i]); FREE(ads_entries); return ret; } @@ -1555,14 +1584,14 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p) * read_ads_entries() for comments about the format of the on-disk * alternate data stream entries. */ for (u16 i = 0; i < inode->num_ads; i++) { - p = put_u64(p, ads_entry_total_length(inode->ads_entries[i])); + p = put_u64(p, ads_entry_total_length(&inode->ads_entries[i])); p = put_u64(p, 0); /* Unused */ hash = inode_stream_hash(inode, i + 1); p = put_bytes(p, SHA1_HASH_SIZE, hash); - p = put_u16(p, inode->ads_entries[i]->stream_name_len); - if (inode->ads_entries[i]->stream_name_len) { - p = put_bytes(p, inode->ads_entries[i]->stream_name_len, - (u8*)inode->ads_entries[i]->stream_name); + p = put_u16(p, inode->ads_entries[i].stream_name_len); + if (inode->ads_entries[i].stream_name_len) { + p = put_bytes(p, inode->ads_entries[i].stream_name_len, + (u8*)inode->ads_entries[i].stream_name); p = put_u16(p, 0); } p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8); diff --git a/src/dentry.h b/src/dentry.h index f87353e9..d1027f76 100644 --- a/src/dentry.h +++ b/src/dentry.h @@ -7,10 +7,13 @@ #include "sha1.h" #include - struct stat; struct lookup_table; struct WIMStruct; +struct lookup_table_entry; +struct wimlib_fd; +struct inode; +struct dentry; /* Size of the struct dentry up to and including the file_name_len. */ #define WIM_DENTRY_DISK_SIZE 102 @@ -52,7 +55,6 @@ struct WIMStruct; #define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 #define FILE_ATTRIBUTE_VIRTUAL 0x00010000 -struct lookup_table_entry; /* Alternate data stream entry. * @@ -114,108 +116,32 @@ static inline bool ads_entries_have_same_name(const struct ads_entry *entry_1, entry_1->stream_name_len) == 0; } -struct wimlib_fd; - -struct inode { - /* Timestamps for the inode. The timestamps are the number of - * 100-nanosecond intervals that have elapsed since 12:00 A.M., January - * 1st, 1601, UTC. This is the same format used in NTFS inodes. */ - u64 creation_time; - u64 last_access_time; - u64 last_write_time; - - /* The file attributes associated with this inode. This is a bitwise OR - * of the FILE_ATTRIBUTE_* flags. */ - u32 attributes; - - /* The index of the security descriptor in the WIM image's table of - * security descriptors that contains this file's security information. - * If -1, no security information exists for this file. */ - int32_t security_id; - - /* %true iff the inode's lookup table entries has been resolved (i.e. - * the @lte field is valid, but the @hash field is not valid) - * - * (This is not an on-disk field.) */ - u8 resolved : 1; - - u8 verified : 1; - - u16 num_ads; - - /* A hash of the file's contents, or a pointer to the lookup table entry - * for this dentry if the lookup table entries have been resolved. - * - * More specifically, this is for the un-named default file stream, as - * opposed to the alternate (named) file streams, which may have their - * own lookup table entries. */ - union { - u8 hash[SHA1_HASH_SIZE]; - struct lookup_table_entry *lte; - }; - - /* Identity of a reparse point. See - * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx - * for what a reparse point is. */ - u32 reparse_tag; - - u32 link_count; - - struct ads_entry **ads_entries; - - /* If the file is part of a hard link set, all the directory entries in - * the set will share the same value for this field. - * - * Unfortunately, in some WIMs it is NOT the case that all dentries that - * share this field are actually in the same hard link set, although the - * WIMs that wimlib writes maintain this restriction. */ - u64 ino; - - struct list_head dentry_list; - struct hlist_node hlist; - char *extracted_file; - - struct dentry *children; - -#ifdef WITH_FUSE - u16 num_opened_fds; - u16 num_allocated_fds; - struct wimlib_fd **fds; - u32 next_stream_id; -#endif -}; - -#define inode_for_each_dentry(dentry, inode) \ - list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list) - -#define inode_add_dentry(dentry, inode) \ - ({ \ - wimlib_assert((inode)->dentry_list.next != NULL); \ - list_add(&(dentry)->inode_dentry_list, &(inode)->dentry_list); \ - }) - /* * In-memory structure for a WIM directory entry (dentry). There is a directory * tree for each image in the WIM. * - * Please note that this is a directory entry and not an inode. Since NTFS - * allows hard links, it's possible for a NTFS inode to correspond to multiple - * WIM dentries. The @hard_link field tells you the number of the NTFS inode - * that the dentry corresponds to. + * Note that this is a directory entry and not an inode. Since NTFS allows hard + * links, it's possible for a NTFS inode to correspond to multiple WIM dentries. + * The hard_link field on the on-disk WIM dentry tells us the number of the NTFS + * inode that the dentry corresponds to. * * Unfortunately, WIM files do not have an analogue to an inode; instead certain * information, such as file attributes, the security descriptor, and file * streams is replicated in each hard-linked dentry, even though this - * information really is associated with an inode. + * information really is associated with an inode. In-memory, we fix up this + * flaw by allocating a `struct inode' for each dentry that contains some of + * this duplicated information, then combining the inodes for each hard link + * group together. * - * Confusingly, it's also possible for stream information to be missing from a - * dentry in a hard link set, in which case the stream information needs to be - * gotten from one of the other dentries in the hard link set. In addition, it - * is possible for dentries to have inconsistent security IDs, file attributes, - * or file streams when they share the same hard link ID (don't even ask. I - * hope that Microsoft may have fixed this problem, since I've only noticed it - * in the 'install.wim' for Windows 7). For those dentries, we have to use the - * conflicting fields to split up the hard link groups. + * Confusingly, it's possible for stream information to be missing from a dentry + * in a hard link set, in which case the stream information needs to be gotten + * from one of the other dentries in the hard link set. In addition, it is + * possible for dentries to have inconsistent security IDs, file attributes, or + * file streams when they share the same hard link ID (don't even ask. I hope + * that Microsoft may have fixed this problem, since I've only noticed it in the + * 'install.wim' for Windows 7). For those dentries, we have to use the + * conflicting fields to split up the hard link groups. (See fix_inodes() in + * hardlink.c). */ struct dentry { /* The inode for this dentry */ @@ -248,22 +174,12 @@ struct dentry { */ u64 length; - /* The offset, from the start of the uncompressed WIM metadata resource * for this image, of this dentry's child dentries. 0 if the directory * entry has no children, which is the case for regular files or reparse * points. */ u64 subdir_offset; - - /* Although M$'s documentation does not tell you this, it seems that the - * reparse_reserved field does not actually exist. So the hard_link - * field directly follows the reparse_tag on disk. EXCEPT when the - * dentry is actually a reparse point... well, just take a look at the - * read_dentry() function. */ - //u32 reparse_reserved; - - /* Length of short filename, in bytes, not including the terminating * zero wide-character. */ u16 short_name_len; @@ -293,20 +209,110 @@ struct dentry { * WIMStructs */ u32 refcnt; - /* List of dentries in the hard link set */ + /* List of dentries in the inode (hard link set) */ struct list_head inode_dentry_list; + union { struct list_head tmp_list; bool is_extracted; }; }; +/* + * WIM inode. + * + * As mentioned above, in the WIM file that is no on-disk analogue of a real + * inode, as most of these fields are duplicated in the dentries. + */ +struct inode { + /* Timestamps for the inode. The timestamps are the number of + * 100-nanosecond intervals that have elapsed since 12:00 A.M., January + * 1st, 1601, UTC. This is the same format used in NTFS inodes. */ + u64 creation_time; + u64 last_access_time; + u64 last_write_time; + + /* The file attributes associated with this inode. This is a bitwise OR + * of the FILE_ATTRIBUTE_* flags. */ + u32 attributes; + + /* The index of the security descriptor in the WIM image's table of + * security descriptors that contains this file's security information. + * If -1, no security information exists for this file. */ + int32_t security_id; + + /* %true iff the inode's lookup table entries has been resolved (i.e. + * the @lte field is valid, but the @hash field is not valid) + * + * (This is not an on-disk field.) */ + u8 resolved : 1; + + /* %true iff verify_inode() has run on this dentry. */ + u8 verified : 1; + + /* Number of alternate data streams associated with this inode */ + u16 num_ads; + + /* A hash of the file's contents, or a pointer to the lookup table entry + * for this dentry if the lookup table entries have been resolved. + * + * More specifically, this is for the un-named default file stream, as + * opposed to the alternate (named) file streams, which may have their + * own lookup table entries. */ + union { + u8 hash[SHA1_HASH_SIZE]; + struct lookup_table_entry *lte; + }; + + /* Identity of a reparse point. See + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx + * for what a reparse point is. */ + u32 reparse_tag; + + /* Number of dentries that reference this inode */ + u32 link_count; + + /* Alternate data stream entries. */ + struct ads_entry *ads_entries; + + /* Inode number */ + u64 ino; + + /* List of dentries that reference this inode (there should be + * link_count of them) */ + struct list_head dentry_list; + struct hlist_node hlist; + char *extracted_file; + + /* If non-NULL, the children of this inode (implies the inode is a + * directory) */ + struct dentry *children; + +#ifdef WITH_FUSE + /* wimfs file descriptors table for the inode */ + u16 num_opened_fds; + u16 num_allocated_fds; + struct wimlib_fd **fds; + + /* Next alternate data stream ID to be assigned */ + u32 next_stream_id; +#endif +}; + +#define inode_for_each_dentry(dentry, inode) \ + list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list) + +#define inode_add_dentry(dentry, inode) \ + ({ \ + wimlib_assert((inode)->dentry_list.next != NULL); \ + list_add(&(dentry)->inode_dentry_list, &(inode)->dentry_list); \ + }) + static inline bool dentry_is_extracted(const struct dentry *dentry) { return dentry->is_extracted; } - extern struct ads_entry *inode_get_ads_entry(struct inode *inode, const char *stream_name, u16 *idx_ret); @@ -314,12 +320,17 @@ extern struct ads_entry *inode_get_ads_entry(struct inode *inode, extern struct ads_entry *inode_add_ads(struct inode *dentry, const char *stream_name); +extern void inode_remove_ads(struct inode *inode, u16 idx, + struct lookup_table *lookup_table); + extern const char *path_stream_name(const char *path); extern u64 dentry_total_length(const struct dentry *dentry); extern u64 dentry_correct_total_length(const struct dentry *dentry); extern void stbuf_to_inode(const struct stat *stbuf, struct inode *inode); +extern int inode_to_stbuf(const struct inode *inode, + struct lookup_table_entry *lte, struct stat *stbuf); extern int for_dentry_in_tree(struct dentry *root, int (*visitor)(struct dentry*, void*), @@ -357,7 +368,6 @@ extern struct inode *new_timeless_inode(); extern struct dentry *new_dentry_with_inode(const char *name); extern struct dentry *new_dentry_with_timeless_inode(const char *name); -extern void free_ads_entry(struct ads_entry *entry); extern void inode_free_ads_entries(struct inode *inode); extern struct inode *free_dentry(struct dentry *dentry); extern void free_inode(struct inode *inode); diff --git a/src/hardlink.c b/src/hardlink.c index d9f0640d..2927a789 100644 --- a/src/hardlink.c +++ b/src/hardlink.c @@ -184,8 +184,8 @@ static bool ref_inodes_consistent(const struct inode * restrict ref_inode_1, ref_2_hash = inode_stream_hash(ref_inode_2, i); if (!hashes_equal(ref_1_hash, ref_2_hash)) return false; - if (i && !ads_entries_have_same_name(ref_inode_1->ads_entries[i - 1], - ref_inode_2->ads_entries[i - 1])) + if (i && !ads_entries_have_same_name(&ref_inode_1->ads_entries[i - 1], + &ref_inode_2->ads_entries[i - 1])) return false; } @@ -209,8 +209,8 @@ static bool inodes_consistent(const struct inode * restrict ref_inode, hash = inode_stream_hash(inode, i); if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash)) return false; - if (i && !ads_entries_have_same_name(ref_inode->ads_entries[i - 1], - inode->ads_entries[i - 1])) + if (i && !ads_entries_have_same_name(&ref_inode->ads_entries[i - 1], + &inode->ads_entries[i - 1])) return false; } return true; diff --git a/src/lookup_table.c b/src/lookup_table.c index e28c12c6..e0fca5d4 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -457,6 +457,7 @@ __lookup_resource(const struct lookup_table *table, const u8 hash[]) return NULL; } +#ifdef WITH_FUSE /* * Finds the dentry, lookup table entry, and stream index for a WIM file stream, * given a path name. @@ -523,6 +524,7 @@ out: *stream_idx_ret = stream_idx; return 0; } +#endif static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table) { @@ -535,8 +537,7 @@ static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table) /* Resolve the alternate data streams */ for (u16 i = 0; i < inode->num_ads; i++) { - struct ads_entry *cur_entry = inode->ads_entries[i]; - + struct ads_entry *cur_entry = &inode->ads_entries[i]; lte = __lookup_resource(table, cur_entry->hash); cur_entry->lte = lte; } diff --git a/src/lookup_table.h b/src/lookup_table.h index 8735468c..f23a864a 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -307,7 +307,7 @@ inode_stream_lte_resolved(const struct inode *inode, unsigned stream_idx) if (stream_idx == 0) return inode->lte; else - return inode->ads_entries[stream_idx - 1]->lte; + return inode->ads_entries[stream_idx - 1].lte; } static inline struct lookup_table_entry * @@ -323,7 +323,7 @@ inode_stream_lte_unresolved(const struct inode *inode, unsigned stream_idx, else return __lookup_resource(table, inode->ads_entries[ - stream_idx - 1]->hash); + stream_idx - 1].hash); } /* * Returns the lookup table entry for stream @stream_idx of the inode, where @@ -351,7 +351,7 @@ static inline const u8 *inode_stream_hash_unresolved(const struct inode *inode, if (stream_idx == 0) return inode->hash; else - return inode->ads_entries[stream_idx - 1]->hash; + return inode->ads_entries[stream_idx - 1].hash; } @@ -389,7 +389,7 @@ static inline u16 inode_stream_name_len(const struct inode *inode, if (stream_idx == 0) return 0; else - return inode->ads_entries[stream_idx - 1]->stream_name_len; + return inode->ads_entries[stream_idx - 1].stream_name_len; } static inline struct lookup_table_entry * diff --git a/src/mount.c b/src/mount.c index 1a6f1dce..1241800d 100644 --- a/src/mount.c +++ b/src/mount.c @@ -227,76 +227,6 @@ static void remove_dentry(struct dentry *dentry, put_dentry(dentry); } -/* Remove an alternate data stream from the inode */ -static void inode_remove_ads(struct inode *inode, u16 idx, - struct lookup_table *lookup_table) -{ - struct ads_entry *ads_entry; - struct lookup_table_entry *lte; - - ads_entry = inode->ads_entries[idx]; - - wimlib_assert(ads_entry); - - lte = ads_entry->lte; - - if (lte) - lte_decrement_refcnt(lte, lookup_table); - - free_ads_entry(ads_entry); - - wimlib_assert(inode->num_ads); - memcpy(&inode->ads_entries[idx], - &inode->ads_entries[idx + 1], - (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0])); - inode->num_ads--; -} - -/* Transfers file attributes from a struct inode to a `stat' buffer. - * - * The lookup table entry tells us which stream in the inode we are statting. - * For a named data stream, everything returned is the same as the unnamed data - * stream except possibly the size and block count. */ -int inode_to_stbuf(const struct inode *inode, struct lookup_table_entry *lte, - struct stat *stbuf) -{ - if (inode_is_symlink(inode)) - stbuf->st_mode = S_IFLNK | 0777; - else if (inode_is_directory(inode)) - stbuf->st_mode = S_IFDIR | 0755; - else - stbuf->st_mode = S_IFREG | 0644; - - stbuf->st_ino = (ino_t)inode->ino; - stbuf->st_nlink = inode->link_count; - stbuf->st_uid = getuid(); - stbuf->st_gid = getgid(); - - if (lte) { - if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { - wimlib_assert(mount_flags & WIMLIB_MOUNT_FLAG_READWRITE); - wimlib_assert(lte->staging_file_name); - struct stat native_stat; - if (stat(lte->staging_file_name, &native_stat) != 0) { - DEBUG("Failed to stat `%s': %m", - lte->staging_file_name); - return -errno; - } - stbuf->st_size = native_stat.st_size; - } else { - stbuf->st_size = wim_resource_size(lte); - } - } else { - stbuf->st_size = 0; - } - - stbuf->st_atime = wim_timestamp_to_unix(inode->last_access_time); - stbuf->st_mtime = wim_timestamp_to_unix(inode->last_write_time); - stbuf->st_ctime = wim_timestamp_to_unix(inode->creation_time); - stbuf->st_blocks = (stbuf->st_size + 511) / 512; - return 0; -} - /* Creates a new staging file and returns its file descriptor opened for * writing. * @@ -470,8 +400,8 @@ static int extract_resource_to_staging_dir(struct inode *inode, inode->lte = new_lte; else for (u16 i = 0; i < inode->num_ads; i++) - if (inode->ads_entries[i]->stream_id == stream_id) - inode->ads_entries[i]->lte = new_lte; + if (inode->ads_entries[i].stream_id == stream_id) + inode->ads_entries[i].lte = new_lte; lookup_table_insert(w->lookup_table, new_lte); list_add(&new_lte->staging_list, &staging_list); @@ -1054,15 +984,15 @@ static int wimfs_listxattr(const char *path, char *list, size_t size) if (size == 0) { needed_size = 0; for (i = 0; i < inode->num_ads; i++) - needed_size += inode->ads_entries[i]->stream_name_utf8_len + 6; + needed_size += inode->ads_entries[i].stream_name_utf8_len + 6; return needed_size; } else { for (i = 0; i < inode->num_ads; i++) { - needed_size = inode->ads_entries[i]->stream_name_utf8_len + 6; + needed_size = inode->ads_entries[i].stream_name_utf8_len + 6; if (needed_size > size) return -ERANGE; p += sprintf(p, "user.%s", - inode->ads_entries[i]->stream_name_utf8) + 1; + inode->ads_entries[i].stream_name_utf8) + 1; size -= needed_size; } return p - list; @@ -1172,7 +1102,7 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) if (stream_idx == 0) stream_id = 0; else - stream_id = inode->ads_entries[stream_idx - 1]->stream_id; + stream_id = inode->ads_entries[stream_idx - 1].stream_id; /* The file resource may be in the staging directory (read-write mounts * only) or in the WIM. If it's in the staging directory, we need to @@ -1568,7 +1498,7 @@ static int wimfs_truncate(const char *path, off_t size) if (stream_idx == 0) stream_id = 0; else - stream_id = inode->ads_entries[stream_idx - 1]->stream_id; + stream_id = inode->ads_entries[stream_idx - 1].stream_id; if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { wimlib_assert(lte->staging_file_name); diff --git a/src/ntfs-apply.c b/src/ntfs-apply.c index 1a97e72c..9628e25e 100644 --- a/src/ntfs-apply.c +++ b/src/ntfs-apply.c @@ -162,8 +162,8 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct dentry *dentry, } if (stream_idx == inode->num_ads) break; - stream_name = (ntfschar*)inode->ads_entries[stream_idx]->stream_name; - stream_name_len = inode->ads_entries[stream_idx]->stream_name_len / 2; + stream_name = (ntfschar*)inode->ads_entries[stream_idx].stream_name; + stream_name_len = inode->ads_entries[stream_idx].stream_name_len / 2; stream_idx++; } return ret; @@ -241,8 +241,6 @@ static int wim_apply_hardlink_ntfs(const struct dentry *from_dentry, return ret; } -/*#define HAVE_NTFS_INODE_FUNCTIONS*/ - static int apply_file_attributes_and_security_data(ntfs_inode *ni, ntfs_inode *dir_ni, @@ -252,9 +250,6 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32, dentry->full_path_utf8, dentry->inode->attributes); int ret; -#ifdef HAVE_NTFS_INODE_FUNCTIONS - ret = ntfs_set_inode_attributes(ni, dentry->inode->attributes); -#else struct SECURITY_CONTEXT ctx; u32 attributes_le32; attributes_le32 = cpu_to_le32(dentry->inode->attributes); @@ -264,7 +259,6 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, ni, dir_ni, (const char*)&attributes_le32, sizeof(u32), 0); -#endif if (ret != 0) { ERROR("Failed to set NTFS file attributes on `%s'", dentry->full_path_utf8); @@ -280,17 +274,9 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, DEBUG("Applying security descriptor %d to `%s'", dentry->inode->security_id, dentry->full_path_utf8); - #ifdef HAVE_NTFS_INODE_FUNCTIONS - u32 selection = OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION | - SACL_SECURITY_INFORMATION; - ret = ntfs_set_inode_security(ni, selection, descriptor); - #else ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL, ni, dir_ni, descriptor, sd->sizes[dentry->inode->security_id], 0); - #endif if (ret != 0) { ERROR_WITH_ERRNO("Failed to set security data on `%s'", diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index 7c92c9e2..bc7bc954 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -51,13 +51,6 @@ #include #include -#if 0 -extern int ntfs_get_inode_security(ntfs_inode *ni, u32 selection, char *buf, - u32 buflen, u32 *psize); - -extern u32 ntfs_get_inode_attributes(ntfs_inode *ni); -#endif - /* Structure that allows searching the security descriptors by SHA1 message * digest. */ struct sd_set { @@ -521,9 +514,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, struct dentry *root; mrec_flags = ni->mrec->flags; -#ifdef HAVE_NTFS_INODE_FUNCTIONS - attributes = ntfs_get_inode_attributes(ni); -#else struct SECURITY_CONTEXT ctx; memset(&ctx, 0, sizeof(ctx)); ctx.vol = ni->vol; @@ -535,7 +525,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, path); return WIMLIB_ERR_NTFS_3G; } -#endif if (exclude_path(path, config, false)) { if (flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) { @@ -622,41 +611,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, if (ret != 0) return ret; -#ifdef HAVE_NTFS_INODE_FUNCTIONS - ret = ntfs_get_inode_security(ni, - OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION | - SACL_SECURITY_INFORMATION, - NULL, 0, &sd_size); - char sd[sd_size]; - ret = ntfs_get_inode_security(ni, - OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION | - SACL_SECURITY_INFORMATION, - sd, sd_size, &sd_size); - if (ret == 0) { - ERROR_WITH_ERRNO("Failed to get security information from " - "`%s'", path); - ret = WIMLIB_ERR_NTFS_3G; - } else { - if (ret > 0) { - /*print_security_descriptor(sd, sd_size);*/ - root->security_id = sd_set_add_sd(sd_set, sd, ret); - if (root->security_id == -1) { - ERROR("Out of memory"); - return WIMLIB_ERR_NOMEM; - } - DEBUG("Added security ID = %u for `%s'", - root->security_id, path); - } else { - root->security_id = -1; - DEBUG("No security ID for `%s'", path); - } - ret = 0; - } -#else char _sd[1]; char *sd = _sd; errno = 0; @@ -685,7 +639,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, root->inode->security_id = -1; DEBUG("No security ID for `%s'", path); } -#endif return ret; } -- 2.43.0