From: Eric Biggers Date: Tue, 20 Nov 2012 07:15:36 +0000 (-0600) Subject: Implement soft delete X-Git-Tag: v1.2.0~26 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=9368708ff94a8da723874c098d24fefcd5866207 Implement soft delete --- diff --git a/doc/imagex-delete.1.in b/doc/imagex-delete.1.in index 1d8c3176..1505b9bd 100644 --- a/doc/imagex-delete.1.in +++ b/doc/imagex-delete.1.in @@ -18,9 +18,10 @@ command to show what images a WIM file contains. .SH NOTES -The WIM file is rebuilt with all unnecessary file data removed. This is -different from Microsoft's imagex.exe, which only will delete the directory tree -metadata and XML data for this operation. +By default, the WIM file is rebuilt with all unnecessary file data removed. +This is different from Microsoft's imagex.exe, which only will delete the +directory tree metadata and XML data for this operation. (See the \fB--soft\fR +option for the other kind of delete). Also, unlike imagex.exe, it is legal to delete all the images from a WIM and have a WIM with 0 images, although such a file wouldn't be very useful. @@ -34,6 +35,17 @@ When reading \fIWIMFILE\fR, verify its integrity if the integrity table is present; additionally, when rewriting \fIWIMFILE\fR after the specified image was deleted, write an integrity table. If this option is not specified, no integrity table is included in the new WIM file, even if there was one before. +.TP 6 +\fB--soft\fR +Perform a "soft delete". Specifying this flag overrides the default behavior of +rebuilding the entire WIM after deleting an image. Instead, only minimal +changes to correctly remove the image from the WIM will be taken. In +particular, all streams will be left alone, even if they are no longer +referenced. This is probably not what you want, because almost no space will be +saved by deleting an image in this way. + +You may use \fBimagex optimize\fR to delete unreferenced streams from a WIM that +has had images soft-deleted from it. .SH EXAMPLES Delete the first image from 'boot.wim': diff --git a/programs/imagex.c b/programs/imagex.c index 4e5765f6..d047130b 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -77,7 +77,7 @@ static const char *usage_strings[] = { " [--flags EDITION_ID] [--verbose] [--dereference]\n" " [--config=FILE] [--threads=NUM_THREADS]\n", [DELETE] = -"imagex delete WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--check]\n", +"imagex delete WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--check] [--soft]\n", [DIR] = "imagex dir WIMFILE (IMAGE_NUM | IMAGE_NAME | all)\n", [EXPORT] = @@ -134,6 +134,7 @@ static const struct option capture_or_append_options[] = { }; static const struct option delete_options[] = { {"check", no_argument, NULL, 'c'}, + {"soft", no_argument, NULL, 's'}, {NULL, 0, NULL, 0}, }; @@ -675,6 +676,9 @@ static int imagex_delete(int argc, const char **argv) open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY; write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; break; + case 's': + write_flags |= WIMLIB_WRITE_FLAG_SOFT_DELETE; + break; default: usage(DELETE); return -1; diff --git a/src/wim.c b/src/wim.c index 0507e477..f40915fd 100644 --- a/src/wim.c +++ b/src/wim.c @@ -132,7 +132,8 @@ static int append_metadata_resource_entry(struct lookup_table_entry *lte, if (lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) { if (w->current_image == w->hdr.image_count) { - ERROR("Expected only %u images, but found more", + ERROR("The WIM header says there are %u images in the WIM,\n" + " but we found more metadata resources than this", w->hdr.image_count); ret = WIMLIB_ERR_IMAGE_COUNT; } else { diff --git a/src/wimlib.h b/src/wimlib.h index 6c99ffdb..ce079ce4 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -284,6 +284,15 @@ enum wim_compression_type { * same. Instead, recompress them. */ #define WIMLIB_WRITE_FLAG_RECOMPRESS 0x00000020 +/** Specifying this flag overrides the default behavior of wimlib_overwrite() + * after one or more calls to wimlib_delete_image(), which is to rebuild the + * entire WIM. If you specifiy this flag to wimlib_overwrite() instead, only + * minimal changes to correctly remove the image from the WIM will be taken. In + * particular, all streams will be left alone, even if they are no longer + * references. This is probably not what you want, because almost no space will + * be spaced by deleting an image in this way. */ +#define WIMLIB_WRITE_FLAG_SOFT_DELETE 0x00000040 + /** Mark the image being added as the bootable image of the WIM. */ #define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000001 @@ -1143,8 +1152,9 @@ extern int wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads); /** - * This function is deprecated; call wimlib_overwrite() without the - * WIMLIB_WRITE_FLAG_REBUILD flag instead. + * This function is deprecated; call wimlib_overwrite() instead. + * (wimlib_overwrite() no longer rebuilds the full WIM unless it has to or is + * specified explicitly with ::WIMLIB_WRITE_FLAG_REBUILD) */ extern int wimlib_overwrite_xml_and_header(WIMStruct *wim, int write_flags); diff --git a/src/write.c b/src/write.c index a9cb6aec..1eb695d5 100644 --- a/src/write.c +++ b/src/write.c @@ -1570,6 +1570,8 @@ WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path, if (!w || !path) return WIMLIB_ERR_INVALID_PARAM; + write_flags &= WIMLIB_WRITE_MASK_PUBLIC; + if (image != WIM_ALL_IMAGES && (image < 1 || image > w->hdr.image_count)) return WIMLIB_ERR_INVALID_IMAGE; @@ -1746,9 +1748,9 @@ static int overwrite_wim_inplace(WIMStruct *w, int write_flags, if (ret != 0) return ret; - if (modified_image_idx == w->hdr.image_count) { - /* If no images are modified, a new lookup table does not need - * to be written. */ + if (modified_image_idx == w->hdr.image_count && !w->deletion_occurred) { + /* If no images have been modified and no images have been + * deleted, a new lookup table does not need to be written. */ wimlib_assert(list_empty(&stream_list)); old_wim_end = w->hdr.lookup_table_res_entry.offset + w->hdr.lookup_table_res_entry.size; @@ -1877,7 +1879,9 @@ WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags, return WIMLIB_ERR_SPLIT_UNSUPPORTED; } - if (!w->deletion_occurred && !(write_flags & WIMLIB_WRITE_FLAG_REBUILD)) { + if ((!w->deletion_occurred || (write_flags & WIMLIB_WRITE_FLAG_SOFT_DELETE)) + && !(write_flags & WIMLIB_WRITE_FLAG_REBUILD)) + { int i, modified_image_idx; for (i = 0; i < w->hdr.image_count && !w->image_metadata[i].modified; i++) ;