]> wimlib.net Git - wimlib/blobdiff - src/inode.c
mount_image.c: add fallback definitions of RENAME_* constants
[wimlib] / src / inode.c
index 4b1b1d3eee8e108b3934ce5c6ba6f026cba7ac32..40fe5679a6a3eeac8f6799ee091ca74dea8b37a5 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /*
- * Copyright (C) 2012, 2013, 2014, 2015 Eric Biggers
+ * Copyright (C) 2012-2018 Eric Biggers
  *
  * This file is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
@@ -21,7 +21,7 @@
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with this file; if not, see http://www.gnu.org/licenses/.
+ * along with this file; if not, see https://www.gnu.org/licenses/.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -56,9 +56,8 @@ new_inode(struct wim_dentry *dentry, bool set_timestamps)
 
        inode->i_security_id = -1;
        /*inode->i_nlink = 0;*/
-       inode->i_not_rpfixed = 1;
-       INIT_LIST_HEAD(&inode->i_list);
-       INIT_LIST_HEAD(&inode->i_dentry);
+       inode->i_rp_flags = WIM_RP_FLAG_NOT_FIXED;
+       INIT_HLIST_HEAD(&inode->i_alias_list);
        inode->i_streams = inode->i_embedded_streams;
        if (set_timestamps) {
                u64 now = now_as_wim_timestamp();
@@ -86,10 +85,8 @@ free_inode(struct wim_inode *inode)
                FREE(inode->i_streams);
        if (inode->i_extra)
                FREE(inode->i_extra);
-       /* HACK: This may instead delete the inode from i_list, but hlist_del()
-        * behaves the same as list_del(). */
-       if (!hlist_unhashed(&inode->i_hlist))
-               hlist_del(&inode->i_hlist);
+       if (!hlist_unhashed(&inode->i_hlist_node))
+               hlist_del(&inode->i_hlist_node);
        FREE(inode);
 }
 
@@ -111,7 +108,7 @@ d_associate(struct wim_dentry *dentry, struct wim_inode *inode)
 {
        wimlib_assert(!dentry->d_inode);
 
-       list_add_tail(&dentry->d_alias, &inode->i_dentry);
+       hlist_add_head(&dentry->d_alias_node, &inode->i_alias_list);
        dentry->d_inode = inode;
        inode->i_nlink++;
 }
@@ -128,7 +125,7 @@ d_disassociate(struct wim_dentry *dentry)
 
        wimlib_assert(inode->i_nlink > 0);
 
-       list_del(&dentry->d_alias);
+       hlist_del(&dentry->d_alias_node);
        dentry->d_inode = NULL;
        inode->i_nlink--;
 
