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-2018 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 https://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 and associate the specified dentry with it. */
49 new_inode(struct wim_dentry *dentry, bool set_timestamps)
51 struct wim_inode *inode;
53 inode = CALLOC(1, sizeof(struct wim_inode));
57 inode->i_security_id = -1;
58 /*inode->i_nlink = 0;*/
59 inode->i_rp_flags = WIM_RP_FLAG_NOT_FIXED;
60 INIT_HLIST_HEAD(&inode->i_alias_list);
61 inode->i_streams = inode->i_embedded_streams;
63 u64 now = now_as_wim_timestamp();
64 inode->i_creation_time = now;
65 inode->i_last_access_time = now;
66 inode->i_last_write_time = now;
68 d_associate(dentry, inode);
73 destroy_stream(struct wim_inode_stream *strm)
75 if (strm->stream_name != NO_STREAM_NAME)
76 FREE(strm->stream_name);
80 free_inode(struct wim_inode *inode)
82 for (unsigned i = 0; i < inode->i_num_streams; i++)
83 destroy_stream(&inode->i_streams[i]);
84 if (inode->i_streams != inode->i_embedded_streams)
85 FREE(inode->i_streams);
88 if (!hlist_unhashed(&inode->i_hlist_node))
89 hlist_del(&inode->i_hlist_node);
94 free_inode_if_unneeded(struct wim_inode *inode)
99 if (inode->i_num_opened_fds)
105 /* Associate a dentry with the specified inode. */
107 d_associate(struct wim_dentry *dentry, struct wim_inode *inode)
109 wimlib_assert(!dentry->d_inode);
111 hlist_add_head(&dentry->d_alias_node, &inode->i_alias_list);
112 dentry->d_inode = inode;
116 /* Disassociate a dentry from its inode, if any. Following this, free the inode
117 * if it is no longer in use. */
119 d_disassociate(struct wim_dentry *dentry)
121 struct wim_inode *inode = dentry->d_inode;
123 if (unlikely(!inode))
126 wimlib_assert(inode->i_nlink > 0);
128 hlist_del(&dentry->d_alias_node);
129 dentry->d_inode = NULL;
132 free_inode_if_unneeded(inode);
137 inode_dec_num_opened_fds(struct wim_inode *inode)
139 wimlib_assert(inode->i_num_opened_fds > 0);
141 if (--inode->i_num_opened_fds == 0) {
142 /* The last file descriptor to this inode was closed. */
145 inode->i_num_allocated_fds = 0;
147 free_inode_if_unneeded(inode);
153 * Retrieve a stream of an inode.
156 * The inode from which the stream is desired
158 * The type of the stream desired
160 * The name of the stream desired as a null-terminated UTF-16LE string, or
161 * NO_STREAM_NAME if an unnamed stream is desired
163 * Returns a pointer to the stream if found, otherwise NULL.
165 struct wim_inode_stream *
166 inode_get_stream(const struct wim_inode *inode, int stream_type,
167 const utf16lechar *stream_name)
169 if (stream_name == NO_STREAM_NAME) /* Optimization */
170 return inode_get_unnamed_stream(inode, stream_type);
172 for (unsigned i = 0; i < inode->i_num_streams; i++) {
173 struct wim_inode_stream *strm = &inode->i_streams[i];
174 if (strm->stream_type == stream_type &&
175 !cmp_utf16le_strings_z(strm->stream_name, stream_name,
176 default_ignore_case))
185 * This is equivalent to inode_get_stream(inode, stream_type, NO_STREAM_NAME),
186 * but this optimizes for the unnamed case by not doing full string comparisons.
188 struct wim_inode_stream *
189 inode_get_unnamed_stream(const struct wim_inode *inode, int stream_type)
191 for (unsigned i = 0; i < inode->i_num_streams; i++) {
192 struct wim_inode_stream *strm = &inode->i_streams[i];
193 if (strm->stream_type == stream_type &&
194 strm->stream_name == NO_STREAM_NAME)
204 inode_set_stream_blob(struct wim_inode *inode, struct wim_inode_stream *strm,
205 struct blob_descriptor *new_blob)
207 strm->_stream_blob = new_blob;
208 strm->stream_resolved = 1;
210 new_blob->refcnt += inode->i_nlink;
214 inode_unset_stream_blob(struct wim_inode *inode, struct wim_inode_stream *strm,
215 struct blob_table *blob_table)
217 struct blob_descriptor *old_blob;
219 old_blob = stream_blob(strm, blob_table);
221 blob_subtract_refcnt(old_blob, blob_table, inode->i_nlink);
222 strm->_stream_blob = NULL;
223 strm->stream_resolved = 1;
227 * Replace the blob associated with the specified stream.
230 * The inode containing @strm
232 * The stream whose data needs to be replaced
234 * The new blob descriptor to assign
236 * Pointer to the blob table in which data blobs are being indexed
239 inode_replace_stream_blob(struct wim_inode *inode,
240 struct wim_inode_stream *strm,
241 struct blob_descriptor *new_blob,
242 struct blob_table *blob_table)
244 inode_unset_stream_blob(inode, strm, blob_table);
245 inode_set_stream_blob(inode, strm, new_blob);
249 * Add a new stream to the specified inode.
252 * The inode to which to add the stream
254 * The type of the stream being added
256 * The name of the stream being added as a null-terminated UTF-16LE string,
257 * or NO_STREAM_NAME if the stream is unnamed
259 * The blob that the new stream will initially reference, or NULL
261 * Returns a pointer to the new stream, or NULL with errno set if it could not
264 struct wim_inode_stream *
265 inode_add_stream(struct wim_inode *inode, int stream_type,
266 const utf16lechar *stream_name, struct blob_descriptor *blob)
268 if (inode->i_num_streams >= 0xFFFF) {
269 ERROR("Inode has too many streams! Path=\"%"TS"\"",
270 inode_any_full_path(inode));
275 struct wim_inode_stream *streams;
276 struct wim_inode_stream *new_strm;
278 if (inode->i_streams == inode->i_embedded_streams) {
279 if (inode->i_num_streams < ARRAY_LEN(inode->i_embedded_streams)) {
280 streams = inode->i_embedded_streams;
282 streams = MALLOC((inode->i_num_streams + 1) *
283 sizeof(inode->i_streams[0]));
286 memcpy(streams, inode->i_streams,
287 (inode->i_num_streams *
288 sizeof(inode->i_streams[0])));
289 inode->i_streams = streams;
292 streams = REALLOC(inode->i_streams,
293 (inode->i_num_streams + 1) *
294 sizeof(inode->i_streams[0]));
297 inode->i_streams = streams;
299 new_strm = &streams[inode->i_num_streams];
301 memset(new_strm, 0, sizeof(*new_strm));
303 new_strm->stream_type = stream_type;
306 new_strm->stream_name = (utf16lechar *)NO_STREAM_NAME;
309 new_strm->stream_name = utf16le_dup(stream_name);
310 if (!new_strm->stream_name)
314 new_strm->stream_id = inode->i_next_stream_id++;
316 inode_set_stream_blob(inode, new_strm, blob);
318 inode->i_num_streams++;
324 * Replace the data of the specified stream.
327 * The inode containing @strm
329 * The stream whose data needs to be replaced
331 * The buffer of data to assign to the stream
333 * Size of the @data buffer, in bytes
335 * Pointer to the blob table in which data blobs are being indexed
337 * Returns true if successful; false with errno set if unsuccessful.
340 inode_replace_stream_data(struct wim_inode *inode,
341 struct wim_inode_stream *strm,
342 const void *data, size_t size,
343 struct blob_table *blob_table)
345 struct blob_descriptor *new_blob = NULL;
348 new_blob = new_blob_from_data_buffer(data, size, blob_table);
353 inode_replace_stream_blob(inode, strm, new_blob, blob_table);
358 * Add a new stream to the specified inode and assign it the specified data.
361 * The inode to which to add the stream
363 * The type of the stream being added
365 * The name of the stream being added as a null-terminated UTF-16LE string,
366 * or NO_STREAM_NAME if the stream is unnamed
368 * The buffer of data to assign to the new stream
370 * Size of the @data buffer, in bytes
372 * Pointer to the blob table in which data blobs are being indexed
374 * Returns true if successful; false with errno set if unsuccessful.
377 inode_add_stream_with_data(struct wim_inode *inode,
378 int stream_type, const utf16lechar *stream_name,
379 const void *data, size_t size,
380 struct blob_table *blob_table)
382 struct wim_inode_stream *strm;
383 struct blob_descriptor *blob = NULL;
385 strm = inode_add_stream(inode, stream_type, stream_name, NULL);
390 blob = new_blob_from_data_buffer(data, size, blob_table);
391 if (unlikely(!blob)) {
392 inode_remove_stream(inode, strm, blob_table);
397 inode_set_stream_blob(inode, strm, blob);
402 * Remove a stream from the specified inode.
404 * This handles releasing the references to the blob descriptor, if any.
407 inode_remove_stream(struct wim_inode *inode, struct wim_inode_stream *strm,
408 struct blob_table *blob_table)
410 unsigned idx = strm - inode->i_streams;
412 wimlib_assert(idx < inode->i_num_streams);
414 inode_unset_stream_blob(inode, strm, blob_table);
416 destroy_stream(strm);
418 memmove(strm, strm + 1,
419 (inode->i_num_streams - idx - 1) * sizeof(inode->i_streams[0]));
420 inode->i_num_streams--;
423 /* Returns true iff the specified inode has at least one named data stream. */
425 inode_has_named_data_stream(const struct wim_inode *inode)
427 for (unsigned i = 0; i < inode->i_num_streams; i++)
428 if (stream_is_named_data_stream(&inode->i_streams[i]))
434 * Resolve an inode's streams.
436 * For each stream, this replaces the SHA-1 message digest of the blob data with
437 * a pointer to the 'struct blob_descriptor' for the blob. Blob descriptors are
438 * looked up in @table.
440 * If @force is %false:
441 * If any of the needed blobs do not exist in @table, return
442 * WIMLIB_ERR_RESOURCE_NOT_FOUND.
443 * If @force is %true:
444 * If any of the needed blobs do not exist in @table, allocate new blob
445 * descriptors for them and insert them into @table. This does not, of
446 * course, cause the data of these blobs to magically exist, but this is
447 * needed by the code for extraction from a pipe.
449 * Returns 0 on success; WIMLIB_ERR_NOMEM if out of memory; or
450 * WIMLIB_ERR_RESOURCE_NOT_FOUND if @force is %false and at least one blob
451 * referenced by the inode was missing.
454 inode_resolve_streams(struct wim_inode *inode, struct blob_table *table,
457 for (unsigned i = 0; i < inode->i_num_streams; i++) {
458 struct wim_inode_stream *strm = &inode->i_streams[i];
460 if (strm->stream_resolved)
463 const u8 *hash = stream_hash(strm);
464 struct blob_descriptor *blob = NULL;
466 if (!is_zero_hash(hash)) {
467 blob = lookup_blob(table, hash);
470 return blob_not_found_error(inode, hash);
471 blob = new_blob_descriptor();
473 return WIMLIB_ERR_NOMEM;
474 copy_hash(blob->hash, hash);
475 blob_table_insert(table, blob);
478 strm->_stream_blob = blob;
479 strm->stream_resolved = 1;
485 blob_not_found_error(const struct wim_inode *inode, const u8 *hash)
487 if (wimlib_print_errors) {
488 tchar hashstr[SHA1_HASH_STRING_LEN];
490 sprint_hash(hash, hashstr);
492 ERROR("\"%"TS"\": blob not found\n"
493 " SHA-1 message digest of missing blob:\n"
495 inode_any_full_path(inode), hashstr);
497 return WIMLIB_ERR_RESOURCE_NOT_FOUND;
501 * Return the blob descriptor for the specified stream, or NULL if the stream is
502 * empty or its blob is not available in @table.
504 struct blob_descriptor *
505 stream_blob(const struct wim_inode_stream *strm, const struct blob_table *table)
507 if (strm->stream_resolved)
508 return strm->_stream_blob;
510 return lookup_blob(table, strm->_stream_hash);
514 * Return the SHA-1 message digest of the data of the specified stream, or a
515 * void SHA-1 of all zeroes if the specified stream is empty, or NULL if the
516 * specified stream is unhashed. (Most callers ensure the stream cannot be
520 stream_hash(const struct wim_inode_stream *strm)
522 if (!strm->stream_resolved)
523 return strm->_stream_hash;
525 if (!strm->_stream_blob)
528 if (strm->_stream_blob->unhashed)
531 return strm->_stream_blob->hash;
535 * Return the blob descriptor for the unnamed data stream of the inode, or NULL
536 * if the inode does not have an unnamed data stream, the inode's unnamed data
537 * stream is empty, or the blob for the inode's unnamed data stream is not
538 * available in @blob_table.
540 struct blob_descriptor *
541 inode_get_blob_for_unnamed_data_stream(const struct wim_inode *inode,
542 const struct blob_table *blob_table)
544 const struct wim_inode_stream *strm;
546 strm = inode_get_unnamed_data_stream(inode);
550 return stream_blob(strm, blob_table);
553 /* Like inode_get_blob_for_unnamed_data_stream(), but assumes the unnamed data
554 * stream is resolved. */
555 struct blob_descriptor *
556 inode_get_blob_for_unnamed_data_stream_resolved(const struct wim_inode *inode)
558 const struct wim_inode_stream *strm;
560 strm = inode_get_unnamed_data_stream(inode);
564 return stream_blob_resolved(strm);
568 * Return the SHA-1 message digest of the unnamed data stream of the inode, or a
569 * void SHA-1 of all zeroes if the inode does not have an unnamed data stream or
570 * if the inode's unnamed data stream is empty, or NULL if the inode's unnamed
571 * data stream is unhashed. (Most callers ensure the stream cannot be
575 inode_get_hash_of_unnamed_data_stream(const struct wim_inode *inode)
577 const struct wim_inode_stream *strm;
579 strm = inode_get_unnamed_data_stream(inode);
583 return stream_hash(strm);
586 /* Acquire another reference to each blob referenced by this inode. This is
587 * necessary when creating a hard link to this inode.
589 * All streams of the inode must be resolved. */
591 inode_ref_blobs(struct wim_inode *inode)
593 for (unsigned i = 0; i < inode->i_num_streams; i++) {
594 struct blob_descriptor *blob;
596 blob = stream_blob_resolved(&inode->i_streams[i]);
602 /* Release a reference to each blob referenced by this inode. This is necessary
603 * when deleting a hard link to this inode. */
605 inode_unref_blobs(struct wim_inode *inode, struct blob_table *blob_table)
607 for (unsigned i = 0; i < inode->i_num_streams; i++) {
608 struct blob_descriptor *blob;
610 blob = stream_blob(&inode->i_streams[i], blob_table);
612 blob_decrement_refcnt(blob, blob_table);
617 * Given a blob descriptor, return a pointer to the pointer contained in the
618 * stream that references it.
620 * This is only possible for "unhashed" blobs, which are guaranteed to have only
621 * one referencing stream, and that reference is guaranteed to be in a resolved
622 * stream. (It can't be in an unresolved stream, since that would imply the
625 struct blob_descriptor **
626 retrieve_pointer_to_unhashed_blob(struct blob_descriptor *blob)
628 wimlib_assert(blob->unhashed);
630 struct wim_inode *inode = blob->back_inode;
631 for (unsigned i = 0; i < inode->i_num_streams; i++) {
632 if (inode->i_streams[i].stream_id == blob->back_stream_id) {
633 wimlib_assert(inode->i_streams[i]._stream_blob == blob);
634 return &inode->i_streams[i]._stream_blob;