From: Eric Biggers Date: Sun, 31 May 2015 15:43:49 +0000 (-0500) Subject: ntfs-3g_apply.c: Do not use i_visited X-Git-Tag: v1.8.2~78 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=26a90546f2a8ded51376d631e5a13f3d7a84f8dc ntfs-3g_apply.c: Do not use i_visited 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. --- diff --git a/include/wimlib/inode.h b/include/wimlib/inode.h index 07d1885f..2fd9f083 100644 --- a/include/wimlib/inode.h +++ b/include/wimlib/inode.h @@ -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 */ diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index 3dcf8d53..8f077467 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -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; }