From 4c20310db81ee3aca81ada23ce3c671e72c6f2ae Mon Sep 17 00:00:00 2001 From: ningtao <63358@sangfor.com> Date: Thu, 12 Jul 2018 17:44:33 +0800 Subject: [PATCH] librbd:optionally support FUA (force unit access) on write requests Fixes: http://tracker.ceph.com/issues/19366 Signed-off-by: ningtao <63358@sangfor.com> --- src/include/rados/librados.h | 2 ++ src/osdc/ObjectCacher.cc | 2 +- src/test/librbd/test_librbd.cc | 49 ++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 03ad017464dca..e7cacbb2402aa 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -81,6 +81,8 @@ enum { LIBRADOS_OP_FLAG_FADVISE_DONTNEED = 0x20, // indicate read/write data will not accessed again (by *this* client) LIBRADOS_OP_FLAG_FADVISE_NOCACHE = 0x40, + // optionally support FUA (force unit access) on write requests + LIBRADOS_OP_FLAG_FADVISE_FUA = 0x80, }; #if __GNUC__ >= 4 diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index b577edd95b9b5..e99b1e13e4eef 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -1849,7 +1849,7 @@ int ObjectCacher::_wait_for_write(OSDWrite *wr, uint64_t len, ObjectSet *oset, assert(trace != nullptr); int ret = 0; - if (max_dirty > 0) { + if (max_dirty > 0 && !(wr->fadvise_flags & LIBRADOS_OP_FLAG_FADVISE_FUA)) { if (block_writes_upfront) { maybe_wait_for_writeback(len, trace); if (onfreespace) diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index df671728eaf3a..4d2448cade987 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -2345,6 +2345,55 @@ TEST_F(TestLibRBD, TestEmptyDiscard) rados_ioctx_destroy(ioctx); } +TEST_F(TestLibRBD, TestFUA) +{ + rados_ioctx_t ioctx; + rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx); + + rbd_image_t image_write; + rbd_image_t image_read; + int order = 0; + std::string name = get_temp_image_name(); + uint64_t size = 2 << 20; + size_t num_aios = 256; + + ASSERT_EQ(0, create_image(ioctx, name.c_str(), size, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image_write, NULL)); + ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image_read, NULL)); + + // enable writeback cache + rbd_flush(image_write); + + char test_data[TEST_IO_SIZE + 1]; + int i; + + for (i = 0; i < TEST_IO_SIZE; ++i) { + test_data[i] = (char) (rand() % (126 - 33) + 33); + } + test_data[TEST_IO_SIZE] = '\0'; + for (i = 0; i < 5; ++i) + ASSERT_PASSED(write_test_data, image_write, test_data, + TEST_IO_SIZE * i, TEST_IO_SIZE, LIBRADOS_OP_FLAG_FADVISE_FUA); + + for (i = 0; i < 5; ++i) + ASSERT_PASSED(read_test_data, image_read, test_data, + TEST_IO_SIZE * i, TEST_IO_SIZE, 0); + + for (i = 5; i < 10; ++i) + ASSERT_PASSED(aio_write_test_data, image_write, test_data, + TEST_IO_SIZE * i, TEST_IO_SIZE, LIBRADOS_OP_FLAG_FADVISE_FUA); + + for (i = 5; i < 10; ++i) + ASSERT_PASSED(aio_read_test_data, image_read, test_data, + TEST_IO_SIZE * i, TEST_IO_SIZE, 0); + + ASSERT_PASSED(validate_object_map, image_write); + ASSERT_PASSED(validate_object_map, image_read); + ASSERT_EQ(0, rbd_close(image_write)); + ASSERT_EQ(0, rbd_close(image_read)); + ASSERT_EQ(0, rbd_remove(ioctx, name.c_str())); + rados_ioctx_destroy(ioctx); +} void simple_write_cb_pp(librbd::completion_t cb, void *arg) { -- 2.39.5