4 * Functions that operate on WIM inodes.
6 * See dentry.c for a description of the relationship between WIM dentries and
11 * Copyright (C) 2012, 2013, 2014, 2015 Eric Biggers
13 * This file is free software; you can redistribute it and/or modify it under
14 * the terms of the GNU Lesser General Public License as published by the Free
15 * Software Foundation; either version 3 of the License, or (at your option) any
18 * This file is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this file; if not, see http://www.gnu.org/licenses/.
33 #include "wimlib/assert.h"
34 #include "wimlib/blob_table.h"
35 #include "wimlib/dentry.h"
36 #include "wimlib/encoding.h"
37 #include "wimlib/error.h"
38 #include "wimlib/inode.h"
39 #include "wimlib/timestamp.h"
42 * The 'stream_name' field of unnamed streams always points to this array, which
43 * is an empty UTF-16 string.
45 const utf16lechar NO_STREAM_NAME[1];
47 /* Allocate a new inode. Set the timestamps to the current time. */
51 struct wim_inode *inode = new_timeless_inode();
53 u64 now = now_as_wim_timestamp();
54 inode->i_creation_time = now;
55 inode->i_last_access_time = now;
56 inode->i_last_write_time = now;
61 /* Allocate a new inode. Leave the timestamps zeroed out. */
63 new_timeless_inode(void)
65 struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
67 inode->i_security_id = -1;
68 /*inode->i_nlink = 0;*/
69 inode->i_not_rpfixed = 1;
70 INIT_LIST_HEAD(&inode->i_list);
71 INIT_LIST_HEAD(&inode->i_dentry);
77 destroy_stream(struct wim_inode_stream *strm)
79 if (strm->stream_name != NO_STREAM_NAME)
80 FREE(strm->stream_name);
84 free_inode(struct wim_inode *inode)
86 for (unsigned i = 0; i < inode->i_num_streams; i++)
87 destroy_stream(&inode->i_streams[i]);
88 if (inode->i_streams != inode->i_embedded_streams)
89 FREE(inode->i_streams);
92 /* HACK: This may instead delete the inode from i_list, but hlist_del()
93 * behaves the same as list_del(). */
94 if (!hlist_unhashed(&inode->i_hlist))
95 hlist_del(&inode->i_hlist);
100 free_inode_if_unneeded(struct wim_inode *inode)
105 if (inode->i_num_opened_fds)
111 /* Associate a dentry with the specified inode. */
113 d_associate(struct wim_dentry *dentry, struct wim_inode *inode)
115 wimlib_assert(!dentry->d_inode);
117 list_add_tail(&dentry->d_alias, &inode->i_dentry);
118 dentry->d_inode = inode;
122 /* Disassociate a dentry from its inode, if any. Following this, free the inode
123 * if it is no longer in use. */
125 d_disassociate(struct wim_dentry *dentry)
127 struct wim_inode *inode = dentry->d_inode;
129 if (unlikely(!inode))
132 wimlib_assert(inode->i_nlink > 0);
134 list_del(&dentry->d_alias);
135 dentry->d_inode = NULL;
138 free_inode_if_unneeded(inode);
143 inode_dec_num_opened_fds(struct wim_inode *inode)
145 wimlib_assert(inode->i_num_opened_fds > 0);
147 if (--inode->i_num_opened_fds == 0) {
148 /* The last file descriptor to this inode was closed. */
151 inode->i_num_allocated_fds = 0;
153 free_inode_if_unneeded(inode);
159 * Retrieve a stream of an inode.
162 * The inode from which the stream is desired
164 * The type of the stream desired
166 * The name of the stream desired as a null-terminated UTF-16LE string, or
167 * NO_STREAM_NAME if an unnamed stream is desired
169 * Returns a pointer to the stream if found, otherwise NULL.
171 struct wim_inode_stream *
172 inode_get_stream(const struct wim_inode *inode, int stream_type,
173 const utf16lechar *stream_name)
175 if (stream_name == NO_STREAM_NAME) /* Optimization */
176 return inode_get_unnamed_stream(inode, stream_type);
178 for (unsigned i = 0; i < inode->i_num_streams; i++) {
179 struct wim_inode_stream *strm = &inode->i_streams[i];
180 if (strm->stream_type == stream_type &&
181 !cmp_utf16le_strings_z(strm->stream_name, stream_name,
182 default_ignore_case))
191 * This is equivalent to inode_get_stream(inode, stream_type, NO_STREAM_NAME),
192 * but this optimizes for the unnamed case by not doing full string comparisons.
194 struct wim_inode_stream *
195 inode_get_unnamed_stream(const struct wim_inode *inode, int stream_type)
197 for (unsigned i = 0; i < inode->i_num_streams; i++) {
198 struct wim_inode_stream *strm = &inode->i_streams[i];
199 if (strm->stream_type == stream_type &&
200 strm->stream_name == NO_STREAM_NAME)
209 * Add a new stream to the specified inode.
212 * The inode to which to add the stream
214 * The type of the stream being added
216 * The name of the stream being added as a null-terminated UTF-16LE string,
217 * or NO_STREAM_NAME if the stream is unnamed
219 * The blob that the new stream will initially reference, or NULL
221 * Returns a pointer to the new stream, or NULL with errno set if it could not
224 struct wim_inode_stream *
225 inode_add_stream(struct wim_inode *inode, int stream_type,
226 const utf16lechar *stream_name, struct blob_descriptor *blob)
228 if (inode->i_num_streams >= 0xFFFF) {
229 ERROR("Inode has too many streams! Path=\"%"TS"\"",
230 inode_first_full_path(inode));
235 struct wim_inode_stream *streams;
236 struct wim_inode_stream *new_strm;
238 if (inode->i_streams == inode->i_embedded_streams) {
239 if (inode->i_num_streams < ARRAY_LEN(inode->i_embedded_streams)) {
240 streams = inode->i_embedded_streams;
242 streams = MALLOC((inode->i_num_streams + 1) *
243 sizeof(inode->i_streams[0]));
246 memcpy(streams, inode->i_streams,
247 (inode->i_num_streams *
248 sizeof(inode->i_streams[0])));
249 inode->i_streams = streams;
252 streams = REALLOC(inode->i_streams,
253 (inode->i_num_streams + 1) *
254 sizeof(inode->i_streams[0]));
257 inode->i_streams = streams;
259 new_strm = &streams[inode->i_num_streams];
261 memset(new_strm, 0, sizeof(*new_strm));
263 new_strm->stream_type = stream_type;
266 new_strm->stream_name = (utf16lechar *)NO_STREAM_NAME;
269 new_strm->stream_name = utf16le_dup(stream_name);
270 if (!new_strm->stream_name)
273 new_strm->stream_id = inode->i_next_stream_id++;
275 stream_set_blob(new_strm, blob);
277 inode->i_num_streams++;
283 * Create a new blob descriptor for the specified data buffer or use an existing
284 * blob descriptor in @blob_table for an identical blob, then add a stream of
285 * the specified type and name to the specified inode and set it to initially
286 * reference the blob.
289 * The inode to which to add the stream
291 * The type of the stream being added
293 * The name of the stream being added as a null-terminated UTF-16LE string,
294 * or NO_STREAM_NAME if the stream is unnamed
296 * The uncompressed data of the blob
298 * The size, in bytes, of the blob data
300 * Pointer to the blob table in which the blob needs to be indexed.
302 * Returns a pointer to the new stream if successfully added, otherwise NULL
305 struct wim_inode_stream *
306 inode_add_stream_with_data(struct wim_inode *inode,
307 int stream_type, const utf16lechar *stream_name,
308 const void *data, size_t size,
309 struct blob_table *blob_table)
311 struct blob_descriptor *blob;
312 struct wim_inode_stream *strm;
314 blob = new_blob_from_data_buffer(data, size, blob_table);
317 strm = inode_add_stream(inode, stream_type, stream_name, blob);
319 blob_decrement_refcnt(blob, blob_table);
324 * Remove a stream from the specified inode and release the reference to the
325 * blob descriptor, if any.
328 inode_remove_stream(struct wim_inode *inode, struct wim_inode_stream *strm,
329 struct blob_table *blob_table)
331 struct blob_descriptor *blob;
332 unsigned idx = strm - inode->i_streams;
334 wimlib_assert(idx < inode->i_num_streams);
336 blob = stream_blob(strm, blob_table);
338 blob_decrement_refcnt(blob, blob_table);
340 destroy_stream(strm);
342 memmove(&inode->i_streams[idx],
343 &inode->i_streams[idx + 1],
344 (inode->i_num_streams - idx - 1) * sizeof(inode->i_streams[0]));
345 inode->i_num_streams--;
348 /* Returns true iff the specified inode has at least one named data stream. */
350 inode_has_named_data_stream(const struct wim_inode *inode)
352 for (unsigned i = 0; i < inode->i_num_streams; i++)
353 if (stream_is_named_data_stream(&inode->i_streams[i]))
359 * Resolve an inode's streams.
361 * For each stream, this replaces the SHA-1 message digest of the blob data with
362 * a pointer to the 'struct blob_descriptor' for the blob. Blob descriptors are
363 * looked up in @table.
365 * If @force is %false:
366 * If any of the needed blobs do not exist in @table, return
367 * WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified.
368 * If @force is %true:
369 * If any of the needed blobs do not exist in @table, allocate new blob
370 * descriptors for them and insert them into @table. This does not, of
371 * course, cause the data of these blobs to magically exist, but this is
372 * needed by the code for extraction from a pipe.
374 * Returns 0 on success; WIMLIB_ERR_NOMEM if out of memory; or
375 * WIMLIB_ERR_RESOURCE_NOT_FOUND if @force is %false and at least one blob
376 * referenced by the inode was missing.
379 inode_resolve_streams(struct wim_inode *inode, struct blob_table *table,
382 struct blob_descriptor *blobs[inode->i_num_streams];
384 for (unsigned i = 0; i < inode->i_num_streams; i++) {
386 if (inode->i_streams[i].stream_resolved)
389 const u8 *hash = stream_hash(&inode->i_streams[i]);
390 struct blob_descriptor *blob = NULL;
392 if (!is_zero_hash(hash)) {
393 blob = lookup_blob(table, hash);
396 return blob_not_found_error(inode, hash);
397 blob = new_blob_descriptor();
399 return WIMLIB_ERR_NOMEM;
400 copy_hash(blob->hash, hash);
401 blob_table_insert(table, blob);
407 for (unsigned i = 0; i < inode->i_num_streams; i++)
408 if (!inode->i_streams[i].stream_resolved)
409 stream_set_blob(&inode->i_streams[i], blobs[i]);
413 /* Undo the effects of inode_resolve_streams(). */
415 inode_unresolve_streams(struct wim_inode *inode)
417 for (unsigned i = 0; i < inode->i_num_streams; i++) {
419 if (!inode->i_streams[i].stream_resolved)
422 copy_hash(inode->i_streams[i]._stream_hash,
423 stream_hash(&inode->i_streams[i]));
424 inode->i_streams[i].stream_resolved = 0;
429 blob_not_found_error(const struct wim_inode *inode, const u8 *hash)
431 if (wimlib_print_errors) {
432 tchar hashstr[SHA1_HASH_SIZE * 2 + 1];
434 sprint_hash(hash, hashstr);
436 ERROR("\"%"TS"\": blob not found\n"
437 " SHA-1 message digest of missing blob:\n"
439 inode_first_full_path(inode), hashstr);
441 return WIMLIB_ERR_RESOURCE_NOT_FOUND;
445 * Return the blob descriptor for the specified stream, or NULL if the blob for
446 * the stream is empty or not available.
448 struct blob_descriptor *
449 stream_blob(const struct wim_inode_stream *strm, const struct blob_table *table)
451 if (strm->stream_resolved)
452 return strm->_stream_blob;
454 return lookup_blob(table, strm->_stream_hash);
457 /* Return the SHA-1 message digest of the data of the specified stream, or a
458 * void SHA-1 of all zeroes if the specified stream is empty. */
460 stream_hash(const struct wim_inode_stream *strm)
462 if (strm->stream_resolved)
463 return strm->_stream_blob ? strm->_stream_blob->hash : zero_hash;
465 return strm->_stream_hash;
469 * Return the blob descriptor for the unnamed data stream of the inode, or NULL
470 * if the inode does not have an unnamed data stream, the blob for the inode's
471 * unnamed data stream is empty, or the blob for the inode's unnamed data stream
472 * is not available in @blob_table.
474 struct blob_descriptor *
475 inode_get_blob_for_unnamed_data_stream(const struct wim_inode *inode,
476 const struct blob_table *blob_table)
478 const struct wim_inode_stream *strm;
480 strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA);
484 return stream_blob(strm, blob_table);
487 /* Like inode_get_blob_for_unnamed_data_stream(), but assumes the unnamed data
488 * stream is resolved. */
489 struct blob_descriptor *
490 inode_get_blob_for_unnamed_data_stream_resolved(const struct wim_inode *inode)
492 const struct wim_inode_stream *strm;
494 strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA);
498 return stream_blob_resolved(strm);
502 * Return the SHA-1 message digest of the unnamed data stream of the inode, or a
503 * void SHA-1 of all zeroes if the inode does not have an unnamed data stream or
504 * if the inode's unnamed data stream is empty.
507 inode_get_hash_of_unnamed_data_stream(const struct wim_inode *inode)
509 const struct wim_inode_stream *strm;
511 strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA);
515 return stream_hash(strm);
518 /* Acquire another reference to each blob referenced by this inode. This is
519 * necessary when creating a hard link to this inode.
521 * All streams of the inode must be resolved. */
523 inode_ref_blobs(struct wim_inode *inode)
525 for (unsigned i = 0; i < inode->i_num_streams; i++) {
526 struct blob_descriptor *blob;
528 blob = stream_blob_resolved(&inode->i_streams[i]);
534 /* Release a reference to each blob referenced by this inode. This is necessary
535 * when deleting a hard link to this inode. */
537 inode_unref_blobs(struct wim_inode *inode, struct blob_table *blob_table)
539 for (unsigned i = 0; i < inode->i_num_streams; i++) {
540 struct blob_descriptor *blob;
542 blob = stream_blob(&inode->i_streams[i], blob_table);
544 blob_decrement_refcnt(blob, blob_table);
549 * Given a blob descriptor, return a pointer to the pointer contained in the
550 * stream that references it.
552 * This is only possible for "unhashed" blobs, which are guaranteed to have only
553 * one referencing stream, and that reference is guaranteed to be in a resolved
554 * stream. (It can't be in an unresolved stream, since that would imply the
557 struct blob_descriptor **
558 retrieve_pointer_to_unhashed_blob(struct blob_descriptor *blob)
560 wimlib_assert(blob->unhashed);
562 struct wim_inode *inode = blob->back_inode;
563 for (unsigned i = 0; i < inode->i_num_streams; i++) {
564 if (inode->i_streams[i].stream_id == blob->back_stream_id) {
565 wimlib_assert(inode->i_streams[i]._stream_blob == blob);
566 return &inode->i_streams[i]._stream_blob;