OSDN Git Service

Reset the output file to favour appending to image in ntfsclone
authorJean-Pierre André <jpandre@users.sourceforge.net>
Tue, 11 Mar 2014 08:54:53 +0000 (09:54 +0100)
committerJean-Pierre André <jpandre@users.sourceforge.net>
Tue, 11 Mar 2014 08:54:53 +0000 (09:54 +0100)
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
ntfsprogs/ntfsclone.c

index 24f8d9b..66ad243 100644 (file)
@@ -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 */
 
index 481ebf3..33d76d8 100644 (file)
@@ -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)