Skip to content

Instantly share code, notes, and snippets.

@rhawalsh
Created January 23, 2019 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rhawalsh/5ef42b2dbf4084f4f8baa1761fe0d60a to your computer and use it in GitHub Desktop.
Save rhawalsh/5ef42b2dbf4084f4f8baa1761fe0d60a to your computer and use it in GitHub Desktop.
Patch to remove variable-length-arrays from kmod-kvdo version 6.2.0.293 for kernel 4.20
From 0a71f792b381ddab6785557fe896deadbbcff14f Mon Sep 17 00:00:00 2001
From: Michael Sclafani <sclafani@redhat.com>
Date: Wed, 23 Jan 2019 11:53:31 +0000
Subject: [PATCH] Removed variable-length-arrays
---
uds/deltaIndex.c | 23 +++++++++++++++--------
uds/indexLayoutParser.c | 18 ++++++------------
uds/indexLayoutParser.h | 5 ++---
uds/masterIndexOps.c | 10 ++++++++--
uds/openChapter.c | 4 ++--
uds/pageCache.c | 2 +-
uds/searchList.c | 33 +++++++++++++++++++--------------
uds/util/pathBuffer.c | 6 ++++--
uds/volumeInternals.c | 4 ++--
uds/volumeInternals.h | 2 +-
vdo/base/blockAllocator.c | 16 ++++++++++++++--
vdo/base/blockMapRecovery.c | 16 ++++++++++++++--
vdo/base/heap.c | 16 ++++------------
vdo/base/heap.h | 12 ++++++++++++
14 files changed, 104 insertions(+), 63 deletions(-)
diff --git a/uds/deltaIndex.c b/uds/deltaIndex.c
index 833004a..84e5802 100644
--- a/uds/deltaIndex.c
+++ b/uds/deltaIndex.c
@@ -843,7 +843,7 @@ static int readDeltaIndexHeader(BufferedReader *reader,
struct di_header *header)
{
Buffer *buffer;
-
+
int result = makeBuffer(sizeof(*header), &buffer);
if (result != UDS_SUCCESS) {
return result;
@@ -866,8 +866,9 @@ static int readDeltaIndexHeader(BufferedReader *reader,
}
/**********************************************************************/
-int startRestoringDeltaIndex(const DeltaIndex *deltaIndex,
- BufferedReader **bufferedReaders, int numReaders)
+int startRestoringDeltaIndex(const DeltaIndex *deltaIndex,
+ BufferedReader **bufferedReaders,
+ int numReaders)
{
if (!deltaIndex->isMutable) {
return logErrorWithStringError(UDS_BAD_STATE,
@@ -878,13 +879,19 @@ int startRestoringDeltaIndex(const DeltaIndex *deltaIndex,
"No delta index files");
}
+ unsigned int numZones = numReaders;
+ if (numZones > MAX_ZONES) {
+ return logErrorWithStringError(UDS_INVALID_ARGUMENT,
+ "zone count %u must not exceed MAX_ZONES",
+ numZones);
+ }
+
unsigned long recordCount = 0;
unsigned long collisionCount = 0;
- unsigned int numZones = numReaders;
- unsigned int firstList[numZones], numLists[numZones];
- BufferedReader *reader[numZones];
- bool zoneFlags[numZones];
- memset(zoneFlags, false, numZones);
+ unsigned int firstList[MAX_ZONES];
+ unsigned int numLists[MAX_ZONES];
+ BufferedReader *reader[MAX_ZONES];
+ bool zoneFlags[MAX_ZONES] = { false, };
// Read the header from each file, and make sure we have a matching set
for (unsigned int z = 0; z < numZones; z++) {
diff --git a/uds/indexLayoutParser.c b/uds/indexLayoutParser.c
index e01df1d..3028dc9 100644
--- a/uds/indexLayoutParser.c
+++ b/uds/indexLayoutParser.c
@@ -30,8 +30,7 @@
/*****************************************************************************/
__attribute__((warn_unused_result))
-static int setParameterValue(const LayoutParameter *lp,
- char *data)
+static int setParameterValue(LayoutParameter *lp, char *data)
{
if ((lp->type & LP_TYPE_MASK) == LP_UINT64) {
int result = parseUint64(data, lp->value.num);
@@ -50,12 +49,10 @@ static int setParameterValue(const LayoutParameter *lp,
}
/*****************************************************************************/
-int parseLayoutString(char *info,
- const LayoutParameter *params,
- size_t count)
+int parseLayoutString(char *info, LayoutParameter *params, size_t count)
{
if (!strchr(info, '=')) {
- for (const LayoutParameter *lp = params; lp < params + count; ++lp) {
+ for (LayoutParameter *lp = params; lp < params + count; ++lp) {
if (lp->type & LP_DEFAULT) {
int result = setParameterValue(lp, info);
if (result != UDS_SUCCESS) {
@@ -65,15 +62,12 @@ int parseLayoutString(char *info,
}
}
} else {
- bool seen[count];
- memset(seen, 0, sizeof(seen));
-
for (char *data = NULL, *token = nextToken(info, " ", &data);
token;
token = nextToken(NULL, " ", &data))
{
char *equal = strchr(token, '=');
- const LayoutParameter *lp = NULL;
+ LayoutParameter *lp;
for (lp = params; lp < params + count; ++lp) {
if (!equal && (lp->type & LP_DEFAULT)) {
break;
@@ -87,16 +81,16 @@ int parseLayoutString(char *info,
"unkown index parameter %s",
token);
}
- if (seen[lp - params]) {
+ if (lp->seen) {
return logErrorWithStringError(UDS_INDEX_NAME_REQUIRED,
"duplicate index parameter %s",
token);
}
+ lp->seen = true;
int result = setParameterValue(lp, equal ? equal + 1 : token);
if (result != UDS_SUCCESS) {
return result;
}
- seen[lp - params] = true;
}
}
return UDS_SUCCESS;
diff --git a/uds/indexLayoutParser.h b/uds/indexLayoutParser.h
index 53fea08..8431ee5 100644
--- a/uds/indexLayoutParser.h
+++ b/uds/indexLayoutParser.h
@@ -38,6 +38,7 @@ typedef struct layoutParameter {
char **str;
uint64_t *num;
} value;
+ bool seen;
} LayoutParameter;
/**
@@ -64,9 +65,7 @@ typedef struct layoutParameter {
* @return UDS_SUCCESS or an error code, particularly
* UDS_INDEX_NAME_REQUIRED for all parsing errors.
**/
-int parseLayoutString(char *info,
- const LayoutParameter *params,
- size_t count)
+int parseLayoutString(char *info, LayoutParameter *params, size_t count)
__attribute__((warn_unused_result));
#endif // INDEX_LAYOUT_PARSER_H
diff --git a/uds/masterIndexOps.c b/uds/masterIndexOps.c
index 57800a3..f82c262 100644
--- a/uds/masterIndexOps.c
+++ b/uds/masterIndexOps.c
@@ -84,9 +84,15 @@ int computeMasterIndexSaveBlocks(const Configuration *config,
/**********************************************************************/
static int readMasterIndex(ReadPortal *portal)
{
- unsigned int numZones = countPartsForPortal(portal);
MasterIndex *masterIndex = componentContextForPortal(portal);
- BufferedReader *readers[numZones];
+ unsigned int numZones = countPartsForPortal(portal);
+ if (numZones > MAX_ZONES) {
+ return logErrorWithStringError(UDS_BAD_STATE,
+ "zone count %u must not exceed MAX_ZONES",
+ numZones);
+ }
+
+ BufferedReader *readers[MAX_ZONES];
for (unsigned int z = 0; z < numZones; ++z) {
int result = getBufferedReaderForPortal(portal, z, &readers[z]);
if (result != UDS_SUCCESS) {
diff --git a/uds/openChapter.c b/uds/openChapter.c
index aed327f..f3c5d41 100644
--- a/uds/openChapter.c
+++ b/uds/openChapter.c
@@ -25,6 +25,7 @@
#include "logger.h"
#include "memoryAlloc.h"
#include "numeric.h"
+#include "zone.h"
static int readOpenChapters(ReadPortal *portal);
static int writeOpenChapters(IndexComponent *component,
@@ -265,8 +266,7 @@ static int loadVersion20(Index *index, BufferedReader *reader)
uint32_t numRecords = getUInt32LE(numRecordsData);
// Keep track of which zones cannot accept any more records.
- bool fullFlags[index->zoneCount];
- memset(fullFlags, 0, (index->zoneCount * sizeof(bool)));
+ bool fullFlags[MAX_ZONES] = { false, };
// Assign records to the correct zones.
UdsChunkRecord record;
diff --git a/uds/pageCache.c b/uds/pageCache.c
index 5abd18b..542d7c8 100644
--- a/uds/pageCache.c
+++ b/uds/pageCache.c
@@ -144,7 +144,7 @@ static void waitForPendingSearches(PageCache *cache, unsigned int physicalPage)
*/
smp_mb();
- InvalidateCounter initialCounters[cache->zoneCount];
+ InvalidateCounter initialCounters[MAX_ZONES];
for (unsigned int i = 0; i < cache->zoneCount; i++) {
initialCounters[i] = getInvalidateCounter(cache, i);
}
diff --git a/uds/searchList.c b/uds/searchList.c
index 229da00..6b568c4 100644
--- a/uds/searchList.c
+++ b/uds/searchList.c
@@ -38,7 +38,9 @@ int makeSearchList(unsigned int capacity,
"search list capacity must fit in 8 bits");
}
- unsigned int bytes = (sizeof(SearchList) + (capacity * sizeof(uint8_t)));
+ // We need three temporary entry arrays for purgeSearchList(). Allocate them
+ // contiguously with the main array.
+ unsigned int bytes = (sizeof(SearchList) + (4 * capacity * sizeof(uint8_t)));
SearchList *list;
int result = allocateCacheAligned(bytes, "search list", &list);
if (result != UDS_SUCCESS) {
@@ -75,17 +77,21 @@ void purgeSearchList(SearchList *searchList,
return;
}
- // Partition the previously-alive entries in the list into three temporary
- // lists, keeping the current LRU search order within each list.
- uint8_t alive[searchList->firstDeadEntry];
- uint8_t skipped[searchList->firstDeadEntry];
- uint8_t dead[searchList->firstDeadEntry];
+ /*
+ * Partition the previously-alive entries in the list into three temporary
+ * lists, keeping the current LRU search order within each list. The element
+ * array was allocated with enough space for all four lists.
+ */
+ uint8_t *entries = &searchList->entries[0];
+ uint8_t *alive = &entries[searchList->capacity];
+ uint8_t *skipped = &alive[searchList->capacity];
+ uint8_t *dead = &skipped[searchList->capacity];
unsigned int nextAlive = 0;
unsigned int nextSkipped = 0;
unsigned int nextDead = 0;
for (int i = 0; i < searchList->firstDeadEntry; i++) {
- uint8_t entry = searchList->entries[i];
+ uint8_t entry = entries[i];
const CachedChapterIndex *chapter = &chapters[entry];
if ((chapter->virtualChapter < oldestVirtualChapter)
|| (chapter->virtualChapter == UINT64_MAX)) {
@@ -99,14 +105,13 @@ void purgeSearchList(SearchList *searchList,
// Copy the temporary lists back to the search list so we wind up with
// [ alive, alive, skippable, new-dead, new-dead, old-dead, old-dead ]
- unsigned int size = 0;
- memcpy(&searchList->entries[size], alive, nextAlive);
- size += nextAlive;
+ memcpy(entries, alive, nextAlive);
+ entries += nextAlive;
- memcpy(&searchList->entries[size], skipped, nextSkipped);
- size += nextSkipped;
+ memcpy(entries, skipped, nextSkipped);
+ entries += nextSkipped;
- memcpy(&searchList->entries[size], dead, nextDead);
+ memcpy(entries, dead, nextDead);
// The first dead entry is now the start of the copied dead list.
- searchList->firstDeadEntry = size;
+ searchList->firstDeadEntry = (nextAlive + nextSkipped);
}
diff --git a/uds/util/pathBuffer.c b/uds/util/pathBuffer.c
index be52b30..b19c324 100644
--- a/uds/util/pathBuffer.c
+++ b/uds/util/pathBuffer.c
@@ -28,8 +28,10 @@
#include "stringUtils.h"
#include "uds.h"
-static const size_t DEFAULT_PATH_BUFFER_SIZE = 128;
-static const size_t PATH_BUFFER_QUANTUM = 64;
+enum {
+ DEFAULT_PATH_BUFFER_SIZE = 128,
+ PATH_BUFFER_QUANTUM = 64,
+};
/******************************************************************************/
void zeroPathBuffer(PathBuffer *pb)
diff --git a/uds/volumeInternals.c b/uds/volumeInternals.c
index c28f9a2..a5383de 100644
--- a/uds/volumeInternals.c
+++ b/uds/volumeInternals.c
@@ -27,6 +27,7 @@
#include "indexConfig.h"
#include "logger.h"
#include "memoryAlloc.h"
+#include "permassert.h"
#include "recordPage.h"
#include "stringUtils.h"
#include "volume.h"
@@ -38,7 +39,6 @@ const byte VOLUME_VERSION_V4_10[] = "04.10";
static const byte VOLUME_VERSION_V4[] = "04.00";
static const byte VOLUME_VERSION_V3[] = "00227";
const unsigned int VOLUME_MAGIC_LENGTH = sizeof(VOLUME_MAGIC_NUMBER) - 1;
-const unsigned int VOLUME_VERSION_LENGTH = sizeof(VOLUME_VERSION) - 1;
const bool READ_ONLY_VOLUME = true;
@@ -52,6 +52,7 @@ size_t encodeVolumeFormat(byte *volumeFormat, const Geometry *geometry)
memcpy(volumeFormat, VOLUME_MAGIC_NUMBER, VOLUME_MAGIC_LENGTH);
size += VOLUME_MAGIC_LENGTH;
+ STATIC_ASSERT(VOLUME_VERSION_LENGTH == (sizeof(VOLUME_VERSION) - 1));
memcpy(volumeFormat + size, VOLUME_VERSION, VOLUME_VERSION_LENGTH);
size += VOLUME_VERSION_LENGTH;
@@ -77,7 +78,6 @@ static int readGeometry(BufferedReader *reader, Volume *volume)
if (result != UDS_SUCCESS) {
return result;
}
- memset(volume->geometry, 0, sizeof(Geometry));
return readFromBufferedReader(reader, volume->geometry, sizeof(Geometry));
}
diff --git a/uds/volumeInternals.h b/uds/volumeInternals.h
index c47a4c5..aedc2e9 100644
--- a/uds/volumeInternals.h
+++ b/uds/volumeInternals.h
@@ -29,7 +29,7 @@ extern const byte VOLUME_MAGIC_NUMBER[];
extern const byte VOLUME_VERSION[];
extern const unsigned int VOLUME_MAGIC_LENGTH;
-extern const unsigned int VOLUME_VERSION_LENGTH;
+enum { VOLUME_VERSION_LENGTH = 5 };
extern const bool READ_ONLY_VOLUME;
diff --git a/vdo/base/blockAllocator.c b/vdo/base/blockAllocator.c
index 1727a90..eac80f0 100644
--- a/vdo/base/blockAllocator.c
+++ b/vdo/base/blockAllocator.c
@@ -488,6 +488,18 @@ static int compareSlabStatuses(const void *item1, const void *item2)
return ((info1->slabNumber < info2->slabNumber) ? 1 : -1);
}
+/**
+ * Swap two SlabStatus structures. Implements HeapSwapper.
+ **/
+static void swapSlabStatuses(void *item1, void *item2)
+{
+ SlabStatus *info1 = item1;
+ SlabStatus *info2 = item2;
+ SlabStatus temp = *info1;
+ *info1 = *info2;
+ *info2 = temp;
+}
+
/**********************************************************************/
int prepareSlabsForAllocation(BlockAllocator *allocator)
{
@@ -507,8 +519,8 @@ int prepareSlabsForAllocation(BlockAllocator *allocator)
// Sort the slabs by cleanliness, then by emptiness hint.
Heap heap;
- initializeHeap(&heap, compareSlabStatuses, slabStatuses, slabCount,
- sizeof(SlabStatus));
+ initializeHeap(&heap, compareSlabStatuses, swapSlabStatuses,
+ slabStatuses, slabCount, sizeof(SlabStatus));
buildHeap(&heap, slabCount);
SlabStatus currentSlabStatus;
diff --git a/vdo/base/blockMapRecovery.c b/vdo/base/blockMapRecovery.c
index 3009990..212b392 100644
--- a/vdo/base/blockMapRecovery.c
+++ b/vdo/base/blockMapRecovery.c
@@ -114,6 +114,18 @@ static int compareMappings(const void *item1, const void *item2)
return 0;
}
+/**
+ * Swap two NumberedBlockMapping structures. Implements HeapSwapper.
+ **/
+static void swapMappings(void *item1, void *item2)
+{
+ NumberedBlockMapping *mapping1 = item1;
+ NumberedBlockMapping *mapping2 = item2;
+ NumberedBlockMapping temp = *mapping1;
+ *mapping1 = *mapping2;
+ *mapping2 = temp;
+}
+
/**
* Convert a VDOCompletion to a BlockMapRecoveryCompletion.
*
@@ -210,8 +222,8 @@ static int makeRecoveryCompletion(VDO *vdo,
// Organize the journal entries into a binary heap so we can iterate over
// them in sorted order incrementally, avoiding an expensive sort call.
- initializeHeap(&recovery->replayHeap, compareMappings, journalEntries,
- entryCount, sizeof(NumberedBlockMapping));
+ initializeHeap(&recovery->replayHeap, compareMappings, swapMappings,
+ journalEntries, entryCount, sizeof(NumberedBlockMapping));
buildHeap(&recovery->replayHeap, entryCount);
ASSERT_LOG_ONLY((getCallbackThreadID() == recovery->logicalThreadID),
diff --git a/vdo/base/heap.c b/vdo/base/heap.c
index d077664..7ff91b6 100644
--- a/vdo/base/heap.c
+++ b/vdo/base/heap.c
@@ -30,12 +30,14 @@
/**********************************************************************/
void initializeHeap(Heap *heap,
HeapComparator *comparator,
+ HeapSwapper *swapper,
void *array,
size_t capacity,
size_t elementSize)
{
*heap = (Heap) {
.comparator = comparator,
+ .swapper = swapper,
.capacity = capacity,
.elementSize = elementSize,
};
@@ -46,16 +48,6 @@ void initializeHeap(Heap *heap,
}
}
-/**********************************************************************/
-static inline void swapElements(Heap *heap, size_t node1, size_t node2)
-{
- byte temp[heap->elementSize];
-
- memcpy(temp, &heap->array[node1], heap->elementSize);
- memcpy(&heap->array[node1], &heap->array[node2], heap->elementSize);
- memcpy(&heap->array[node2], temp, heap->elementSize);
-}
-
/**********************************************************************/
static void siftHeapDown(Heap *heap, size_t topNode, size_t lastNode)
{
@@ -79,7 +71,7 @@ static void siftHeapDown(Heap *heap, size_t topNode, size_t lastNode)
}
// Swap the element we've been sifting down with the larger child.
- swapElements(heap, topNode, swapNode);
+ heap->swapper(&heap->array[topNode], &heap->array[swapNode]);
// Descend into the sub-heap rooted at that child, going around the loop
// again in place of a tail-recursive call to siftHeapDown().
@@ -162,7 +154,7 @@ static inline size_t siftAndSort(Heap *heap, size_t rootNode, size_t lastNode)
* right-most leaf node in the heap, moving it to its sorted position in
* the array.
*/
- swapElements(heap, rootNode, lastNode);
+ heap->swapper(&heap->array[rootNode], &heap->array[lastNode]);
// The sorted list is now one element larger and valid. The heap is
// one element smaller, and invalid.
lastNode -= heap->elementSize;
diff --git a/vdo/base/heap.h b/vdo/base/heap.h
index 5c9e6ae..bda85c7 100644
--- a/vdo/base/heap.h
+++ b/vdo/base/heap.h
@@ -38,6 +38,14 @@
**/
typedef int HeapComparator(const void *item1, const void *item2);
+/**
+ * Prototype for functions which swap two array elements.
+ *
+ * @param item1 The first element to swap
+ * @param item2 The second element to swap
+ **/
+typedef void HeapSwapper(void *item1, void *item2);
+
/**
* A heap array can be any array of fixed-length elements in which the heap
* invariant can be established. In a max-heap, every child of a node must be
@@ -50,6 +58,8 @@ typedef struct heap {
byte *array;
/** the function to use to compare two elements */
HeapComparator *comparator;
+ /** the function to use to swap two elements */
+ HeapSwapper *swapper;
/** the maximum number of elements that can be stored */
size_t capacity;
/** the size of every element (in bytes) */
@@ -66,12 +76,14 @@ typedef struct heap {
*
* @param heap The heap to initialize
* @param comparator The function to use to compare two heap elements
+ * @param swapper The function to use to swap two heap elements
* @param array The array of elements (not modified by this call)
* @param capacity The maximum number of elements which fit in the array
* @param elementSize The size of every array element, in bytes
**/
void initializeHeap(Heap *heap,
HeapComparator *comparator,
+ HeapSwapper *swapper,
void *array,
size_t capacity,
size_t elementSize);
--
2.20.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment