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.
edge.strict_endians
Jean-Pierre André 2013-02-09 15:07:06 +01:00
parent a086683ece
commit a6b765c824
1 changed files with 22 additions and 12 deletions

View File

@ -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<clusters_per_set) && rl[ri].length; k++) {
read_rescue(fd, &buff[k*csize], csize, rl[ri].lcn + rj);
read_rescue(fd, &buff[k*csize], csize, bytes_per_sector,
rl[ri].lcn + rj);
if (++rj >= 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<clusters_per_set) && rl[ri].length; k++) {
read_rescue(fd, &buff[k*csize], csize, rl[ri].lcn + rj);
read_rescue(fd, &buff[k*csize], csize, bytes_per_sector,
rl[ri].lcn + rj);
if (++rj >= rl[ri].length) {
rj = 0;
if (rl[++ri].length)