X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Flookup_table.h;h=f23a864a45796fee19a3e10dc5b3d1e9daac324e;hp=6fc5ae50c3f5f37439ca191f01d4fc3ef3ba0105;hb=50670821723291959a6f35442c523800d369c934;hpb=6f841e85af6215e88bce12a34a00548664fba6ea diff --git a/src/lookup_table.h b/src/lookup_table.h index 6fc5ae50..f23a864a 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -142,28 +142,23 @@ struct lookup_table_entry { #endif }; union { - /* Temporary field for creating a singly linked list. Shouldn't - * really be here */ - struct lookup_table_entry *next_lte_in_swm; - /* @file_on_disk_fp and @attr are both used to cache file/stream * handles so we don't have re-open them on every read */ + + /* Valid iff resource_location == RESOURCE_IN_FILE_ON_DISK */ FILE *file_on_disk_fp; #ifdef WITH_NTFS_3G + /* Valid iff resource_location == RESOURCE_IN_NTFS_VOLUME */ struct _ntfs_attr *attr; #endif + + /* Pointer to inode that contains the opened file descriptors to + * this stream (valid iff resource_location == + * RESOURCE_IN_STAGING_FILE) */ + struct inode *inode; }; #ifdef WITH_FUSE - /* File descriptors table for this data stream. This is used if the WIM - * is mounted. Basically, each time a file is open()ed, a new file - * descriptor is added here, and each time a file is close()ed, the file - * descriptor is gotten rid of. If the stream is opened for writing, it - * will be extracted to the staging directory and there will be an - * actual native file descriptor associated with each "wimlib file - * descriptor". */ u16 num_opened_fds; - u16 num_allocated_fds; - struct wimlib_fd **fds; #endif /* When a WIM file is written, out_refcnt starts at 0 and is incremented @@ -173,35 +168,32 @@ struct lookup_table_entry { * dentries. */ u32 out_refcnt; + u32 real_refcnt; + + /* When a WIM file is written, @output_resource_entry is filled + * in with the resource entry for the output WIM. This will not + * necessarily be the same as the @resource_entry since: + * - The stream may have a different offset in the new WIM + * - The stream may have a different compressed size in the + * new WIM if the compression type changed + */ + struct resource_entry output_resource_entry; + + /* This field is used for the special hardlink or symlink image + * extraction mode. In these mode, all identical files are linked + * together, and @extracted_file will be set to the filename of the + * first extracted file containing this stream. */ + char *extracted_file; + union { - /* When a WIM file is written, @output_resource_entry is filled - * in with the resource entry for the output WIM. This will not - * necessarily be the same as the @resource_entry since: - * - The stream may have a different offset in the new WIM - * - The stream may have a different compressed size in the - * new WIM if the compression type changed - */ - struct resource_entry output_resource_entry; - - /* This field is used for the special hardlink or symlink image - * application mode. In these mode, all identical files are - * linked together, and @extracted_file will be set to the - * filename of the first extracted file containing this stream. - * */ - char *extracted_file; - }; + /* List of lookup table entries that correspond to streams that have + * been extracted to the staging directory when modifying a read-write + * mounted WIM. */ + struct list_head staging_list; - /* Circular linked list of streams that share the same lookup table - * entry. - * - * This list of streams may include streams from different hard link - * sets that happen to be the same. */ - struct list_head lte_group_list; - - /* List of lookup table entries that correspond to streams that have - * been extracted to the staging directory when modifying a read-write - * mounted WIM. */ - struct list_head staging_list; + /* Temporary field for creating a singly linked list. */ + struct lookup_table_entry *next_lte_in_swm; + }; }; static inline u64 wim_resource_size(const struct lookup_table_entry *lte) @@ -246,6 +238,12 @@ static inline void lookup_table_unlink(struct lookup_table *table, extern struct lookup_table_entry * lookup_table_decrement_refcnt(struct lookup_table* table, const u8 hash[]); +#ifdef WITH_FUSE +extern struct lookup_table_entry * +lte_decrement_num_opened_fds(struct lookup_table_entry *lte, + struct lookup_table *table); +#endif + extern struct lookup_table_entry * lte_decrement_refcnt(struct lookup_table_entry *lte, struct lookup_table *table); @@ -263,9 +261,11 @@ __lookup_resource(const struct lookup_table *table, const u8 hash[]); extern int lookup_resource(WIMStruct *w, const char *path, int lookup_flags, struct dentry **dentry_ret, struct lookup_table_entry **lte_ret, - unsigned *stream_idx_ret); + u16 *stream_idx_ret); -extern int zero_out_refcnts(struct lookup_table_entry *entry, void *ignore); +extern int lte_zero_out_refcnt(struct lookup_table_entry *entry, void *ignore); +extern int lte_zero_real_refcnt(struct lookup_table_entry *entry, void *ignore); +extern int lte_free_extracted_file(struct lookup_table_entry *lte, void *ignone); extern void print_lookup_table_entry(const struct lookup_table_entry *entry); @@ -300,75 +300,66 @@ static inline struct resource_entry* wim_metadata_resource_entry(WIMStruct *w) } static inline struct lookup_table_entry * -dentry_stream_lte_resolved(const struct dentry *dentry, unsigned stream_idx) +inode_stream_lte_resolved(const struct inode *inode, unsigned stream_idx) { - wimlib_assert(dentry->resolved); - wimlib_assert(stream_idx <= dentry->num_ads); + wimlib_assert(inode->resolved); + wimlib_assert(stream_idx <= inode->num_ads); if (stream_idx == 0) - return dentry->lte; + return inode->lte; else - return dentry->ads_entries[stream_idx - 1].lte; + return inode->ads_entries[stream_idx - 1].lte; } static inline struct lookup_table_entry * -dentry_stream_lte_unresolved(const struct dentry *dentry, unsigned stream_idx, +inode_stream_lte_unresolved(const struct inode *inode, unsigned stream_idx, const struct lookup_table *table) { - wimlib_assert(!dentry->resolved); - wimlib_assert(stream_idx <= dentry->num_ads); + wimlib_assert(!inode->resolved); + wimlib_assert(stream_idx <= inode->num_ads); if (!table) return NULL; if (stream_idx == 0) - return __lookup_resource(table, dentry->hash); + return __lookup_resource(table, inode->hash); else return __lookup_resource(table, - dentry->ads_entries[ + inode->ads_entries[ stream_idx - 1].hash); } /* - * Returns the lookup table entry for stream @stream_idx of the dentry, where + * Returns the lookup table entry for stream @stream_idx of the inode, where * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1 * corresponds to an alternate data stream. * * This works for both resolved and un-resolved dentries. */ static inline struct lookup_table_entry * -dentry_stream_lte(const struct dentry *dentry, unsigned stream_idx, - const struct lookup_table *table) +inode_stream_lte(const struct inode *inode, unsigned stream_idx, + const struct lookup_table *table) { - if (dentry->resolved) - return dentry_stream_lte_resolved(dentry, stream_idx); + if (inode->resolved) + return inode_stream_lte_resolved(inode, stream_idx); else - return dentry_stream_lte_unresolved(dentry, stream_idx, table); + return inode_stream_lte_unresolved(inode, stream_idx, table); } -static inline const u8 *dentry_stream_hash_unresolved(const struct dentry *dentry, - unsigned stream_idx) +static inline const u8 *inode_stream_hash_unresolved(const struct inode *inode, + unsigned stream_idx) { - wimlib_assert(!dentry->resolved); - wimlib_assert(stream_idx <= dentry->num_ads); + wimlib_assert(!inode->resolved); + wimlib_assert(stream_idx <= inode->num_ads); if (stream_idx == 0) - return dentry->hash; + return inode->hash; else - return dentry->ads_entries[stream_idx - 1].hash; + return inode->ads_entries[stream_idx - 1].hash; } -static inline u16 dentry_stream_name_len(const struct dentry *dentry, - unsigned stream_idx) -{ - wimlib_assert(stream_idx <= dentry->num_ads); - if (stream_idx == 0) - return 0; - else - return dentry->ads_entries[stream_idx - 1].stream_name_len; -} -static inline const u8 *dentry_stream_hash_resolved(const struct dentry *dentry, - unsigned stream_idx) +static inline const u8 *inode_stream_hash_resolved(const struct inode *inode, + unsigned stream_idx) { struct lookup_table_entry *lte; - lte = dentry_stream_lte_resolved(dentry, stream_idx); + lte = inode_stream_lte_resolved(inode, stream_idx); if (lte) return lte->hash; else @@ -376,46 +367,57 @@ static inline const u8 *dentry_stream_hash_resolved(const struct dentry *dentry, } /* - * Returns the hash for stream @stream_idx of the dentry, where stream_idx = 0 + * Returns the hash for stream @stream_idx of the inode, where stream_idx = 0 * means the default un-named file stream, and stream_idx >= 1 corresponds to an * alternate data stream. * * This works for both resolved and un-resolved dentries. */ -static inline const u8 *dentry_stream_hash(const struct dentry *dentry, - unsigned stream_idx) +static inline const u8 *inode_stream_hash(const struct inode *inode, + unsigned stream_idx) +{ + if (inode->resolved) + return inode_stream_hash_resolved(inode, stream_idx); + else + return inode_stream_hash_unresolved(inode, stream_idx); +} + +static inline u16 inode_stream_name_len(const struct inode *inode, + unsigned stream_idx) { - if (dentry->resolved) - return dentry_stream_hash_resolved(dentry, stream_idx); + wimlib_assert(stream_idx <= inode->num_ads); + if (stream_idx == 0) + return 0; else - return dentry_stream_hash_unresolved(dentry, stream_idx); + return inode->ads_entries[stream_idx - 1].stream_name_len; } static inline struct lookup_table_entry * -dentry_unnamed_lte_resolved(const struct dentry *dentry) +inode_unnamed_lte_resolved(const struct inode *inode) { - wimlib_assert(dentry->resolved); - for (unsigned i = 0; i <= dentry->num_ads; i++) - if (dentry_stream_name_len(dentry, i) == 0 && - !is_zero_hash(dentry_stream_hash_resolved(dentry, i))) - return dentry_stream_lte_resolved(dentry, i); + wimlib_assert(inode->resolved); + for (unsigned i = 0; i <= inode->num_ads; i++) + if (inode_stream_name_len(inode, i) == 0 && + !is_zero_hash(inode_stream_hash_resolved(inode, i))) + return inode_stream_lte_resolved(inode, i); return NULL; } static inline struct lookup_table_entry * -dentry_unnamed_lte_unresolved(const struct dentry *dentry, - const struct lookup_table *table) +inode_unnamed_lte_unresolved(const struct inode *inode, + const struct lookup_table *table) { - wimlib_assert(!dentry->resolved); - for (unsigned i = 0; i <= dentry->num_ads; i++) - if (dentry_stream_name_len(dentry, i) == 0 && - !is_zero_hash(dentry_stream_hash_unresolved(dentry, i))) - return dentry_stream_lte_unresolved(dentry, i, table); + wimlib_assert(!inode->resolved); + for (unsigned i = 0; i <= inode->num_ads; i++) + if (inode_stream_name_len(inode, i) == 0 && + !is_zero_hash(inode_stream_hash_unresolved(inode, i))) + return inode_stream_lte_unresolved(inode, i, table); return NULL; } extern struct lookup_table_entry * -dentry_unnamed_lte(const struct dentry *dentry, - const struct lookup_table *table); +inode_unnamed_lte(const struct inode *inode, + const struct lookup_table *table); + #endif