Skip to content

Commit 6078913

Browse files
committed
io_u/backend: fix missing final fsync() when using fsync=N
When fsync=N is specified and the final I/O issued happens to be the Nth, the following fsync() 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]
1 parent bdb3d50 commit 6078913

File tree

3 files changed

+30
-14
lines changed

3 files changed

+30
-14
lines changed

backend.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,7 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
10001000

10011001
while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
10021002
(!flist_empty(&td->trim_list)) || !io_issue_bytes_exceeded(td) ||
1003+
ddir_is_sync(td) ||
10031004
td->o.time_based) {
10041005
struct timespec comp_time;
10051006
struct io_u *io_u;
@@ -1032,8 +1033,8 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
10321033
*/
10331034
if (bytes_issued >= total_bytes &&
10341035
!td->o.read_iolog_file &&
1035-
(!td->o.time_based ||
1036-
(td->o.time_based && td->o.verify != VERIFY_NONE)))
1036+
((!td->o.time_based && !ddir_is_sync(td)) ||
1037+
(td->o.time_based && td->o.verify != VERIFY_NONE)))
10371038
break;
10381039

10391040
io_u = get_io_u(td);

io_u.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -742,19 +742,8 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
742742
return ddir;
743743
}
744744

745-
/*
746-
* Return the data direction for the next io_u. If the job is a
747-
* mixed read/write workload, check the rwmix cycle and switch if
748-
* necessary.
749-
*/
750-
static enum fio_ddir get_rw_ddir(struct thread_data *td)
745+
static inline enum fio_ddir get_sync_ddir(const struct thread_data *td)
751746
{
752-
enum fio_ddir ddir;
753-
754-
/*
755-
* See if it's time to fsync/fdatasync/sync_file_range first,
756-
* and if not then move on to check regular I/Os.
757-
*/
758747
if (should_fsync(td) && td->last_ddir_issued == DDIR_WRITE) {
759748
if (td->o.fsync_blocks && td->io_issues[DDIR_WRITE] &&
760749
!(td->io_issues[DDIR_WRITE] % td->o.fsync_blocks))
@@ -768,6 +757,30 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td)
768757
!(td->io_issues[DDIR_WRITE] % td->sync_file_range_nr))
769758
return DDIR_SYNC_FILE_RANGE;
770759
}
760+
return DDIR_INVAL;
761+
}
762+
763+
bool ddir_is_sync(const struct thread_data *td)
764+
{
765+
return get_sync_ddir(td) != DDIR_INVAL;
766+
}
767+
768+
/*
769+
* Return the data direction for the next io_u. If the job is a
770+
* mixed read/write workload, check the rwmix cycle and switch if
771+
* necessary.
772+
*/
773+
static enum fio_ddir get_rw_ddir(struct thread_data *td)
774+
{
775+
enum fio_ddir ddir;
776+
777+
/*
778+
* See if it's time to fsync/fdatasync/sync_file_range first,
779+
* and if not then move on to check regular I/Os.
780+
*/
781+
ddir = get_sync_ddir(td);
782+
if (ddir != DDIR_INVAL)
783+
return ddir;
771784

772785
if (td_rw(td)) {
773786
/*

io_u.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ bool queue_full(const struct thread_data *);
169169
int do_io_u_sync(const struct thread_data *, struct io_u *);
170170
int do_io_u_trim(struct thread_data *, struct io_u *);
171171

172+
bool ddir_is_sync(const struct thread_data *);
173+
172174
#ifdef FIO_INC_DEBUG
173175
static inline void dprint_io_u(struct io_u *io_u, const char *p)
174176
{

0 commit comments

Comments
 (0)