- n = read_sectors(src, pos, buf, want);
-
- if (n <= 0) {
- report_bad_blocks_progress(src, pos, pos, errno);
- for (i = 0; i < 4; i++) {
- n = read_sectors(src, pos, buf, 1);
- if (n > 0) {
- clear_progress();
- fprintf(stderr, "%s: sector %"PRIu32" read ok after retry\n",
- prog, pos);
- bad_lo = bad_hi = pos;
- goto recovered;
- }
- }
-
- bad_lo = pos; step = 1; bad_hi = pos + 1;
- for (;;) {
- report_bad_blocks_progress(src, bad_lo, bad_hi, errno);
- if (bad_hi >= end) {
- clear_progress();
- fprintf(stderr, "%s: giving up on this extent\n", prog);
- n = 0; goto recovered;
- }
- step *= 2;
- if (step > end - bad_lo) step = end - bad_lo;
- pos = bad_lo + step - 1;
- n = read_sectors(src, pos, buf, 1);
- if (n > 0) break;
- bad_hi = pos + 1;
- }
-
- good = pos;
- while (good > bad_hi) {
- report_bad_blocks_progress(src, bad_lo, bad_hi, errno);
- pos = bad_hi + (good - bad_hi)/2;
- n = read_sectors(src, pos, buf, 1);
- if (n > 0) good = pos;
- else bad_hi = pos + 1;
- }
- recovered:
- if (bad_hi > bad_lo) {
- clear_progress();
- fprintf(stderr, "%s: skipping %"PRIu32" bad sectors "
- "(%"PRIu32" .. %"PRIu32")\n",
- prog, bad_hi - bad_lo, bad_lo, bad_hi);
- if (src->mapfile) {
- if (!src->mapfp) {
- src->mapfp = fopen(src->mapfile, "w");
- if (!src->mapfp)
- bail_syserr(errno, "failed to open bad-sector map file `%s'",
- optarg);
- fprintf(src->mapfp, "## bad sector map\n\n");
- }
- fprintf(src->mapfp, "%"PRIu32" %"PRIu32"\n", bad_lo, bad_hi);
- fflush(src->mapfp);
- if (ferror(src->mapfp))
- bail_syserr(errno, "error writing bad-sector map file");
- }
- if (outfd >= 0 &&
- lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0)
- bail_syserr(errno, "failed to seek past bad sectors");
- status = 1;
- }
- pos = bad_hi;
- }