Previously O_ATOMIC support was added in commit d01612f3ae25 ("Add support for O_ATOMIC"). But support was removed in commit a25ba6c64fe1 ("Get rid of O_ATOMIC"), as support was never added in the Linux kernel. Linux kernel 6.11 will add support for RWF_ATOMIC, which can be supported for various ioengines. See latest man pages for details. The plumbing was left in place for thread option oatomic, so that will be reused. Add a flag to say whether an engine supports atomic writes, and reject when oatomic is set for an engine which does not support atomic writes. This is a change in behaviour, as since commit a25ba6c64fe1 ("Get rid of O_ATOMIC"), this oatomic has been ignored. However, it is better to tell the user that their ioengine of choice does not support atomic writes. Today RWF_ATOMIC is only supported for direct-IO. In future it may be supported for buffered IO. As such, do not auto-set odirect=1 when oatomic==1. Signed-off-by: John Garry <john.g.garry@xxxxxxxxxx> --- init.c | 11 +++++++++++ ioengines.h | 2 ++ options.c | 2 ++ os/os-linux.h | 1 + 4 files changed, 16 insertions(+) diff --git a/init.c b/init.c index 414535cc..bad8b75b 100644 --- a/init.c +++ b/init.c @@ -855,6 +855,17 @@ static int fixup_options(struct thread_data *td) o->max_bs[DDIR_WRITE]); } + if (td->o.oatomic) { + if (!td_ioengine_flagged(td, FIO_ATOMICWRITES)) { + log_err("fio: engine does not support atomic writes\n"); + td->o.oatomic = 0; + ret |= 1; + } + + if (!td_write(td)) + td->o.oatomic = 0; + } + if (o->pre_read) { if (o->invalidate_cache) o->invalidate_cache = 0; diff --git a/ioengines.h b/ioengines.h index b9834fec..1531cd89 100644 --- a/ioengines.h +++ b/ioengines.h @@ -96,6 +96,7 @@ enum { __FIO_RO_NEEDS_RW_OPEN, /* open files in rw mode even if we have a read job; only affects ioengines using generic_open_file */ __FIO_MULTI_RANGE_TRIM, /* ioengine supports trim with more than one range */ + __FIO_ATOMICWRITES, /* ioengine supports atomic writes */ __FIO_IOENGINE_F_LAST, /* not a real bit; used to count number of bits */ }; @@ -120,6 +121,7 @@ enum fio_ioengine_flags { FIO_SKIPPABLE_IOMEM_ALLOC = 1 << __FIO_SKIPPABLE_IOMEM_ALLOC, FIO_RO_NEEDS_RW_OPEN = 1 << __FIO_RO_NEEDS_RW_OPEN, FIO_MULTI_RANGE_TRIM = 1 << __FIO_MULTI_RANGE_TRIM, + FIO_ATOMICWRITES = 1 << __FIO_ATOMICWRITES, }; /* diff --git a/options.c b/options.c index 5a6b0a06..95567de6 100644 --- a/options.c +++ b/options.c @@ -2926,6 +2926,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IO_TYPE, }, +#ifdef FIO_HAVE_RWF_ATOMIC { .name = "atomic", .lname = "Atomic I/O", @@ -2936,6 +2937,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IO_TYPE, }, +#endif { .name = "buffered", .lname = "Buffered I/O", diff --git a/os/os-linux.h b/os/os-linux.h index 010a8291..ead8295c 100644 --- a/os/os-linux.h +++ b/os/os-linux.h @@ -62,6 +62,7 @@ #define FIO_HAVE_BYTEORDER_FUNCS #define FIO_HAVE_PWRITEV2 #define FIO_HAVE_SHM_ATTACH_REMOVED +#define FIO_HAVE_RWF_ATOMIC #ifdef MAP_HUGETLB #define FIO_HAVE_MMAP_HUGE -- 2.31.1