From a6b765c824515f77693980817357ff91a8590a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Sat, 9 Feb 2013 15:07:06 +0100 Subject: [PATCH] Fixed rescuing clusters by physical sectors in ntfsclone When a sector is unreadable, consider the whole sector as bad, instead of trying to find which 512-byte parts of it are bad. This was causing unwanted retries for devices with 4K sectors. --- ntfsprogs/ntfsclone.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/ntfsprogs/ntfsclone.c b/ntfsprogs/ntfsclone.c index 1ea0e39d..967dd95f 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-2012 Jean-Pierre Andre + * Copyright (c) 2010-2013 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. @@ -675,7 +675,7 @@ static int io_all(void *fd, void *buf, int count, int do_write) } -static void rescue_sector(void *fd, off_t pos, void *buff) +static void rescue_sector(void *fd, u32 bytes_per_sector, off_t pos, void *buff) { const char badsector_magic[] = "BadSectoR"; struct ntfs_device *dev = fd; @@ -689,10 +689,10 @@ static void rescue_sector(void *fd, off_t pos, void *buff) perr_exit("seek input"); } - if (read_all(fd, buff, NTFS_SECTOR_SIZE) == -1) { + if (read_all(fd, buff, bytes_per_sector) == -1) { Printf("WARNING: Can't read sector at %llu, lost data.\n", (unsigned long long)pos); - memset(buff, '?', NTFS_SECTOR_SIZE); + memset(buff, '?', bytes_per_sector); memmove(buff, badsector_magic, sizeof(badsector_magic)); } } @@ -701,7 +701,8 @@ static void rescue_sector(void *fd, off_t pos, void *buff) * Read a cluster, try to rescue if cannot read */ -static void read_rescue(void *fd, char *buff, u32 csize, u64 rescue_lcn) +static void read_rescue(void *fd, char *buff, u32 csize, u32 bytes_per_sector, + u64 rescue_lcn) { off_t rescue_pos; @@ -713,8 +714,9 @@ static void read_rescue(void *fd, char *buff, u32 csize, u64 rescue_lcn) u32 i; rescue_pos = (off_t)(rescue_lcn * csize); - for (i = 0; i < csize; i += NTFS_SECTOR_SIZE) - rescue_sector(fd, rescue_pos + i, buff + i); + for (i = 0; i < csize; i += bytes_per_sector) + rescue_sector(fd, bytes_per_sector, + rescue_pos + i, buff + i); } else { Printf("%s", bad_sectors_warning_msg); err_exit("Disk is faulty, can't make full backup!"); @@ -732,10 +734,11 @@ static void copy_cluster(int rescue, u64 rescue_lcn, u64 lcn) off_t rescue_pos; NTFS_BOOT_SECTOR *bs; le64 mask; - static u16 bytes_per_sector; + static u16 bytes_per_sector = NTFS_SECTOR_SIZE; if (!opt.restore_image) { csize = vol->cluster_size; + bytes_per_sector = vol->sector_size; fd = vol->dev; } @@ -761,8 +764,9 @@ static void copy_cluster(int rescue, u64 rescue_lcn, u64 lcn) } else if (rescue){ s32 i; - for (i = 0; i < csize; i += NTFS_SECTOR_SIZE) - rescue_sector(fd, rescue_pos + i, buff + i); + for (i = 0; i < csize; i += bytes_per_sector) + rescue_sector(fd, bytes_per_sector, + rescue_pos + i, buff + i); } else { Printf("%s", bad_sectors_warning_msg); err_exit("Disk is faulty, can't make full backup!"); @@ -1463,6 +1467,7 @@ static void copy_wipe_mft(ntfs_walk_clusters_ctx *image, runlist *rl) s64 mft_no; u32 mft_record_size; u32 csize; + u32 bytes_per_sector; u32 records_per_set; u32 clusters_per_set; u32 wi,wj; /* indexes for reading */ @@ -1474,6 +1479,7 @@ static void copy_wipe_mft(ntfs_walk_clusters_ctx *image, runlist *rl) current_lcn = image->current_lcn; mft_record_size = image->ni->vol->mft_record_size; csize = image->ni->vol->cluster_size; + bytes_per_sector = image->ni->vol->sector_size; fd = image->ni->vol->dev; /* * Depending on the sizes, there may be several records @@ -1493,7 +1499,8 @@ static void copy_wipe_mft(ntfs_walk_clusters_ctx *image, runlist *rl) lseek_to_cluster(rl[ri].lcn); while (rl[ri].length) { for (k=0; (k= rl[ri].length) { rj = 0; if (rl[++ri].length) @@ -1533,6 +1540,7 @@ static void copy_wipe_i30(ntfs_walk_clusters_ctx *image, runlist *rl) void *fd; u32 indx_record_size; u32 csize; + u32 bytes_per_sector; u32 records_per_set; u32 clusters_per_set; u32 wi,wj; /* indexes for reading */ @@ -1543,6 +1551,7 @@ static void copy_wipe_i30(ntfs_walk_clusters_ctx *image, runlist *rl) current_lcn = image->current_lcn; csize = image->ni->vol->cluster_size; + bytes_per_sector = image->ni->vol->sector_size; fd = image->ni->vol->dev; /* * Depending on the sizes, there may be several records @@ -1562,7 +1571,8 @@ static void copy_wipe_i30(ntfs_walk_clusters_ctx *image, runlist *rl) lseek_to_cluster(rl[ri].lcn); while (rl[ri].length) { for (k=0; (k= rl[ri].length) { rj = 0; if (rl[++ri].length)