From 8df6805f0c4eddae59c9edcebeeab885c835f93c Mon Sep 17 00:00:00 2001 From: corwin Date: Fri, 14 Dec 2018 16:49:51 -0500 Subject: [PATCH] Version 6.2.0.293 Note: This is a pre-release version, future versions of VDO may not support VDO devices created with this version. - Improved dmsetup error reporting of invalid thread counts. - Allowed VDO backing devices to specified by device number. - Eliminated memory allocations when suspended. - Improved error handling during suspend. --- kvdo.spec | 6 ++--- uds/Makefile | 2 +- uds/linuxIORegion.c | 11 ++++++++-- uds/linuxIORegion.h | 9 ++++---- vdo/Makefile | 2 +- vdo/kernel/deviceConfig.c | 46 +++++++++++++++++++++++++-------------- vdo/kernel/kernelLayer.c | 15 ++++++++++--- vdo/kernel/kernelVDO.c | 28 +++++++++++++++++++++++- vdo/kernel/kernelVDO.h | 10 ++++++++- vdo/kernel/kvdoFlush.c | 28 ++++++++++++++---------- 10 files changed, 113 insertions(+), 44 deletions(-) diff --git a/kvdo.spec b/kvdo.spec index 8452918a..3608fd9d 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.0.273 +%define kmod_driver_version 6.2.0.293 %define kmod_rpm_release %{spec_release} %define kmod_kernel_version 3.10.0-693.el7 @@ -85,5 +85,5 @@ rm -rf $RPM_BUILD_ROOT %{_usr}/src/%{kmod_name}-%{version}-%{kmod_driver_version}/* %changelog -* Thu Nov 15 2018 - J. corwin Coburn - 6.2.0.273-1 -HASH(0x1d75b98) \ No newline at end of file +* Fri Dec 14 2018 - J. corwin Coburn - 6.2.0.293-1 +HASH(0xb67b20) \ No newline at end of file diff --git a/uds/Makefile b/uds/Makefile index b8829cb5..67de07b4 100644 --- a/uds/Makefile +++ b/uds/Makefile @@ -1,4 +1,4 @@ -UDS_VERSION = 6.2.0.74 +UDS_VERSION = 6.2.0.77 SOURCES = $(notdir $(wildcard $(src)/*.c)) murmur/MurmurHash3.c SOURCES += $(addprefix util/,$(notdir $(wildcard $(src)/util/*.c))) diff --git a/uds/linuxIORegion.c b/uds/linuxIORegion.c index 8e49c6f7..7cbb655a 100644 --- a/uds/linuxIORegion.c +++ b/uds/linuxIORegion.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * - * $Id: //eng/uds-releases/gloria/kernelLinux/uds/linuxIORegion.c#5 $ + * $Id: //eng/uds-releases/gloria/kernelLinux/uds/linuxIORegion.c#6 $ */ #include "linuxIORegion.h" @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -337,7 +338,13 @@ int openLinuxRegion(const char *path, uint64_t size, IORegion **regionPtr) "size not a multiple of blockSize"); } - struct block_device *bdev = blkdev_get_by_path(path, BLK_FMODE, NULL); + struct block_device *bdev; + dev_t device = name_to_dev_t(path); + if (device != 0) { + bdev = blkdev_get_by_dev(device, BLK_FMODE, NULL); + } else { + bdev = blkdev_get_by_path(path, BLK_FMODE, NULL); + } if (IS_ERR(bdev)) { logErrorWithStringError(-PTR_ERR(bdev), "%s is not a block device", path); return UDS_INVALID_ARGUMENT; diff --git a/uds/linuxIORegion.h b/uds/linuxIORegion.h index 6d00a020..c87686ce 100644 --- a/uds/linuxIORegion.h +++ b/uds/linuxIORegion.h @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * - * $Id: //eng/uds-releases/gloria/kernelLinux/uds/linuxIORegion.h#1 $ + * $Id: //eng/uds-releases/gloria/kernelLinux/uds/linuxIORegion.h#2 $ */ #ifndef LINUX_IO_REGION_H @@ -27,9 +27,10 @@ /** * Make an IO region for a block device in the Linux kernel * - * @param [in] path The pathname for the block device - * @param [in] size Size of the block device - * @param [out] regionPtr Where to put the new region. + * @param [in] path The pathname or major:minor device number for + * the block device + * @param [in] size Size of the block device + * @param [out] regionPtr Where to put the new region. * * @return UDS_SUCCESS or an error code. **/ diff --git a/vdo/Makefile b/vdo/Makefile index 58ca3691..a141e98f 100644 --- a/vdo/Makefile +++ b/vdo/Makefile @@ -1,4 +1,4 @@ -VDO_VERSION = 6.2.0.273 +VDO_VERSION = 6.2.0.293 VDO_VERSION_MAJOR = $(word 1,$(subst ., ,$(VDO_VERSION))) VDO_VERSION_MINOR = $(word 2,$(subst ., ,$(VDO_VERSION))) diff --git a/vdo/kernel/deviceConfig.c b/vdo/kernel/deviceConfig.c index e2ea341f..f906d529 100644 --- a/vdo/kernel/deviceConfig.c +++ b/vdo/kernel/deviceConfig.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/deviceConfig.c#9 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/deviceConfig.c#10 $ */ #include "deviceConfig.h" @@ -34,9 +34,11 @@ enum { // If we bump this, update the arrays below TABLE_VERSION = 2, - // Arbitrary limit used when parsing thread-count config spec strings - THREAD_COUNT_LIMIT = 100, - BIO_ROTATION_INTERVAL_LIMIT = 1024, + // Limits used when parsing thread-count config spec strings + BIO_ROTATION_INTERVAL_LIMIT = 1024, + LOGICAL_THREAD_COUNT_LIMIT = 60, + PHYSICAL_THREAD_COUNT_LIMIT = 16, + THREAD_COUNT_LIMIT = 100, // XXX The bio-submission queue configuration defaults are temporarily // still being defined here until the new runtime-based thread // configuration has been fully implemented for managed VDO devices. @@ -210,7 +212,7 @@ static int processOneThreadConfigSpec(const char *threadParamType, unsigned int count, ThreadCountConfig *config) { - // Handle thread parameters other than thread config + // Handle limited thread parameters if (strcmp(threadParamType, "bioRotationInterval") == 0) { if (count == 0) { logError("thread config string error:" @@ -224,8 +226,26 @@ static int processOneThreadConfigSpec(const char *threadParamType, } config->bioRotationInterval = count; return VDO_SUCCESS; + } else if (strcmp(threadParamType, "logical") == 0) { + if (count > LOGICAL_THREAD_COUNT_LIMIT) { + logError("thread config string error: at most %d 'logical' threads" + " are allowed", + LOGICAL_THREAD_COUNT_LIMIT); + return -EINVAL; + } + config->logicalZones = count; + return VDO_SUCCESS; + } else if (strcmp(threadParamType, "physical") == 0) { + if (count > PHYSICAL_THREAD_COUNT_LIMIT) { + logError("thread config string error: at most %d 'physical' threads" + " are allowed", + PHYSICAL_THREAD_COUNT_LIMIT); + return -EINVAL; + } + config->physicalZones = count; + return VDO_SUCCESS; } else { - // Handle thread count parameters + // Handle other thread count parameters if (count > THREAD_COUNT_LIMIT) { logError("thread config string error: at most %d '%s' threads" " are allowed", @@ -233,7 +253,10 @@ static int processOneThreadConfigSpec(const char *threadParamType, return -EINVAL; } - if (strcmp(threadParamType, "cpu") == 0) { + if (strcmp(threadParamType, "hash") == 0) { + config->hashZones = count; + return VDO_SUCCESS; + } else if (strcmp(threadParamType, "cpu") == 0) { if (count == 0) { logError("thread config string error:" " at least one 'cpu' thread required"); @@ -252,15 +275,6 @@ static int processOneThreadConfigSpec(const char *threadParamType, } config->bioThreads = count; return VDO_SUCCESS; - } else if (strcmp(threadParamType, "logical") == 0) { - config->logicalZones = count; - return VDO_SUCCESS; - } else if (strcmp(threadParamType, "physical") == 0) { - config->physicalZones = count; - return VDO_SUCCESS; - } else if (strcmp(threadParamType, "hash") == 0) { - config->hashZones = count; - return VDO_SUCCESS; } } diff --git a/vdo/kernel/kernelLayer.c b/vdo/kernel/kernelLayer.c index 71468f66..533c152c 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#21 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelLayer.c#22 $ */ #include "kernelLayer.h" @@ -1228,9 +1228,18 @@ int suspendKernelLayer(KernelLayer *layer) setKernelLayerState(layer, LAYER_SUSPENDED); - // Attempt to flush all I/O before completing post suspend work. + /* + * Attempt to flush all I/O before completing post suspend work. This is + * needed so that changing write policy upon resume is safe. Also, we think + * a suspended device is expected to have persisted all data written before + * the suspend, even if it hasn't been flushed yet. + */ waitForNoRequestsActive(layer); - return synchronousFlush(layer); + int result = synchronousFlush(layer); + if (result != VDO_SUCCESS) { + setKVDOReadOnly(&layer->kvdo, result); + } + return result; } /**********************************************************************/ diff --git a/vdo/kernel/kernelVDO.c b/vdo/kernel/kernelVDO.c index 0f2e5cec..14fda913 100644 --- a/vdo/kernel/kernelVDO.c +++ b/vdo/kernel/kernelVDO.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/kernelVDO.c#1 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelVDO.c#2 $ */ #include "kernelVDOInternals.h" @@ -27,6 +27,7 @@ #include "statistics.h" #include "threadConfig.h" +#include "threadData.h" #include "vdo.h" #include "vdoClose.h" #include "vdoDebug.h" @@ -258,6 +259,31 @@ bool setKVDOCompressing(KVDO *kvdo, bool enableCompression) return data.wasEnabled; } +/**********************************************************************/ +typedef struct { + int result; +} VDOReadOnlyData; + +/**********************************************************************/ +static void enterReadOnlyModeWork(KvdoWorkItem *item) +{ + SyncQueueWork *work = container_of(item, SyncQueueWork, workItem); + VDOReadOnlyData *data = work->data; + makeVDOReadOnly(getVDO(work->kvdo), data->result, true); + complete(work->completion); +} + +/***********************************************************************/ +void setKVDOReadOnly(KVDO *kvdo, int result) +{ + struct completion readOnlyWait; + VDOReadOnlyData data; + data.result = result; + performKVDOOperation(kvdo, enterReadOnlyModeWork, &data, + getAdminThread(getThreadConfig(kvdo->vdo)), + &readOnlyWait); +} + /** * Does the work of calling the vdo statistics gathering tool * diff --git a/vdo/kernel/kernelVDO.h b/vdo/kernel/kernelVDO.h index 9cdfe2f1..2ac787de 100644 --- a/vdo/kernel/kernelVDO.h +++ b/vdo/kernel/kernelVDO.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/kernelVDO.h#1 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelVDO.h#2 $ */ #ifndef KERNEL_VDO_H @@ -211,6 +211,14 @@ int kvdoPrepareToGrowLogical(KVDO *kvdo, BlockCount logicalCount); */ int kvdoResizeLogical(KVDO *kvdo, BlockCount logicalCount); +/** + * Request the base code go read-only. + * + * @param kvdo The KVDO to be updated + * @param result The error code causing the read only + */ +void setKVDOReadOnly(KVDO *kvdo, int result); + /** * Perform an extended base-code command * diff --git a/vdo/kernel/kvdoFlush.c b/vdo/kernel/kvdoFlush.c index 1a76c2c1..5fb19262 100644 --- a/vdo/kernel/kvdoFlush.c +++ b/vdo/kernel/kvdoFlush.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/kvdoFlush.c#3 $ + * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kvdoFlush.c#4 $ */ #include "kvdoFlush.h" @@ -256,25 +256,29 @@ static void endSynchronousFlush(BIO *bio, int result) /**********************************************************************/ int synchronousFlush(KernelLayer *layer) { - BIO *bio; - int result = createBio(layer, NULL, &bio); - if (result != VDO_SUCCESS) { - return result; - } + BIO bio; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + bio_init(&bio, 0, 0); +#else + bio_init(&bio); +#endif + int result = 0; init_completion(&layer->flushWait); - prepareFlushBIO(bio, layer, getKernelLayerBdev(layer), endSynchronousFlush); - bio->bi_next = NULL; - generic_make_request(bio); + prepareFlushBIO(&bio, layer, getKernelLayerBdev(layer), endSynchronousFlush); + bio.bi_next = NULL; + generic_make_request(&bio); wait_for_completion(&layer->flushWait); #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) - if (getBioResult(bio) != 0) { + if (getBioResult(&bio) != 0) { #else - if (!bio_flagged(bio, BIO_UPTODATE)) { + if (!bio_flagged(&bio, BIO_UPTODATE)) { #endif result = -EIO; } - freeBio(bio, layer); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) + bio_uninit(&bio); +#endif return result; }