From: Sage Weil Date: Tue, 5 Jan 2016 03:04:28 +0000 (-0500) Subject: os/bluestore/BlockDevice: make flush a no-op if there was no IO X-Git-Tag: v10.0.3~88^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3120cbb9dbb5881d50b5fb4e712e44dc6898ab88;p=ceph.git os/bluestore/BlockDevice: make flush a no-op if there was no IO fdatasync(2) does a cache flush on the device, which we want to avoid if we didn't actually write anything. Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlockDevice.cc b/src/os/bluestore/BlockDevice.cc index 0dbe095fb71d..13607ad2b84c 100644 --- a/src/os/bluestore/BlockDevice.cc +++ b/src/os/bluestore/BlockDevice.cc @@ -46,6 +46,7 @@ BlockDevice::BlockDevice(aio_callback_t cb, void *cbpriv) fs(NULL), aio(false), dio(false), debug_lock("BlockDevice::debug_lock"), ioc_reap_lock("BlockDevice::ioc_reap_lock"), + flush_lock("BlockDevice::flush_lock"), aio_queue(g_conf->bdev_aio_max_queue_depth), aio_callback(cb), aio_callback_priv(cbpriv), @@ -165,7 +166,15 @@ void BlockDevice::close() int BlockDevice::flush() { + // serialize flushers, so that we can avoid weird io_since_flush + // races (w/ multipler flushers). + Mutex::Locker l(flush_lock); + if (io_since_flush.read() == 0) { + dout(10) << __func__ << " no-op (no ios since last flush)" << dendl; + return 0; + } dout(10) << __func__ << " start" << dendl; + io_since_flush.set(0); if (g_conf->bdev_inject_crash) { // sleep for a moment to give other threads a chance to submit or // wait on io that races with a flush. @@ -409,6 +418,8 @@ int BlockDevice::aio_write( ::sync_file_range(fd_buffered, off, len, SYNC_FILE_RANGE_WRITE); } } + + io_since_flush.set(1); return 0; } diff --git a/src/os/bluestore/BlockDevice.h b/src/os/bluestore/BlockDevice.h index f5acc1113d95..77bb8eb49b1a 100644 --- a/src/os/bluestore/BlockDevice.h +++ b/src/os/bluestore/BlockDevice.h @@ -59,6 +59,9 @@ private: vector ioc_reap_queue; atomic_t ioc_reap_count; + Mutex flush_lock; + atomic_t io_since_flush; + FS::aio_queue_t aio_queue; aio_callback_t aio_callback; void *aio_callback_priv;