>From 450aaeda98a3e37c50d2a8e3b12330bbea2a86ac Mon Sep 17 00:00:00 2001
From: Andreas Oberritter
Date: Mon, 11 Oct 2010 03:54:08 +0200
Subject: [PATCH 3/4] Add new command-line option -E to specifiy maximum amount of new errors
---
ddrescue.h | 8 ++++----
doc/ddrescue.1 | 7 +++++--
main.cc | 22 ++++++++++++++--------
rescuebook.cc | 5 +++--
4 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/ddrescue.h b/ddrescue.h
index 6fb3cd7..13793e2 100644
--- a/ddrescue.h
+++ b/ddrescue.h
@@ -125,9 +125,9 @@ class Rescuebook : public Logbook
long long sparse_size; // end position of pending writes
long long recsize, errsize; // total recovered and error sizes
const char * const iname_;
- int errors; // error areas found so far
+ int errors, old_errors; // error areas found so far
int ides_, odes_; // input and output file descriptors
- const int max_errors_, max_retries_, skipbs_;
+ const int max_errors_, max_new_errors_, max_retries_, skipbs_;
const bool nosplit_, sparse_, synchronous_;
// variables for show_status
long long a_rate, c_rate, first_size, last_size;
@@ -142,7 +142,7 @@ class Rescuebook : public Logbook
int check_all();
void count_errors() throw();
bool too_many_errors() const throw()
- { return ( max_errors_ >= 0 && errors > max_errors_ ); }
+ { return ( max_errors_ >= 0 && errors > max_errors_ ) || ( max_new_errors_ >= 0 && errors - old_errors >= max_new_errors_ ); }
int copy_and_update( const Block & b, const Sblock::Status st,
int & copied_size, int & error_size,
const char * const msg, bool & first_post );
@@ -156,7 +156,7 @@ public:
Rescuebook( const long long ipos, const long long opos,
Domain & dom, const long long isize, const char * const iname,
const char * const logname, const int cluster, const int hardbs,
- const int max_errors = -1, const int max_retries = 0,
+ const int max_errors = -1, const int max_new_errors = -1, const int max_retries = 0,
const bool complete_only = false, const bool nosplit = false,
const bool retrim = false, const bool sparse = false,
const bool synchronous = false, const bool try_again = false );
diff --git a/doc/ddrescue.1 b/doc/ddrescue.1
index f74e6f0..f87642c 100644
--- a/doc/ddrescue.1
+++ b/doc/ddrescue.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
-.TH DDRESCUE "1" "August 2010" "ddrescue 1.13" "User Commands"
+.TH DDRESCUE "1" "October 2010" "ddrescue 1.13" "User Commands"
.SH NAME
ddrescue \- data recovery tool
.SH SYNOPSIS
@@ -38,7 +38,10 @@ use direct disc access for input file
use synchronous writes for output file
.TP
\fB\-e\fR, \fB\-\-max\-errors=\fR
-maximum number of error areas allowed
+maximum number of total error areas allowed
+.TP
+\fB\-E\fR, \fB\-\-max\-new\-errors=\fR
+maximum number of additional error areas allowed
.TP
\fB\-f\fR, \fB\-\-force\fR
overwrite output device or partition
diff --git a/main.cc b/main.cc
index 9129e6f..845bdc8 100644
--- a/main.cc
+++ b/main.cc
@@ -73,7 +73,8 @@ void show_help( const int cluster, const int hardbs ) throw()
std::printf( " -C, --complete-only do not read new data beyond logfile limits\n" );
std::printf( " -d, --direct use direct disc access for input file\n" );
std::printf( " -D, --synchronous use synchronous writes for output file\n" );
- std::printf( " -e, --max-errors= maximum number of error areas allowed\n" );
+ std::printf( " -e, --max-errors= maximum number of total error areas allowed\n" );
+ std::printf( " -E, --max-new-errors= maximum number of additional error areas allowed\n" );
std::printf( " -f, --force overwrite output device or partition\n" );
std::printf( " -F, --fill= fill given type blocks with infile data (?*/-+)\n" );
std::printf( " -g, --generate-logfile generate approximate logfile from partial copy\n" );
@@ -318,7 +319,7 @@ int do_generate( const long long ipos, const long long opos, Domain & domain,
int do_rescue( const long long ipos, const long long opos, Domain & domain,
const char *iname, const char *oname, const char *logname,
const int cluster, const int hardbs,
- const int max_errors, const int max_retries,
+ const int max_errors, const int max_new_errors, const int max_retries,
const int o_direct, const int o_trunc,
const bool complete_only, const bool nosplit,
const bool preallocate, const bool retrim, const bool sparse,
@@ -332,7 +333,7 @@ int do_rescue( const long long ipos, const long long opos, Domain & domain,
{ show_error( "Input file is not seekable." ); return 1; }
Rescuebook rescuebook( ipos, opos, domain, isize, iname, logname, cluster,
- hardbs, max_errors, max_retries, complete_only,
+ hardbs, max_errors, max_new_errors, max_retries, complete_only,
nosplit, retrim, sparse, synchronous, try_again );
if( rescuebook.domain().in_size() == 0 )
{ show_error( "Nothing to do." ); return 0; }
@@ -375,6 +376,8 @@ int do_rescue( const long long ipos, const long long opos, Domain & domain,
bool nl = false;
if( max_errors >= 0 )
{ nl = true; std::printf( "Max_errors: %d ", max_errors ); }
+ if( max_new_errors >= 0 )
+ { nl = true; std::printf( "Max_new_errors: %d ", max_new_errors ); }
if( max_retries >= 0 )
{ nl = true; std::printf( "Max_retries: %d ", max_retries ); }
if( nl ) std::printf( "\n" );
@@ -438,6 +441,7 @@ int main( const int argc, const char * const argv[] )
int cluster = 0;
int hardbs = 512;
int max_errors = -1;
+ int max_new_errors = -1;
int max_retries = 0;
int o_direct = 0;
int o_trunc = 0;
@@ -465,6 +469,7 @@ int main( const int argc, const char * const argv[] )
{ 'd', "direct", Arg_parser::no },
{ 'D', "synchronous", Arg_parser::no },
{ 'e', "max-errors", Arg_parser::yes },
+ { 'E', "max-new-errors", Arg_parser::yes },
{ 'f', "force", Arg_parser::no },
{ 'F', "fill", Arg_parser::yes },
{ 'g', "generate-logfile", Arg_parser::no },
@@ -510,6 +515,7 @@ int main( const int argc, const char * const argv[] )
break;
case 'D': synchronous = true; break;
case 'e': max_errors = getnum( arg, 0, -1, INT_MAX ); break;
+ case 'E': max_new_errors = getnum( arg, 0, -1, INT_MAX ); break;
case 'f': force = true; break;
case 'F': filltypes = arg; check_fill_types( filltypes ); break;
case 'g': generate = true; break;
@@ -554,11 +560,11 @@ int main( const int argc, const char * const argv[] )
if( filltypes.size() )
{
- if( max_errors >= 0 || max_retries || o_direct || o_trunc ||
+ if( max_errors >= 0 || max_new_errors >= 0 || max_retries || o_direct || o_trunc ||
complete_only || generate || nosplit || preallocate || retrim ||
sparse || synchronous || try_again )
{
- show_error( "warning: Options -C -d -D -e -g -n -p -r -R -S -t and -T" );
+ show_error( "warning: Options -C -d -D -e -E -g -n -p -r -R -S -t and -T" );
show_error( "are ignored in fill mode." );
}
@@ -567,11 +573,11 @@ int main( const int argc, const char * const argv[] )
}
if( generate )
{
- if( max_errors >= 0 || max_retries || o_direct || o_trunc ||
+ if( max_errors >= 0 || max_new_errors >= 0 || max_retries || o_direct || o_trunc ||
complete_only || nosplit || preallocate || retrim ||
sparse || synchronous || try_again )
{
- show_error( "warning: Options -C -d -D -e -n -p -r -R -S -t and -T" );
+ show_error( "warning: Options -C -d -D -e -E -n -p -r -R -S -t and -T" );
show_error( "are ignored in generate-logfile mode." );
}
@@ -579,7 +585,7 @@ int main( const int argc, const char * const argv[] )
cluster, hardbs );
}
return do_rescue( ipos, opos, domain, iname, oname, logname, cluster,
- hardbs, max_errors, max_retries, o_direct, o_trunc,
+ hardbs, max_errors, max_new_errors, max_retries, o_direct, o_trunc,
complete_only, nosplit, preallocate, retrim, sparse,
synchronous, try_again );
}
diff --git a/rescuebook.cc b/rescuebook.cc
index bdd8d43..b54fa40 100644
--- a/rescuebook.cc
+++ b/rescuebook.cc
@@ -289,14 +289,14 @@ int Rescuebook::copy_errors()
Rescuebook::Rescuebook( const long long ipos, const long long opos,
Domain & dom, const long long isize, const char * const iname,
const char * const logname, const int cluster, const int hardbs,
- const int max_errors, const int max_retries,
+ const int max_errors, const int max_new_errors, const int max_retries,
const bool complete_only, const bool nosplit,
const bool retrim, const bool sparse,
const bool synchronous, const bool try_again )
: Logbook( ipos, opos, dom, isize, logname, cluster, hardbs, complete_only ),
sparse_size( 0 ),
iname_( ( iname && access( iname, F_OK ) == 0 ) ? iname : 0 ),
- max_errors_( max_errors ), max_retries_( max_retries ),
+ max_errors_( max_errors ), max_new_errors_( max_new_errors ), max_retries_( max_retries ),
skipbs_( std::max( 65536, hardbs ) ),
nosplit_( nosplit ), sparse_( sparse ), synchronous_( synchronous ),
a_rate( 0 ), c_rate( 0 ), first_size( 0 ), last_size( 0 ),
@@ -404,6 +404,7 @@ int Rescuebook::do_rescue( const int ides, const int odes )
}
count_errors();
set_signals();
+ old_errors = errors;
if( verbosity >= 0 )
{
std::printf( "Press Ctrl-C to interrupt\n" );
--
1.7.0.4