Merge pull request #704 from PartialVolume/fix_sync_occuring_in_directIO_when_no_command_line_arguments

Fix_direct I/O, fdatasync
This commit is contained in:
PartialVolume
2026-01-02 23:56:32 +00:00
committed by GitHub
4 changed files with 43 additions and 22 deletions

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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