New "--error-skip-block" option.
This commit is contained in:
@@ -42,6 +42,7 @@ struct opts_s { /* structure describing run-time options */
|
||||
unsigned long long size; /* total size of data */
|
||||
bool no_splice; /* flag set if never to use splice */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
unsigned long long error_skip_block; /* skip block size, 0 for adaptive */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
|
||||
@@ -93,6 +93,7 @@ struct pvstate_s {
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
unsigned long long error_skip_block; /* skip block size, 0 for adaptive */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
|
||||
@@ -148,6 +148,7 @@ extern void pv_state_bits_set(pvstate_t, bool);
|
||||
extern void pv_state_null_terminated_lines_set(pvstate_t, bool);
|
||||
extern void pv_state_no_display_set(pvstate_t, bool);
|
||||
extern void pv_state_skip_errors_set(pvstate_t, unsigned int);
|
||||
extern void pv_state_error_skip_block_set(pvstate_t, unsigned long long);
|
||||
extern void pv_state_stop_at_size_set(pvstate_t, bool);
|
||||
extern void pv_state_sync_after_write_set(pvstate_t, bool);
|
||||
extern void pv_state_direct_io_set(pvstate_t, bool);
|
||||
|
||||
@@ -368,6 +368,9 @@ void display_help(void)
|
||||
{ "-E", "--skip-errors", NULL,
|
||||
N_("skip read errors in input"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-Z", "--error-skip-block", N_("BYTES"),
|
||||
N_("skip errors in BYTES blocks at a time"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-S", "--stop-at-size", NULL,
|
||||
N_("stop after --size bytes have been transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
|
||||
@@ -271,6 +271,7 @@ int main(int argc, char **argv)
|
||||
pv_state_bits_set(state, opts->bits);
|
||||
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
|
||||
pv_state_skip_errors_set(state, opts->skip_errors);
|
||||
pv_state_error_skip_block_set(state, opts->error_skip_block);
|
||||
pv_state_stop_at_size_set(state, opts->stop_at_size);
|
||||
pv_state_sync_after_write_set(state, opts->sync_after_write);
|
||||
pv_state_direct_io_set(state, opts->direct_io);
|
||||
|
||||
+11
-1
@@ -169,6 +169,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
{ "buffer-size", 1, NULL, (int) 'B' },
|
||||
{ "no-splice", 0, NULL, (int) 'C' },
|
||||
{ "skip-errors", 0, NULL, (int) 'E' },
|
||||
{ "error-skip-block", 1, NULL, (int) 'Z' },
|
||||
{ "stop-at-size", 0, NULL, (int) 'S' },
|
||||
{ "sync", 0, NULL, (int) 'Y' },
|
||||
{ "direct-io", 0, NULL, (int) 'K' },
|
||||
@@ -185,7 +186,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
/*@+nullassign@ */
|
||||
int option_index = 0;
|
||||
#endif /* HAVE_GETOPT_LONG */
|
||||
char *short_options = "hVpteIrab8TA:fnqcWD:s:l0i:w:H:N:F:L:B:CESYKXR:P:d:m:"
|
||||
char *short_options = "hVpteIrab8TA:fnqcWD:s:l0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:"
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
"!:"
|
||||
#endif
|
||||
@@ -281,6 +282,8 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
case 'R':
|
||||
/*@fallthrough@ */
|
||||
case 'm':
|
||||
/*@fallthrough@ */
|
||||
case 'Z':
|
||||
if (pv_getnum_check(optarg, PV_NUMTYPE_INTEGER) != 0) {
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: -%c: %s\n", opts->program_name, c, _("integer argument expected"));
|
||||
@@ -461,6 +464,9 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
case 'E':
|
||||
opts->skip_errors++;
|
||||
break;
|
||||
case 'Z':
|
||||
opts->error_skip_block = pv_getnum_ull(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
opts->stop_at_size = true;
|
||||
break;
|
||||
@@ -605,6 +611,10 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->bytes = true;
|
||||
}
|
||||
|
||||
/* If -Z was given but not -E, pretend one -E was given too. */
|
||||
if (opts->error_skip_block > 0 && 0 == opts->skip_errors)
|
||||
opts->skip_errors = 1;
|
||||
|
||||
/*
|
||||
* Store remaining command-line arguments.
|
||||
*/
|
||||
|
||||
@@ -207,6 +207,11 @@ void pv_state_skip_errors_set(pvstate_t state, unsigned int val)
|
||||
state->skip_errors = val;
|
||||
};
|
||||
|
||||
void pv_state_error_skip_block_set(pvstate_t state, unsigned long long val)
|
||||
{
|
||||
state->error_skip_block = val;
|
||||
}
|
||||
|
||||
void pv_state_stop_at_size_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->stop_at_size = val;
|
||||
|
||||
+15
-6
@@ -402,12 +402,21 @@ static int pv__transfer_read(pvstate_t state, int fd, int *eof_in, int *eof_out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (state->read_errors_in_a_row < 10) {
|
||||
amount_to_skip = state->read_errors_in_a_row < 5 ? 1 : 2;
|
||||
} else if (state->read_errors_in_a_row < 20) {
|
||||
amount_to_skip = 1 << (state->read_errors_in_a_row - 10);
|
||||
} else {
|
||||
amount_to_skip = 512;
|
||||
/*
|
||||
* If a non-zero error skip block size was given, just use that,
|
||||
* otherwise start small and ramp up based on the number of errors
|
||||
* in a row.
|
||||
*/
|
||||
if (state->error_skip_block > 0) {
|
||||
amount_to_skip = state->error_skip_block;
|
||||
} else {
|
||||
if (state->read_errors_in_a_row < 10) {
|
||||
amount_to_skip = state->read_errors_in_a_row < 5 ? 1 : 2;
|
||||
} else if (state->read_errors_in_a_row < 20) {
|
||||
amount_to_skip = 1 << (state->read_errors_in_a_row - 10);
|
||||
} else {
|
||||
amount_to_skip = 512;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user