diff --git a/kvdo.spec b/kvdo.spec index 813f7ce8..1ff4c2d0 100644 --- a/kvdo.spec +++ b/kvdo.spec @@ -1,6 +1,6 @@ %define spec_release 1 %define kmod_name kvdo -%define kmod_driver_version 6.2.6.14 +%define kmod_driver_version 6.2.7.9 %define kmod_rpm_release %{spec_release} %define kmod_kernel_version 3.10.0-693.el7 @@ -96,5 +96,8 @@ rm -rf $RPM_BUILD_ROOT %{_usr}/src/%{kmod_name}-%{version} %changelog -* Thu Feb 10 2022 - Red Hat VDO Team - 6.2.6.14-1 -- Fixed stack frame warnings when building with the debug kernel. +* Wed May 04 2022 - Red Hat VDO Team - 6.2.7.9-1 +- Fixed bug which could result in empty flushes being issued to the storage + below vdo while suspended. +- Fixed syntax mismatch which prevented lvm from being able to configure a + 512MB UDS index. diff --git a/uds/Makefile b/uds/Makefile index 3a9c2f99..4f323d13 100644 --- a/uds/Makefile +++ b/uds/Makefile @@ -1,4 +1,4 @@ -UDS_VERSION = 8.0.4.2 +UDS_VERSION = 8.0.5.1 SOURCES = $(notdir $(wildcard $(src)/*.c)) murmur/MurmurHash3.c SOURCES += $(addprefix util/,$(notdir $(wildcard $(src)/util/*.c))) diff --git a/vdo/Makefile b/vdo/Makefile index bbfcdbe9..181703ba 100644 --- a/vdo/Makefile +++ b/vdo/Makefile @@ -1,4 +1,4 @@ -VDO_VERSION = 6.2.6.14 +VDO_VERSION = 6.2.7.9 VDO_VERSION_MAJOR = $(word 1,$(subst ., ,$(VDO_VERSION))) VDO_VERSION_MINOR = $(word 2,$(subst ., ,$(VDO_VERSION))) diff --git a/vdo/kernel/kernelLayer.c b/vdo/kernel/kernelLayer.c index fdf779b9..082b607e 100644 --- a/vdo/kernel/kernelLayer.c +++ b/vdo/kernel/kernelLayer.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * - * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelLayer.c#38 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelLayer.c#39 $ */ #include "kernelLayer.h" @@ -1056,7 +1056,7 @@ int modifyKernelLayer(KernelLayer *layer, return result; } } - + return VDO_SUCCESS; } @@ -1303,6 +1303,7 @@ int suspendKernelLayer(KernelLayer *layer) * the suspend, even if it hasn't been flushed yet. */ waitForNoRequestsActive(layer); + drainKVDOFlushes(layer); int result = synchronousFlush(layer); if (result != VDO_SUCCESS) { setKVDOReadOnly(&layer->kvdo, result); diff --git a/vdo/kernel/kernelLayer.h b/vdo/kernel/kernelLayer.h index 265e8fce..3fd2b717 100644 --- a/vdo/kernel/kernelLayer.h +++ b/vdo/kernel/kernelLayer.h @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * - * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelLayer.h#18 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelLayer.h#19 $ */ #ifndef KERNELLAYER_H @@ -132,6 +132,9 @@ struct kernelLayer { // for REQ_FLUSH processing struct bio_list waitingFlushes; KVDOFlush *spareKVDOFlush; + uint32_t activeFlushCount; + bool flushesDraining; + struct completion flushCompletion; spinlock_t flushLock; Jiffies flushArrivalTime; /** @@ -150,8 +153,8 @@ struct kernelLayer { /** Optional work queue for calling bio_endio. */ KvdoWorkQueue *bioAckQueue; /** Underlying block device info. */ - uint64_t startingSectorOffset; - VolumeGeometry geometry; + uint64_t startingSectorOffset; + VolumeGeometry geometry; // Memory allocation BufferPool *dataKVIOPool; struct bio_set *bioset; diff --git a/vdo/kernel/kvdoFlush.c b/vdo/kernel/kvdoFlush.c index ce6aa5af..cc704fee 100644 --- a/vdo/kernel/kvdoFlush.c +++ b/vdo/kernel/kvdoFlush.c @@ -16,11 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * - * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kvdoFlush.c#6 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kvdoFlush.c#7 $ */ #include "kvdoFlush.h" +#include + #include "logger.h" #include "memoryAlloc.h" @@ -131,7 +133,7 @@ void launchKVDOFlush(KernelLayer *layer, BIO *bio) // We have flushes to start. Capture them in the KVDOFlush object. initializeKVDOFlush(kvdoFlush, layer); - + layer->activeFlushCount++; spin_unlock(&layer->flushLock); // Finish launching the flushes. @@ -152,9 +154,17 @@ static void releaseKVDOFlush(KVDOFlush *kvdoFlush) KernelLayer *layer = kvdoFlush->layer; bool relaunchFlush = false; bool freeFlush = false; + bool drained = false; spin_lock(&layer->flushLock); + if (bio_list_empty(&layer->waitingFlushes)) { + --layer->activeFlushCount; + if ((layer->activeFlushCount == 0) && layer->flushesDraining) { + layer->flushesDraining = false; + drained = true; + } + // Nothing needs to be started. Save one spare KVDOFlush object. if (layer->spareKVDOFlush == NULL) { // Make the new spare all zero, just like a newly allocated one. @@ -176,6 +186,10 @@ static void releaseKVDOFlush(KVDOFlush *kvdoFlush) } else if (freeFlush) { FREE(kvdoFlush); } + + if (drained) { + complete(&layer->flushCompletion); + } } /** @@ -220,6 +234,36 @@ void kvdoCompleteFlush(VDOFlush **kfp) } } +/**********************************************************************/ +void drainKVDOFlushes(KernelLayer *layer) +{ + bool drained; + + spin_lock(&layer->flushLock); + if (layer->activeFlushCount == 0) { + ASSERT_LOG_ONLY(bio_list_empty(&layer->waitingFlushes), + "no flush bios are waiting when flushes are inactive"); + drained = true; + } else { + layer->flushesDraining = true; + init_completion(&layer->flushCompletion); + drained = false; + } + spin_unlock(&layer->flushLock); + + if (drained) { + return; + } + + // Using the "interruptible" interface means that Linux will not log a + // message when we wait for more than 120 seconds. + while (wait_for_completion_interruptible(&layer->flushCompletion) != 0) { + // However, if we get a signal in a user-mode process, we could + // spin... + msleep(1); + } +} + /**********************************************************************/ int synchronousFlush(KernelLayer *layer) { diff --git a/vdo/kernel/kvdoFlush.h b/vdo/kernel/kvdoFlush.h index 6797719a..75da2f7c 100644 --- a/vdo/kernel/kvdoFlush.h +++ b/vdo/kernel/kvdoFlush.h @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * - * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kvdoFlush.h#1 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kvdoFlush.h#2 $ */ #ifndef KVDO_FLUSH_H @@ -61,6 +61,13 @@ void launchKVDOFlush(KernelLayer *layer, BIO *bio); **/ void kvdoCompleteFlush(VDOFlush **kfp); +/** + * Wait until there are no active KVDOFlushes or bios waiting to flush. + * + * @param layer The physical layer + **/ +void drainKVDOFlushes(KernelLayer *layer); + /** * Issue a flush request and wait for it to complete. *