ntfs-3g_apply.c: Do not use i_visited
authorEric Biggers <ebiggers3@gmail.com>
Sun, 31 May 2015 15:43:49 +0000 (10:43 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 5 Jun 2015 03:45:35 +0000 (22:45 -0500)
The number of inodes examined is limited by MAX_OPEN_FILES, and we can
make it faster in the common case by checking i_num_streams.

include/wimlib/inode.h
src/ntfs-3g_apply.c

index 07d1885..2fd9f08 100644 (file)
@@ -129,10 +129,8 @@ struct wim_inode {
        /* Number of dentries that are aliases for this inode.  */
        u32 i_nlink : 30;
 
-       /* Flag used to mark this inode as visited; this is used when visiting
-        * all the inodes in a dentry tree exactly once.  It will be 0 by
-        * default and must be cleared following the tree traversal, even in
-        * error paths.  */
+       /* Flag used by some code to mark this inode as visited.  It will be 0
+        * by default, and it always must be cleared after use.  */
        u32 i_visited : 1;
 
        /* Cached value  */
index 3dcf8d5..8f07746 100644 (file)
@@ -760,28 +760,29 @@ ntfs_3g_cleanup_blob_extract(struct ntfs_3g_apply_ctx *ctx)
 static ntfs_inode *
 ntfs_3g_open_inode(struct wim_inode *inode, struct ntfs_3g_apply_ctx *ctx)
 {
-       ntfs_inode *ni = NULL;
+       ntfs_inode *ni;
 
-       if (inode->i_visited) {
-               for (u32 i = 0; i < ctx->num_open_inodes; i++) {
+       /* If the same blob is being extracted to multiple streams of the same
+        * inode, then we must only open the inode once.  */
+       if (unlikely(inode->i_num_streams > 1)) {
+               for (unsigned i = 0; i < ctx->num_open_inodes; i++) {
                        if (ctx->open_inodes[i]->mft_no == inode->i_mft_no) {
                                ni = ctx->open_inodes[i];
-                               break;
+                               goto have_inode;
                        }
                }
        }
-       if (!ni) {
-               ni = ntfs_inode_open(ctx->vol, inode->i_mft_no);
-               ctx->open_inodes[ctx->num_open_inodes++] = ni;
-               inode->i_visited = 1;
-       }
 
-       if (!ni) {
+       ni = ntfs_inode_open(ctx->vol, inode->i_mft_no);
+       if (unlikely(!ni)) {
                ERROR_WITH_ERRNO("Can't open \"%s\" in NTFS volume",
                                 dentry_full_path(
                                        inode_first_extraction_dentry(inode)));
                return NULL;
        }
+
+have_inode:
+       ctx->open_inodes[ctx->num_open_inodes++] = ni;
        return ni;
 }
 
@@ -811,8 +812,6 @@ ntfs_3g_begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
 out_cleanup:
        ntfs_3g_cleanup_blob_extract(ctx);
 out:
-       for (u32 i = 0; i < blob->out_refcnt; i++)
-               targets[i].inode->i_visited = 0;
        return ret;
 }