From ddd3a8a329cdc2c73c68db273bf37a5c725f3e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Tue, 11 Mar 2014 09:54:53 +0100 Subject: [PATCH] Reset the output file to favour appending to image in ntfsclone When ntfsclone'ing to a file, the target file was truncated to the volume size. This is not useful on file systems which support sparse files. In the case of ntfs-3g this leads to prevent optimizations specific to appending data. So when a sparse output file is detected, it is emptied to benefit from subsequent appending of data. --- include/ntfs-3g/device_io.h | 2 +- ntfsprogs/ntfsclone.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/ntfs-3g/device_io.h b/include/ntfs-3g/device_io.h index 24f8d9bf..66ad2439 100644 --- a/include/ntfs-3g/device_io.h +++ b/include/ntfs-3g/device_io.h @@ -72,7 +72,7 @@ struct hd_geometry { /* A few useful functions */ int ntfs_win32_set_sparse(int); int ntfs_win32_ftruncate(int fd, s64 size); -int ntfs_win32_device_ftruncate(struct ntfs_device*, s64); +int ntfs_device_win32_ftruncate(struct ntfs_device*, s64); #endif /* HAVE_WINDOWS_H */ diff --git a/ntfsprogs/ntfsclone.c b/ntfsprogs/ntfsclone.c index 481ebf34..33d76d8a 100644 --- a/ntfsprogs/ntfsclone.c +++ b/ntfsprogs/ntfsclone.c @@ -3,7 +3,7 @@ * * Copyright (c) 2003-2006 Szabolcs Szakacsits * Copyright (c) 2004-2006 Anton Altaparmakov - * Copyright (c) 2010-2013 Jean-Pierre Andre + * Copyright (c) 2010-2014 Jean-Pierre Andre * Special image format support copyright (c) 2004 Per Olofsson * * Clone NTFS data and/or metadata to a sparse file, image, device or stdout. @@ -388,7 +388,7 @@ static void version(void) "Efficiently clone, image, restore or rescue an NTFS Volume.\n\n" "Copyright (c) 2003-2006 Szabolcs Szakacsits\n" "Copyright (c) 2004-2006 Anton Altaparmakov\n" - "Copyright (c) 2010-2013 Jean-Pierre Andre\n\n"); + "Copyright (c) 2010-2014 Jean-Pierre Andre\n\n"); fprintf(stderr, "%s\n%s%s", ntfs_gpl, ntfs_bugs, ntfs_home); exit(1); } @@ -2299,6 +2299,27 @@ static void set_filesize(s64 filesize) } exit(1); } + /* + * If truncate just created a sparse file, the ability + * to generically store big files has been checked, but no + * space has been reserved and available space has probably + * not been checked. Better reset the file so that we write + * sequentially to the end. + */ + if (!opt.no_action) { +#ifdef HAVE_WINDOWS_H + if (ftruncate(fd_out, 0)) + Printf("Failed to reset the output file.\n"); +#else + struct stat st; + int s; + + s = fstat(fd_out, &st); + if (s || (!st.st_blocks && ftruncate(fd_out, 0))) + Printf("Failed to reset the output file.\n"); +#endif + /* Proceed even if ftruncate failed */ + } } static s64 open_image(void)