mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-20 05:32:14 +00:00
Fix_direct I/O, fdatasync
This fixes the following problems. 1. Fdatasync is incorrectly called when in direct I/O mode when no --directio command line option is present, i.e when it automatically determines whether direct or cached should be used. 2. When multiple drives are wiped if any of those drives do not support direct I/O then they would have would have had fdatasync incorrectly disabled. There was no record of I/O mode on a per drive basis. 3. Direct I/O on a static pass always called fdatasync as there was no code present to set the SyncRate to 0 when in direct I/O mode.
This commit is contained in:
@@ -59,6 +59,13 @@ typedef enum nwipe_select_t_ {
|
||||
NWIPE_SELECT_DISABLED // Do not wipe this device and do not allow it to be selected.
|
||||
} nwipe_select_t;
|
||||
|
||||
/* I/O mode for data path: auto, direct, or cached. */
|
||||
typedef enum {
|
||||
NWIPE_IO_MODE_AUTO = 0, /* Try O_DIRECT, fall back to cached I/O if not supported. */
|
||||
NWIPE_IO_MODE_DIRECT, /* Force O_DIRECT, fail if not supported. */
|
||||
NWIPE_IO_MODE_CACHED /* Force cached I/O, never attempt O_DIRECT. */
|
||||
} nwipe_io_mode_t;
|
||||
|
||||
#define NWIPE_KNOB_SPEEDRING_SIZE 30
|
||||
#define NWIPE_KNOB_SPEEDRING_GRANULARITY 10
|
||||
|
||||
@@ -199,6 +206,7 @@ typedef struct nwipe_context_t_
|
||||
char HPA_size_text[NWIPE_DEVICE_SIZE_TXT_LENGTH]; // Human readable size bytes, KB, MB, GB ..
|
||||
int HPA_display_toggle_state; // 0 or 1 Used to toggle between "[1TB] [ 33C]" and [HDA STATUS]
|
||||
time_t HPA_toggle_time; // records a time, then if for instance 3 seconds has elapsed the display changes
|
||||
nwipe_io_mode_t io_mode; // specific I/O method for a given drive, direct or cached.
|
||||
int test_use1;
|
||||
int test_use2;
|
||||
|
||||
|
||||
@@ -738,10 +738,12 @@ int main( int argc, char** argv )
|
||||
if( open_flags & O_DIRECT )
|
||||
{
|
||||
io_desc = "direct I/O (O_DIRECT)";
|
||||
c2[i]->io_mode = NWIPE_IO_MODE_DIRECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
io_desc = "cached I/O";
|
||||
c2[i]->io_mode = NWIPE_IO_MODE_CACHED;
|
||||
}
|
||||
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Using %s on device '%s'.", io_desc, c2[i]->device_name );
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#ifndef OPTIONS_H_
|
||||
#define OPTIONS_H_
|
||||
|
||||
#include "method.h"
|
||||
|
||||
/* Program knobs. */
|
||||
#define NWIPE_KNOB_IDENTITY_SIZE 512
|
||||
#define NWIPE_KNOB_LABEL_SIZE 128
|
||||
@@ -47,13 +49,6 @@ void nwipe_options_log( void );
|
||||
/* Function to display help text */
|
||||
void display_help();
|
||||
|
||||
/* I/O mode for data path: auto, direct, or cached. */
|
||||
typedef enum {
|
||||
NWIPE_IO_MODE_AUTO = 0, /* Try O_DIRECT, fall back to cached I/O if not supported. */
|
||||
NWIPE_IO_MODE_DIRECT, /* Force O_DIRECT, fail if not supported. */
|
||||
NWIPE_IO_MODE_CACHED /* Force cached I/O, never attempt O_DIRECT. */
|
||||
} nwipe_io_mode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int autonuke; // Do not prompt the user for confirmation when set.
|
||||
@@ -77,7 +72,8 @@ typedef struct
|
||||
int PDF_preview_details; // 0=Disable preview Org/Cust/date/time before drive selection, 1=Enable Preview
|
||||
int PDFtag; // Enable display of hostID, such as UUID or serial no. on PDF report.
|
||||
nwipe_verify_t verify; // A flag to indicate whether writes should be verified.
|
||||
nwipe_io_mode_t io_mode; // Runtime I/O mode selection (auto/direct/cached).
|
||||
nwipe_io_mode_t io_mode; // Global runtime I/O mode selection (auto/direct/cached), note in auto mode each
|
||||
// drive may use a different I/O mode if directIO isn't supported on a given drive.
|
||||
} nwipe_options_t;
|
||||
|
||||
extern nwipe_options_t nwipe_options;
|
||||
|
||||
43
src/pass.c
43
src/pass.c
@@ -386,18 +386,22 @@ int nwipe_random_pass( NWIPE_METHOD_SIGNATURE )
|
||||
|
||||
int syncRate = nwipe_options.sync;
|
||||
|
||||
/* For direct I/O we do not need periodic fdatasync(), I/O errors are detected
|
||||
* at write() time. Keep sync for cached I/O only. */
|
||||
if( nwipe_options.io_mode == NWIPE_IO_MODE_DIRECT )
|
||||
{
|
||||
syncRate = 0;
|
||||
}
|
||||
|
||||
/* Select effective I/O block size (e.g. 4 MiB, never smaller than st_blksize). */
|
||||
io_blocksize = nwipe_effective_io_blocksize( c );
|
||||
|
||||
/* Compute the per-write sync rate based on io_blocksize and old semantics. */
|
||||
syncRate = nwipe_compute_sync_rate_for_device( c, io_blocksize );
|
||||
/* For direct I/O we do not need periodic fdatasync(), I/O errors are detected
|
||||
* at write() time. Keep sync for cached I/O only. */
|
||||
|
||||
if( c->io_mode == NWIPE_IO_MODE_DIRECT )
|
||||
{
|
||||
syncRate = 0;
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Disabled fdatasync for %s, DirectI/O in use.", c->device_name );
|
||||
}
|
||||
else /* for cached I/O only */
|
||||
{
|
||||
/* Compute the per-write sync rate based on io_blocksize and old semantics. */
|
||||
syncRate = nwipe_compute_sync_rate_for_device( c, io_blocksize );
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int idx;
|
||||
@@ -824,6 +828,22 @@ int nwipe_static_pass( NWIPE_METHOD_SIGNATURE, nwipe_pattern_t* pattern )
|
||||
u64 z = c->device_size;
|
||||
|
||||
int syncRate = nwipe_options.sync;
|
||||
|
||||
io_blocksize = nwipe_effective_io_blocksize( c );
|
||||
|
||||
/* For direct I/O we do not need periodic fdatasync(), I/O errors are detected
|
||||
* at write() time. Keep sync for cached I/O only. */
|
||||
if( c->io_mode == NWIPE_IO_MODE_DIRECT )
|
||||
{
|
||||
syncRate = 0;
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Disabled fdatasync for %s, DirectI/O in use.", c->device_name );
|
||||
}
|
||||
else /* for cached I/O only */
|
||||
{
|
||||
/* Compute per-write sync rate (same semantics as random pass). */
|
||||
syncRate = nwipe_compute_sync_rate_for_device( c, io_blocksize );
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
if( pattern == NULL )
|
||||
@@ -838,11 +858,6 @@ int nwipe_static_pass( NWIPE_METHOD_SIGNATURE, nwipe_pattern_t* pattern )
|
||||
return -1;
|
||||
}
|
||||
|
||||
io_blocksize = nwipe_effective_io_blocksize( c );
|
||||
|
||||
/* Compute per-write sync rate (same semantics as random pass). */
|
||||
syncRate = nwipe_compute_sync_rate_for_device( c, io_blocksize );
|
||||
|
||||
/*
|
||||
* For static patterns we want enough buffer space to always have a
|
||||
* contiguous window of "io_blocksize" bytes available starting at any
|
||||
|
||||
Reference in New Issue
Block a user