e2image: only skip writing zero blocks when writing to a new file
The e2image progam was originally intended to create image files.
However, some people have started using e2image to copy a file system
from one block device to another, since it is more efficient than
using dd because it only copies the blocks which are in use. If we
are doing this, however, we must not skip writing blocks which are all
zero in the source device, since they may not be zero in the
destination device.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: Phillip Susi <psusi@ubuntu.com>
diff --git a/lib/ext2fs/e2image.h b/lib/ext2fs/e2image.h
index 5537980..53b20cc 100644
--- a/lib/ext2fs/e2image.h
+++ b/lib/ext2fs/e2image.h
@@ -12,15 +12,6 @@
* %End-Header%
*/
-/* Image types */
-#define E2IMAGE_RAW 1
-#define E2IMAGE_QCOW2 2
-
-/* Image flags */
-#define E2IMAGE_INSTALL_FLAG 1
-#define E2IMAGE_SCRAMBLE_FLAG 2
-#define E2IMAGE_IS_QCOW2_FLAG 4
-
struct ext2_image_hdr {
__u32 magic_number; /* This must be EXT2_ET_MAGIC_E2IMAGE */
char magic_descriptor[16]; /* "Ext2 Image 1.0", w/ null padding */
diff --git a/misc/e2image.c b/misc/e2image.c
index 4d9868c..67dd3e0 100644
--- a/misc/e2image.c
+++ b/misc/e2image.c
@@ -50,6 +50,15 @@
#define QCOW_OFLAG_COPIED (1LL << 63)
+/* Image types */
+#define E2IMAGE_RAW 1
+#define E2IMAGE_QCOW2 2
+
+/* Image flags */
+#define E2IMAGE_INSTALL_FLAG 1
+#define E2IMAGE_SCRAMBLE_FLAG 2
+#define E2IMAGE_IS_QCOW2_FLAG 4
+#define E2IMAGE_CHECK_ZERO_FLAG 8
static const char * program_name = "e2image";
static char * device_name = NULL;
@@ -495,7 +504,7 @@
signal (SIGINT, SIG_DFL);
}
-static void output_meta_data_blocks(ext2_filsys fs, int fd)
+static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
{
errcode_t retval;
blk64_t blk;
@@ -607,7 +616,8 @@
if (scramble_block_map &&
ext2fs_test_block_bitmap2(scramble_block_map, blk))
scramble_dir_block(fs, blk, buf);
- if ((fd != 1) && check_zero_block(buf, fs->blocksize))
+ if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
+ check_zero_block(buf, fs->blocksize))
goto sparse_write;
if (sparse)
seek_relative(fd, sparse);
@@ -1291,7 +1301,7 @@
if (type & E2IMAGE_QCOW2)
output_qcow2_meta_data_blocks(fs, fd);
else
- output_meta_data_blocks(fs, fd);
+ output_meta_data_blocks(fs, fd, flags);
ext2fs_free_mem(&block_buf);
ext2fs_close_inode_scan(scan);
@@ -1516,6 +1526,8 @@
if (img_type != E2IMAGE_RAW)
o_flags |= O_TRUNC;
+ if (access(image_fn, F_OK) != 0)
+ flags |= E2IMAGE_CHECK_ZERO_FLAG;
fd = ext2fs_open_file(image_fn, o_flags, 0600);
if (fd < 0) {
com_err(program_name, errno,