Skip to content

Commit

Permalink
Fix final fsync absence when fsync=N specified.
Browse files Browse the repository at this point in the history
When `fsync=N` parameter specified and the final IO block issued
happens to be Nth an fsync should follow it is missed.
This update checks if it needs to loop again in `do_io` to issue
that final fsync when all the IO work is done.

Signed-off-by: Roman Sofin [email protected]
  • Loading branch information
Roman Sofin committed Aug 13, 2024
1 parent 656357f commit d3396c6
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
5 changes: 3 additions & 2 deletions backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,7 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)

while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
(!flist_empty(&td->trim_list)) || !io_issue_bytes_exceeded(td) ||
time_to_ddir_sync(td) ||
td->o.time_based) {
struct timespec comp_time;
struct io_u *io_u;
Expand Down Expand Up @@ -1032,8 +1033,8 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
*/
if (bytes_issued >= total_bytes &&
!td->o.read_iolog_file &&
(!td->o.time_based ||
(td->o.time_based && td->o.verify != VERIFY_NONE)))
((!td->o.time_based && !time_to_ddir_sync(td)) ||
(td->o.time_based && td->o.verify != VERIFY_NONE)))
break;

io_u = get_io_u(td);
Expand Down
37 changes: 25 additions & 12 deletions io_u.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,19 +742,8 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
return ddir;
}

/*
* Return the data direction for the next io_u. If the job is a
* mixed read/write workload, check the rwmix cycle and switch if
* necessary.
*/
static enum fio_ddir get_rw_ddir(struct thread_data *td)
static inline enum fio_ddir get_sync_ddir(const struct thread_data *td)
{
enum fio_ddir ddir;

/*
* See if it's time to fsync/fdatasync/sync_file_range first,
* and if not then move on to check regular I/Os.
*/
if (should_fsync(td) && td->last_ddir_issued == DDIR_WRITE) {
if (td->o.fsync_blocks && td->io_issues[DDIR_WRITE] &&
!(td->io_issues[DDIR_WRITE] % td->o.fsync_blocks))
Expand All @@ -768,6 +757,30 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td)
!(td->io_issues[DDIR_WRITE] % td->sync_file_range_nr))
return DDIR_SYNC_FILE_RANGE;
}
return DDIR_INVAL;
}

bool time_to_ddir_sync(const struct thread_data *td)
{
return get_sync_ddir(td) != DDIR_INVAL;
}

/*
* Return the data direction for the next io_u. If the job is a
* mixed read/write workload, check the rwmix cycle and switch if
* necessary.
*/
static enum fio_ddir get_rw_ddir(struct thread_data *td)
{
enum fio_ddir ddir;

/*
* See if it's time to fsync/fdatasync/sync_file_range first,
* and if not then move on to check regular I/Os.
*/
ddir = get_sync_ddir(td);
if (ddir != DDIR_INVAL)
return ddir;

if (td_rw(td)) {
/*
Expand Down
2 changes: 2 additions & 0 deletions io_u.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ bool queue_full(const struct thread_data *);
int do_io_u_sync(const struct thread_data *, struct io_u *);
int do_io_u_trim(struct thread_data *, struct io_u *);

bool time_to_ddir_sync(const struct thread_data *);

#ifdef FIO_INC_DEBUG
static inline void dprint_io_u(struct io_u *io_u, const char *p)
{
Expand Down

0 comments on commit d3396c6

Please sign in to comment.