From: Eric Biggers Date: Sat, 2 May 2015 16:35:59 +0000 (-0500) Subject: NTFS-3g capture: use reference-counted NTFS volumes X-Git-Tag: v1.8.1~31 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=1fcf9333676be806716535d01b38722ee53d52e9 NTFS-3g capture: use reference-counted NTFS volumes This avoids the hack of storing the NTFS volume in 'struct wim_image_metadata'. --- diff --git a/include/wimlib.h b/include/wimlib.h index 712202d4..2dcbd12d 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -2564,15 +2564,9 @@ wimlib_add_image(WIMStruct *wim, * capture for full details on how this mode works. * * In addition to the error codes that wimlib_add_image() can return, - * wimlib_add_image_multisource() can return ::WIMLIB_ERR_INVALID_OVERLAY - * when trying to overlay a non-directory on a directory or when otherwise - * trying to overlay multiple conflicting files to the same location in the WIM - * image. It will also return ::WIMLIB_ERR_INVALID_PARAM if - * ::WIMLIB_ADD_FLAG_NTFS was specified in @p add_flags but there - * was not exactly one capture source with the target being the root directory. - * (In this respect, there is no advantage to using - * wimlib_add_image_multisource() instead of wimlib_add_image() when requesting - * NTFS mode.) + * wimlib_add_image_multisource() can return ::WIMLIB_ERR_INVALID_OVERLAY when + * trying to overlay a non-directory on a directory or when otherwise trying to + * overlay multiple conflicting files to the same location in the WIM image. */ extern int wimlib_add_image_multisource(WIMStruct *wim, @@ -4258,12 +4252,9 @@ wimlib_unmount_image_with_progress(const wimlib_tchar *dir, * Attempted to perform an add command that conflicted with previously * existing files in the WIM when an overlay was attempted. * @retval ::WIMLIB_ERR_INVALID_PARAM - * An unknown operation type was specified in the update commands; or, - * attempted to execute an add command where ::WIMLIB_ADD_FLAG_NTFS was set - * in the @p add_flags, but the same image had previously already been - * added from an NTFS volume; or, both ::WIMLIB_ADD_FLAG_RPFIX and - * ::WIMLIB_ADD_FLAG_NORPFIX were specified in the @p add_flags for one add - * command; or, ::WIMLIB_ADD_FLAG_NTFS or ::WIMLIB_ADD_FLAG_RPFIX were + * An unknown operation type was specified in the update commands; or, both + * ::WIMLIB_ADD_FLAG_RPFIX and ::WIMLIB_ADD_FLAG_NORPFIX were specified in + * the @p add_flags for one add command; or ::WIMLIB_ADD_FLAG_RPFIX were * specified in the @p add_flags for an add command in which @p * wim_target_path was not the root directory of the WIM image. * @retval ::WIMLIB_ERR_INVALID_REPARSE_DATA diff --git a/include/wimlib/blob_table.h b/include/wimlib/blob_table.h index 672dedf5..556187e8 100644 --- a/include/wimlib/blob_table.h +++ b/include/wimlib/blob_table.h @@ -35,9 +35,8 @@ enum blob_location { #ifdef WITH_NTFS_3G /* The blob's data is available as the contents of an NTFS attribute - * accessible through libntfs-3g. The attribute is identified by - * volume, path to an inode, attribute name, and attribute type. - * @ntfs_loc points to a structure containing this information. */ + * accessible through libntfs-3g. @ntfs_loc points to a structure which + * identifies the attribute. */ BLOB_IN_NTFS_VOLUME, #endif diff --git a/include/wimlib/capture.h b/include/wimlib/capture.h index 7b352dc5..e41e1b0f 100644 --- a/include/wimlib/capture.h +++ b/include/wimlib/capture.h @@ -42,10 +42,6 @@ struct capture_params { /* Flags that affect the capture operation (WIMLIB_ADD_FLAG_*) */ int add_flags; - /* Extra argument; set to point to a pointer to the ntfs_volume for - * libntfs-3g capture. */ - void *extra_arg; - /* If non-NULL, the user-supplied progress function. */ wimlib_progress_func_t progfunc; void *progctx; diff --git a/include/wimlib/metadata.h b/include/wimlib/metadata.h index cb456bc4..00647a1c 100644 --- a/include/wimlib/metadata.h +++ b/include/wimlib/metadata.h @@ -5,10 +5,6 @@ #include "wimlib/types.h" #include "wimlib/wim.h" -#ifdef WITH_NTFS_3G -struct _ntfs_volume; -#endif - /* Metadata for a WIM image */ struct wim_image_metadata { @@ -39,10 +35,6 @@ struct wim_image_metadata { * the WIM file. If this is the case, the memory for the dentry tree * should not be freed when switching to a different WIM image. */ u8 modified : 1; - -#ifdef WITH_NTFS_3G - struct _ntfs_volume *ntfs_vol; -#endif }; /* Retrieve the metadata of the image in @wim currently selected with diff --git a/include/wimlib/ntfs_3g.h b/include/wimlib/ntfs_3g.h index 3d92dffc..2641801f 100644 --- a/include/wimlib/ntfs_3g.h +++ b/include/wimlib/ntfs_3g.h @@ -1,23 +1,13 @@ #ifndef _WIMLIB_NTFS_3G_H #define _WIMLIB_NTFS_3G_H +#ifdef WITH_NTFS_3G + #include "wimlib/callback.h" #include "wimlib/types.h" struct blob_descriptor; -struct _ntfs_volume; - -#ifdef WITH_NTFS_3G -struct _ntfs_volume; -struct ntfs_location { - struct _ntfs_volume *ntfs_vol; - u64 mft_no; - utf16lechar *attr_name; - unsigned attr_name_nchars; - unsigned attr_type; - u64 sort_key; -}; -#endif +struct ntfs_location; extern void libntfs3g_global_init(void); @@ -26,7 +16,16 @@ extern int read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size, consume_data_callback_t cb, void *cb_ctx); +extern struct ntfs_location * +clone_ntfs_location(const struct ntfs_location *loc); + +extern void +free_ntfs_location(struct ntfs_location *loc); + extern int -do_ntfs_umount(struct _ntfs_volume *vol); +cmp_ntfs_locations(const struct ntfs_location *loc1, + const struct ntfs_location *loc2); + +#endif /* WITH_NTFS_3G */ -#endif +#endif /* _WIMLIB_NTFS_3G_H */ diff --git a/src/blob_table.c b/src/blob_table.c index 0ddd13ad..1d87a717 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -138,18 +138,9 @@ clone_blob_descriptor(const struct blob_descriptor *old) break; #ifdef WITH_NTFS_3G case BLOB_IN_NTFS_VOLUME: - if (old->ntfs_loc) { - new->ntfs_loc = memdup(old->ntfs_loc, - sizeof(struct ntfs_location)); - if (new->ntfs_loc == NULL) - goto out_free; - if (new->ntfs_loc->attr_name != NULL) { - new->ntfs_loc->attr_name = - utf16le_dup(new->ntfs_loc->attr_name); - if (new->ntfs_loc->attr_name == NULL) - goto out_free; - } - } + new->ntfs_loc = clone_ntfs_location(old->ntfs_loc); + if (!new->ntfs_loc) + goto out_free; break; #endif } @@ -186,14 +177,10 @@ blob_release_location(struct blob_descriptor *blob) break; #ifdef WITH_NTFS_3G case BLOB_IN_NTFS_VOLUME: - if (blob->ntfs_loc) { - FREE(blob->ntfs_loc->attr_name); - FREE(blob->ntfs_loc); - } + if (blob->ntfs_loc) + free_ntfs_location(blob->ntfs_loc); break; #endif - default: - break; } } @@ -448,7 +435,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) return tstrcmp(blob1->file_on_disk, blob2->file_on_disk); #ifdef WITH_NTFS_3G case BLOB_IN_NTFS_VOLUME: - return cmp_u64(blob1->ntfs_loc->sort_key, blob2->ntfs_loc->sort_key); + return cmp_ntfs_locations(blob1->ntfs_loc, blob2->ntfs_loc); #endif default: /* No additional sorting order defined for this resource diff --git a/src/ntfs-3g_capture.c b/src/ntfs-3g_capture.c index c0bd9076..ab20511c 100644 --- a/src/ntfs-3g_capture.c +++ b/src/ntfs-3g_capture.c @@ -48,6 +48,39 @@ #include "wimlib/reparse.h" #include "wimlib/security.h" +/* A reference-counted NTFS volume than is automatically unmounted when the + * reference count reaches 0 */ +struct ntfs_volume_wrapper { + ntfs_volume *vol; + size_t refcnt; +}; + +/* Description of where data is located in an NTFS volume */ +struct ntfs_location { + struct ntfs_volume_wrapper *volume; + u64 mft_no; + utf16lechar *attr_name; + unsigned attr_name_nchars; + unsigned attr_type; + u64 sort_key; +}; + +static struct ntfs_volume_wrapper * +get_ntfs_volume(struct ntfs_volume_wrapper *volume) +{ + volume->refcnt++; + return volume; +} + +static void +put_ntfs_volume(struct ntfs_volume_wrapper *volume) +{ + if (--volume->refcnt == 0) { + ntfs_umount(volume->vol, FALSE); + FREE(volume); + } +} + static inline const ntfschar * attr_record_name(const ATTR_RECORD *record) { @@ -76,7 +109,7 @@ read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size, consume_data_callback_t cb, void *cb_ctx) { const struct ntfs_location *loc = blob->ntfs_loc; - ntfs_volume *vol = loc->ntfs_vol; + ntfs_volume *vol = loc->volume->vol; ntfs_inode *ni; ntfs_attr *na; s64 pos; @@ -123,6 +156,41 @@ out: return ret; } +void +free_ntfs_location(struct ntfs_location *loc) +{ + put_ntfs_volume(loc->volume); + FREE(loc->attr_name); + FREE(loc); +} + +struct ntfs_location * +clone_ntfs_location(const struct ntfs_location *loc) +{ + struct ntfs_location *new = memdup(loc, sizeof(*loc)); + if (!new) + goto err0; + if (loc->attr_name) { + new->attr_name = utf16le_dup(loc->attr_name); + if (!new->attr_name) + goto err1; + } + new->volume = get_ntfs_volume(loc->volume); + return new; + +err1: + FREE(new); +err0: + return NULL; +} + +int +cmp_ntfs_locations(const struct ntfs_location *loc1, + const struct ntfs_location *loc2) +{ + return cmp_u64(loc1->sort_key, loc2->sort_key); +} + static int read_reparse_tag(ntfs_inode *ni, struct ntfs_location *loc, u32 *reparse_tag_ret) @@ -199,7 +267,7 @@ scan_ntfs_attr(struct wim_inode *inode, const char *path, size_t path_len, struct list_head *unhashed_blobs, - ntfs_volume *vol, + struct ntfs_volume_wrapper *volume, ATTR_TYPES type, const ATTR_RECORD *record) { @@ -236,7 +304,7 @@ scan_ntfs_attr(struct wim_inode *inode, blob->blob_location = BLOB_IN_NTFS_VOLUME; blob->size = data_size; - blob->ntfs_loc->ntfs_vol = vol; + blob->ntfs_loc->volume = get_ntfs_volume(volume); blob->ntfs_loc->attr_type = type; blob->ntfs_loc->mft_no = ni->mft_no; @@ -293,7 +361,7 @@ scan_ntfs_attrs_with_type(struct wim_inode *inode, char *path, size_t path_len, struct list_head *unhashed_blobs, - ntfs_volume *vol, + struct ntfs_volume_wrapper *volume, ATTR_TYPES type) { ntfs_attr_search_ctx *actx; @@ -316,7 +384,7 @@ scan_ntfs_attrs_with_type(struct wim_inode *inode, path, path_len, unhashed_blobs, - vol, + volume, type, actx->attr); if (ret) @@ -455,7 +523,7 @@ struct readdir_ctx { char *path; size_t path_len; struct dos_name_map *dos_name_map; - ntfs_volume *vol; + struct ntfs_volume_wrapper *volume; struct capture_params *params; int ret; }; @@ -466,7 +534,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p, char *path, size_t path_len, int name_type, - ntfs_volume *ntfs_vol, + struct ntfs_volume_wrapper *volume, struct capture_params *params); static int @@ -512,7 +580,7 @@ wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, /* Open the inode for this directory entry and recursively capture the * directory tree rooted at it */ - ntfs_inode *ni = ntfs_inode_open(ctx->vol, mref); + ntfs_inode *ni = ntfs_inode_open(ctx->volume->vol, mref); if (!ni) { /* XXX This used to be treated as an error, but NTFS-3g seemed * to be unable to read some inodes on a Windows 8 image for @@ -530,7 +598,7 @@ wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, child = NULL; ret = build_dentry_tree_ntfs_recursive(&child, ni, ctx->path, path_len, name_type, - ctx->vol, ctx->params); + ctx->volume, ctx->params); path_len -= mbs_name_nbytes + 1; if (child) dentry_add_child(ctx->parent, child); @@ -550,7 +618,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, char *path, size_t path_len, int name_type, - ntfs_volume *vol, + struct ntfs_volume_wrapper *volume, struct capture_params *params) { u32 attributes; @@ -611,7 +679,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, /* Scan the reparse point stream. */ ret = scan_ntfs_attrs_with_type(inode, ni, path, path_len, params->unhashed_blobs, - vol, AT_REPARSE_POINT); + volume, AT_REPARSE_POINT); if (ret) goto out; } @@ -623,7 +691,8 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, * points) can have an unnamed data stream as well as named data * streams. */ ret = scan_ntfs_attrs_with_type(inode, ni, path, path_len, - params->unhashed_blobs, vol, AT_DATA); + params->unhashed_blobs, + volume, AT_DATA); if (ret) goto out; @@ -637,7 +706,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, .path = path, .path_len = path_len, .dos_name_map = &dos_name_map, - .vol = vol, + .volume = volume, .params = params, .ret = 0, }; @@ -680,7 +749,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, /* Get security descriptor */ memset(&sec_ctx, 0, sizeof(sec_ctx)); - sec_ctx.vol = vol; + sec_ctx.vol = volume->vol; errno = 0; sd = _sd; @@ -728,36 +797,31 @@ out: return ret; } - -int -do_ntfs_umount(struct _ntfs_volume *vol) -{ - DEBUG("Unmounting NTFS volume"); - if (ntfs_umount(vol, FALSE)) - return WIMLIB_ERR_NTFS_3G; - else - return 0; -} - int build_dentry_tree_ntfs(struct wim_dentry **root_p, const char *device, struct capture_params *params) { + struct ntfs_volume_wrapper *volume; ntfs_volume *vol; ntfs_inode *root_ni; + char *path; int ret; + volume = MALLOC(sizeof(struct ntfs_volume_wrapper)); + if (!volume) + return WIMLIB_ERR_NOMEM; + DEBUG("Mounting NTFS volume `%s' read-only", device); -/* NTFS-3g 2013 renamed the "read-only" mount flag from MS_RDONLY to - * NTFS_MNT_RDONLY. - * - * Unfortunately we can't check for defined(NTFS_MNT_RDONLY) because - * NTFS_MNT_RDONLY is an enumerated constant. Also, the NTFS-3g headers don't - * seem to contain any explicit version information. So we have to rely on a - * test done at configure time to detect whether NTFS_MNT_RDONLY should be used. - * */ + /* NTFS-3g 2013 renamed the "read-only" mount flag from MS_RDONLY to + * NTFS_MNT_RDONLY. + * + * Unfortunately we can't check for defined(NTFS_MNT_RDONLY) because + * NTFS_MNT_RDONLY is an enumerated constant. Also, the NTFS-3g headers + * don't seem to contain any explicit version information. So we have + * to rely on a test done at configure time to detect whether + * NTFS_MNT_RDONLY should be used. */ #ifdef HAVE_NTFS_MNT_RDONLY /* NTFS-3g 2013 */ vol = ntfs_mount(device, NTFS_MNT_RDONLY); @@ -770,8 +834,13 @@ build_dentry_tree_ntfs(struct wim_dentry **root_p, if (!vol) { ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s' read-only", device); + FREE(volume); return WIMLIB_ERR_NTFS_3G; } + + volume->vol = vol; + volume->refcnt = 1; + ntfs_open_secure(vol); /* We don't want to capture the special NTFS files such as $Bitmap. Not @@ -785,40 +854,29 @@ build_dentry_tree_ntfs(struct wim_dentry **root_p, ERROR_WITH_ERRNO("Failed to open root inode of NTFS volume " "`%s'", device); ret = WIMLIB_ERR_NTFS_3G; - goto out; + goto out_put_ntfs_volume; } /* Currently we assume that all the paths fit into this length and there * is no check for overflow. */ - char *path = MALLOC(32768); + path = MALLOC(32768); if (!path) { - ERROR("Could not allocate memory for NTFS pathname"); ret = WIMLIB_ERR_NOMEM; - goto out_cleanup; + goto out_close_root_ni; } path[0] = '/'; path[1] = '\0'; ret = build_dentry_tree_ntfs_recursive(root_p, root_ni, path, 1, - FILE_NAME_POSIX, vol, params); -out_cleanup: + FILE_NAME_POSIX, volume, params); FREE(path); +out_close_root_ni: ntfs_inode_close(root_ni); -out: +out_put_ntfs_volume: ntfs_index_ctx_put(vol->secure_xsii); ntfs_index_ctx_put(vol->secure_xsdh); ntfs_inode_close(vol->secure_ni); - - if (ret) { - if (do_ntfs_umount(vol)) { - ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%s'", - device); - } - } else { - /* We need to leave the NTFS volume mounted so that we can read - * the NTFS files again when we are actually writing the WIM */ - *(ntfs_volume**)params->extra_arg = vol; - } + put_ntfs_volume(volume); return ret; } #endif /* WITH_NTFS_3G */ diff --git a/src/resource.c b/src/resource.c index 2c04882e..fb1047e0 100644 --- a/src/resource.c +++ b/src/resource.c @@ -36,6 +36,7 @@ #include "wimlib/endianness.h" #include "wimlib/error.h" #include "wimlib/file_io.h" +#include "wimlib/ntfs_3g.h" /* for read_ntfs_attribute_prefix() */ #include "wimlib/resource.h" #include "wimlib/sha1.h" #include "wimlib/wim.h" @@ -45,12 +46,6 @@ # include "wimlib/win32.h" #endif -#ifdef WITH_NTFS_3G -/* for read_ntfs_attribute_prefix() */ -# include "wimlib/ntfs_3g.h" -#endif - - /* * Compressed WIM resources * diff --git a/src/update_image.c b/src/update_image.c index b2eceecf..f36f9ecf 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -62,9 +62,6 @@ #include "wimlib/endianness.h" #include "wimlib/error.h" #include "wimlib/metadata.h" -#ifdef WITH_NTFS_3G -# include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */ -#endif #include "wimlib/paths.h" #include "wimlib/progress.h" #include "wimlib/xml.h" @@ -792,10 +789,6 @@ execute_add_command(struct update_command_journal *j, struct capture_params params; struct capture_config config; capture_tree_t capture_tree = platform_default_capture_tree; -#ifdef WITH_NTFS_3G - struct _ntfs_volume *ntfs_vol = NULL; -#endif - void *extra_arg = NULL; struct wim_dentry *branch; add_flags = add_cmd->add.add_flags; @@ -809,15 +802,8 @@ execute_add_command(struct update_command_journal *j, memset(¶ms, 0, sizeof(params)); #ifdef WITH_NTFS_3G - if (add_flags & WIMLIB_ADD_FLAG_NTFS) { + if (add_flags & WIMLIB_ADD_FLAG_NTFS) capture_tree = build_dentry_tree_ntfs; - extra_arg = &ntfs_vol; - if (wim_get_current_image_metadata(wim)->ntfs_vol != NULL) { - ERROR("NTFS volume already set"); - ret = WIMLIB_ERR_INVALID_PARAM; - goto out; - } - } #endif ret = get_capture_config(config_file, &config, @@ -831,7 +817,6 @@ execute_add_command(struct update_command_journal *j, params.sd_set = sd_set; params.config = &config; params.add_flags = add_flags; - params.extra_arg = extra_arg; params.progfunc = wim->progfunc; params.progctx = wim->progctx; @@ -852,7 +837,7 @@ execute_add_command(struct update_command_journal *j, ¶ms.progress, params.progctx); if (ret) { free_dentry_tree(branch, wim->blob_table); - goto out_cleanup_after_capture; + goto out_destroy_config; } if (WIMLIB_IS_WIM_ROOT_PATH(wim_target_path) && @@ -861,13 +846,13 @@ execute_add_command(struct update_command_journal *j, ERROR("\"%"TS"\" is not a directory!", fs_source_path); ret = WIMLIB_ERR_NOTDIR; free_dentry_tree(branch, wim->blob_table); - goto out_cleanup_after_capture; + goto out_destroy_config; } ret = attach_branch(branch, wim_target_path, j, add_flags, params.progfunc, params.progctx); if (ret) - goto out_cleanup_after_capture; + goto out_destroy_config; if (config_file && (add_flags & WIMLIB_ADD_FLAG_WIMBOOT) && WIMLIB_IS_WIM_ROOT_PATH(wim_target_path)) @@ -881,23 +866,14 @@ execute_add_command(struct update_command_journal *j, * /Windows/System32/WimBootCompress.ini in the WIM image. */ ret = platform_default_capture_tree(&branch, config_file, ¶ms); if (ret) - goto out_cleanup_after_capture; + goto out_destroy_config; ret = attach_branch(branch, wimboot_cfgfile, j, 0, NULL, NULL); if (ret) - goto out_cleanup_after_capture; + goto out_destroy_config; } -#ifdef WITH_NTFS_3G - wim_get_current_image_metadata(wim)->ntfs_vol = ntfs_vol; -#endif ret = 0; - goto out_destroy_config; -out_cleanup_after_capture: -#ifdef WITH_NTFS_3G - if (ntfs_vol) - do_ntfs_umount(ntfs_vol); -#endif out_destroy_config: destroy_capture_config(&config); out: @@ -1252,9 +1228,8 @@ check_add_command(struct wimlib_update_command *cmd, #ifndef WITH_NTFS_3G if (add_flags & WIMLIB_ADD_FLAG_NTFS) { - ERROR("wimlib was compiled without support for NTFS-3g, so\n" - " we cannot capture a WIM image directly " - "from an NTFS volume"); + ERROR("NTFS-3g capture mode is unsupported because wimlib " + "was compiled --without-ntfs-3g"); return WIMLIB_ERR_UNSUPPORTED; } #endif @@ -1299,12 +1274,6 @@ check_add_command(struct wimlib_update_command *cmd, } if (!is_entire_image) { - if (add_flags & WIMLIB_ADD_FLAG_NTFS) { - ERROR("Cannot add directly from an NTFS volume " - "when not capturing a full image!"); - return WIMLIB_ERR_INVALID_PARAM; - } - if (add_flags & WIMLIB_ADD_FLAG_RPFIX) { ERROR("Cannot do reparse point fixups when " "not capturing a full image!"); diff --git a/src/wim.c b/src/wim.c index a82bd479..f06f25f1 100644 --- a/src/wim.c +++ b/src/wim.c @@ -40,9 +40,7 @@ #include "wimlib/file_io.h" #include "wimlib/integrity.h" #include "wimlib/metadata.h" -#ifdef WITH_NTFS_3G -# include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */ -#endif +#include "wimlib/ntfs_3g.h" /* for libntfs3g_global_init() */ #include "wimlib/security.h" #include "wimlib/wim.h" #include "wimlib/xml.h" @@ -218,12 +216,6 @@ destroy_image_metadata(struct wim_image_metadata *imd, } INIT_LIST_HEAD(&imd->unhashed_blobs); INIT_HLIST_HEAD(&imd->inode_list); -#ifdef WITH_NTFS_3G - if (imd->ntfs_vol) { - do_ntfs_umount(imd->ntfs_vol); - imd->ntfs_vol = NULL; - } -#endif } void