@@ -270,7 +267,7 @@ inode_add_stream(struct wim_inode *inode, int stream_type,
 {
        if (inode->i_num_streams >= 0xFFFF) {
                ERROR("Inode has too many streams! Path=\"%"TS"\"",
-                     inode_first_full_path(inode));
+                     inode_any_full_path(inode));
                errno = EFBIG;
                return NULL;
        }
@@ -345,11 +342,13 @@ inode_replace_stream_data(struct wim_inode *inode,
                          const void *data, size_t size,
                          struct blob_table *blob_table)
 {
-       struct blob_descriptor *new_blob;
+       struct blob_descriptor *new_blob = NULL;
 
-       new_blob = new_blob_from_data_buffer(data, size, blob_table);
-       if (!new_blob)
-               return false;
+       if (size) {
+               new_blob = new_blob_from_data_buffer(data, size, blob_table);
+               if (!new_blob)
+                       return false;
+       }
 
        inode_replace_stream_blob(inode, strm, new_blob, blob_table);
        return true;
@@ -381,16 +380,18 @@ inode_add_stream_with_data(struct wim_inode *inode,
                           struct blob_table *blob_table)
 {
        struct wim_inode_stream *strm;
-       struct blob_descriptor *blob;
+       struct blob_descriptor *blob = NULL;
 
        strm = inode_add_stream(inode, stream_type, stream_name, NULL);
        if (!strm)
                return false;
 
-       blob = new_blob_from_data_buffer(data, size, blob_table);
-       if (!blob) {
-               inode_remove_stream(inode, strm, blob_table);
-               return false;
+       if (size) {
+               blob = new_blob_from_data_buffer(data, size, blob_table);
+               if (unlikely(!blob)) {
+                       inode_remove_stream(inode, strm, blob_table);
+                       return false;
+               }
        }
 
        inode_set_stream_blob(inode, strm, blob);
@@ -480,40 +481,25 @@ inode_resolve_streams(struct wim_inode *inode, struct blob_table *table,
        return 0;
 }
 
-/* Undo the effects of inode_resolve_streams().  */
-void
-inode_unresolve_streams(struct wim_inode *inode)
-{
-       for (unsigned i = 0; i < inode->i_num_streams; i++) {
-
-               if (!inode->i_streams[i].stream_resolved)
-                       continue;
-
-               copy_hash(inode->i_streams[i]._stream_hash,
-                         stream_hash(&inode->i_streams[i]));
-               inode->i_streams[i].stream_resolved = 0;
-       }
-}
-
 int
 blob_not_found_error(const struct wim_inode *inode, const u8 *hash)
 {
        if (wimlib_print_errors) {
-               tchar hashstr[SHA1_HASH_SIZE * 2 + 1];
+               tchar hashstr[SHA1_HASH_STRING_LEN];
 
                sprint_hash(hash, hashstr);
 
                ERROR("\"%"TS"\": blob not found\n"
                      "        SHA-1 message digest of missing blob:\n"
                      "        %"TS"",
-                     inode_first_full_path(inode), hashstr);
+                     inode_any_full_path(inode), hashstr);
        }
        return WIMLIB_ERR_RESOURCE_NOT_FOUND;
 }
 
 /*
- * Return the blob descriptor for the specified stream, or NULL if the blob for
- * the stream is empty or not available.
+ * Return the blob descriptor for the specified stream, or NULL if the stream is
+ * empty or its blob is not available in @table.
  */
 struct blob_descriptor *
 stream_blob(const struct wim_inode_stream *strm, const struct blob_table *table)
@@ -524,22 +510,32 @@ stream_blob(const struct wim_inode_stream *strm, const struct blob_table *table)
                return lookup_blob(table, strm->_stream_hash);
 }
 
-/* Return the SHA-1 message digest of the data of the specified stream, or a
- * void SHA-1 of all zeroes if the specified stream is empty.   */
+/*
+ * Return the SHA-1 message digest of the data of the specified stream, or a
+ * void SHA-1 of all zeroes if the specified stream is empty, or NULL if the
+ * specified stream is unhashed.  (Most callers ensure the stream cannot be
+ * unhashed.)
+ */
 const u8 *
 stream_hash(const struct wim_inode_stream *strm)
 {
-       if (strm->stream_resolved)
-               return strm->_stream_blob ? strm->_stream_blob->hash : zero_hash;
-       else
+       if (!strm->stream_resolved)
                return strm->_stream_hash;
+
+       if (!strm->_stream_blob)
+               return zero_hash;
+
+       if (strm->_stream_blob->unhashed)
+               return NULL;
+
+       return strm->_stream_blob->hash;
 }
 
 /*
  * Return the blob descriptor for the unnamed data stream of the inode, or NULL
- * if the inode does not have an unnamed data stream, the blob for the inode's
- * unnamed data stream is empty, or the blob for the inode's unnamed data stream
- * is not available in @blob_table.
+ * if the inode does not have an unnamed data stream, the inode's unnamed data
+ * stream is empty, or the blob for the inode's unnamed data stream is not
+ * available in @blob_table.
  */
 struct blob_descriptor *
 inode_get_blob_for_unnamed_data_stream(const struct wim_inode *inode,
@@ -571,7 +567,9 @@ inode_get_blob_for_unnamed_data_stream_resolved(const struct wim_inode *inode)
 /*
  * Return the SHA-1 message digest of the unnamed data stream of the inode, or a
  * void SHA-1 of all zeroes if the inode does not have an unnamed data stream or
- * if the inode's unnamed data stream is empty.
+ * if the inode's unnamed data stream is empty, or NULL if the inode's unnamed
+ * data stream is unhashed.  (Most callers ensure the stream cannot be
+ * unhashed.)
  */
 const u8 *
 inode_get_hash_of_unnamed_data_stream(const struct wim_inode *inode)