sfdisk: only report I/O errors on --move-data
Now sfdisk stops everything on I/O error when moving data. It seems better to report the error to user and continue as it's better to have one bad sector in the partition than inconsistent all partition. Addresses: https://github.com/karelzak/util-linux/issues/984 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
64cb2da8dc
commit
79ef974a68
|
@ -376,9 +376,9 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
int ok = 0, fd, backward = 0;
|
int ok = 0, fd, backward = 0;
|
||||||
fdisk_sector_t nsectors, from, to, step, i, prev;
|
fdisk_sector_t nsectors, from, to, step, i, prev;
|
||||||
size_t io, ss, step_bytes, cc;
|
size_t io, ss, step_bytes, cc, ioerr = 0;
|
||||||
uintmax_t src, dst, nbytes;
|
uintmax_t src, dst, nbytes;
|
||||||
int errsv, progress = 0;
|
int progress = 0, rc = 0;
|
||||||
struct timeval prev_time;
|
struct timeval prev_time;
|
||||||
uint64_t bytes_per_sec = 0;
|
uint64_t bytes_per_sec = 0;
|
||||||
|
|
||||||
|
@ -474,8 +474,9 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
if (typescript) {
|
if (typescript) {
|
||||||
f = fopen(typescript, "w");
|
f = fopen(typescript, "w");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
|
rc = -errno;
|
||||||
fdisk_warn(sf->cxt, _("cannot open %s"), typescript);
|
fdisk_warn(sf->cxt, _("cannot open %s"), typescript);
|
||||||
goto fail;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't translate */
|
/* don't translate */
|
||||||
|
@ -506,8 +507,6 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
prev = 0;
|
prev = 0;
|
||||||
|
|
||||||
for (cc = 1, i = 0; i < nsectors && nbytes > 0; i += step, cc++) {
|
for (cc = 1, i = 0; i < nsectors && nbytes > 0; i += step, cc++) {
|
||||||
ssize_t rc;
|
|
||||||
|
|
||||||
if (backward)
|
if (backward)
|
||||||
src -= step_bytes, dst -= step_bytes;
|
src -= step_bytes, dst -= step_bytes;
|
||||||
|
|
||||||
|
@ -522,18 +521,26 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
|
|
||||||
if (!sf->noact) {
|
if (!sf->noact) {
|
||||||
/* read source */
|
/* read source */
|
||||||
if (lseek(fd, src, SEEK_SET) == (off_t) -1)
|
if (lseek(fd, src, SEEK_SET) == (off_t) -1 ||
|
||||||
goto fail;
|
read_all(fd, buf, step_bytes) != (ssize_t) step_bytes) {
|
||||||
rc = read(fd, buf, step_bytes);
|
if (f)
|
||||||
if (rc < 0 || rc != (ssize_t) step_bytes)
|
fprintf(f, "%05zu: read error %12ju %12ju\n", cc, src, dst);
|
||||||
goto fail;
|
fdisk_warn(sf->cxt,
|
||||||
|
_("cannot read at offset: %zu; continue"), src);
|
||||||
|
ioerr++;
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
/* write target */
|
/* write target */
|
||||||
if (lseek(fd, dst, SEEK_SET) == (off_t) -1)
|
if (lseek(fd, dst, SEEK_SET) == (off_t) -1 ||
|
||||||
goto fail;
|
write_all(fd, buf, step_bytes) != 0) {
|
||||||
rc = write(fd, buf, step_bytes);
|
if (f)
|
||||||
if (rc < 0 || rc != (ssize_t) step_bytes)
|
fprintf(f, "%05zu: write error %12ju %12ju\n", cc, src, dst);
|
||||||
goto fail;
|
fdisk_warn(sf->cxt,
|
||||||
|
_("cannot write at offset: %zu; continue"), dst);
|
||||||
|
ioerr++;
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
if (sf->movefsync)
|
if (sf->movefsync)
|
||||||
fsync(fd);
|
fsync(fd);
|
||||||
}
|
}
|
||||||
|
@ -571,7 +578,7 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
fputc('\r', stdout);
|
fputc('\r', stdout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
next:
|
||||||
if (!backward)
|
if (!backward)
|
||||||
src += step_bytes, dst += step_bytes;
|
src += step_bytes, dst += step_bytes;
|
||||||
}
|
}
|
||||||
|
@ -587,6 +594,8 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
100.0 / ((double) nsectors/(i+1)));
|
100.0 / ((double) nsectors/(i+1)));
|
||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
}
|
}
|
||||||
|
rc = 0;
|
||||||
|
done:
|
||||||
if (f)
|
if (f)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -595,18 +604,13 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa
|
||||||
|
|
||||||
if (sf->noact)
|
if (sf->noact)
|
||||||
fdisk_info(sf->cxt, _("Your data has not been moved (--no-act)."));
|
fdisk_info(sf->cxt, _("Your data has not been moved (--no-act)."));
|
||||||
|
if (ioerr) {
|
||||||
return 0;
|
fdisk_info(sf->cxt, _("%zu I/O errors detected!"), ioerr);
|
||||||
fail:
|
rc = -EIO;
|
||||||
errsv = -errno;
|
} else if (rc)
|
||||||
warn(_("%s: failed to move data"), devname);
|
warn(_("%s: failed to move data"), devname);
|
||||||
if (f)
|
|
||||||
fclose(f);
|
|
||||||
free(buf);
|
|
||||||
free(devname);
|
|
||||||
free(typescript);
|
|
||||||
|
|
||||||
return errsv;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_changes(struct sfdisk *sf)
|
static int write_changes(struct sfdisk *sf)
|
||||||
|
|
Loading…
Reference in New Issue