dvd-sector-copy.c (find_good_sector): Use plain `read_sectors' for retries.
[dvdrip] / dvd-sector-copy.c
index a608410..8c4ba1f 100644 (file)
@@ -95,8 +95,8 @@ static void put_menu(dvd_reader_t *dvd, unsigned title)
   store_filename(fn, id);
   start = UDFFindFile(dvd, fn, &len); if (!start) return;
 #ifdef DEBUG
-      printf(";; %8"PRIuSEC" .. %-8"PRIuSEC": %s\n",
-            start, start + SECTORS(len), fn);
+  printf(";; %8"PRIuSEC" .. %-8"PRIuSEC": %s\n",
+        start, start + SECTORS(len), fn);
 #endif
   put_file(id, start, start + SECTORS(len));
 }
@@ -336,7 +336,8 @@ static ssize_t read_sectors(secaddr pos, void *buf, secaddr want)
     if (best && pos + want > best->start)
       { want = best->start - pos; fakeerr = EIO; sit(bad_block_delay); }
   }
-  done = 0;
+
+  done = 0; errno = 0;
   while (want) {
     if (vob)
       { errno = 0; n = DVDReadBlocks(vob, pos - file->start, want, p); }
@@ -364,27 +365,6 @@ static ssize_t read_sectors(secaddr pos, void *buf, secaddr want)
   return (!done && errno ? -1 : done);
 }
 
-static void record_bad_sectors(secaddr bad_lo, secaddr bad_hi)
-{
-  char fn[MAXFNSZ];
-
-  if (!mapfile) return;
-
-  open_file_on_demand(mapfile, &mapfp, "bad-sector region map");
-  fprintf(mapfp, "%"PRIuSEC" %"PRIuSEC" # %"PRIuSEC" sectors",
-         bad_lo, bad_hi, bad_hi - bad_lo);
-
-  if (file && id_kind(file->id) != RAW) {
-    store_filename(fn, file->id);
-    fprintf(mapfp, "; `%s' %"PRIuSEC" .. %"PRIuSEC" of %"PRIuSEC"",
-           fn, bad_lo - file->start, bad_hi - file->start,
-           file->end - file->start);
-  }
-
-  fputc('\n', mapfp);
-  check_write(mapfp, "bad-sector region map");
-}
-
 static void recovered(secaddr bad_lo, secaddr bad_hi)
 {
   char fn[MAXFNSZ];
@@ -403,7 +383,19 @@ static void recovered(secaddr bad_lo, secaddr bad_hi)
         file->end - file->start);
   }
 
-  record_bad_sectors(bad_lo, bad_hi);
+  if (mapfile) {
+    open_file_on_demand(mapfile, &mapfp, "bad-sector region map");
+    fprintf(mapfp, "%"PRIuSEC" %"PRIuSEC" # %"PRIuSEC" sectors",
+           bad_lo, bad_hi, bad_hi - bad_lo);
+
+    if (file && id_kind(file->id) != RAW)
+      fprintf(mapfp, "; `%s' %"PRIuSEC" .. %"PRIuSEC" of %"PRIuSEC"",
+             fn, bad_lo - file->start, bad_hi - file->start,
+             file->end - file->start);
+
+    fputc('\n', mapfp);
+    check_write(mapfp, "bad-sector region map");
+  }
 
   if (lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0)
     bail_syserr(errno, "failed to seek past bad sectors");
@@ -456,6 +448,7 @@ static ssize_t recovery_read_sectors(struct recoverybuf *r,
   ssize_t n;
 
   assert(off <= r->sz); assert(want <= r->sz - off);
+  assert(pos == r->pos + off);
   n = read_sectors(pos, r->buf + off*SECTORSZ, want);
   return (n);
 }
@@ -487,9 +480,9 @@ static ssize_t recovery_read_buffer(struct recoverybuf *r,
 #endif
     }
   } else if (pos > r->pos + r->end) {
-      r->pos = pos; r->start = r->end = 0;
+    r->pos = pos; r->start = r->end = 0;
 #ifdef DEBUG
-      show_recovery_buffer_map(r, "cleared; beyond previous region");
+    show_recovery_buffer_map(r, "cleared; beyond previous region");
 #endif
   } else if (pos + want > r->pos + r->sz) {
     diff = (pos + want) - (r->pos + r->sz);
@@ -615,7 +608,7 @@ static secaddr run_length_wanted(secaddr pos, secaddr badlen, secaddr end)
 {
   secaddr want;
 
-  want = clear_factor*badlen;
+  want = ceil(clear_factor*badlen);
   if (want < clear_min) want = clear_min;
   if (want > end - pos) want = end - pos;
   if (clear_max && want > clear_max) want = clear_max;
@@ -636,13 +629,10 @@ static ssize_t find_good_sector(secaddr *pos_inout, secaddr end,
   badblock_progress.render = render_badblock_progress;
   progress_additem(&progress, &badblock_progress);
 
-  r.buf = buf; r.sz = sz; r.pos = r.start = r.end = 0;
-  r.good_lo = r.good_hi = 0;
-
   want = sz; if (want > end - pos) want = end - pos;
   for (retry = 0; retry < max_retries; retry++) {
     report_bad_blocks_progress(pos, errno);
-    n = recovery_read(&r, pos, want);
+    n = read_sectors(pos, buf, want);
 #ifdef DEBUG
     progress_clear(&progress);
     printf(";; [retry] try reading %"PRIuSEC" .. %"PRIuSEC" -> %zd\n",
@@ -657,6 +647,9 @@ static ssize_t find_good_sector(secaddr *pos_inout, secaddr end,
     }
   }
 
+  r.buf = buf; r.sz = sz; r.pos = r.start = r.end = 0;
+  r.good_lo = r.good_hi = 0;
+
   bad_lo = pos; bad_hi = pos + 1;
   for (;;) {
     report_bad_blocks_progress(bad_hi, errno);
@@ -1043,7 +1036,7 @@ int main(int argc, char *argv[])
 #endif
   }
 
-  open_dvd(device, O_RDONLY, &dvdfd, &dvd);
+  if (open_dvd(device, O_RDONLY, &dvdfd, &dvd)) exit(2);
 
   blksz = SECTORSZ; volsz = device_size(dvdfd, device, &blksz);
   if (blksz != SECTORSZ)
@@ -1053,7 +1046,7 @@ int main(int argc, char *argv[])
         device, volsz, SECTORSZ);
 
   if (f&f_checkid) {
-    open_dvd(outfile, O_RDONLY, 0, &dvd_out);
+    if (open_dvd(outfile, O_RDONLY, 0, &dvd_out)) exit(2);
     if (dvd_id(id_in, dvd, DIF_MUSTIFOHASH, device) ||
        dvd_id(id_out, dvd_out, DIF_MUSTIFOHASH, device))
       exit(2);