|
Packit Service |
75d76b |
/*
|
|
Packit Service |
75d76b |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
75d76b |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
75d76b |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
75d76b |
* of the License, or (at your option) any later version.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
75d76b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
75d76b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
75d76b |
* GNU General Public License for more details.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
75d76b |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
75d76b |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
75d76b |
* 02110-1301, USA.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/slabJournalEraser.c#1 $
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#include "slabJournalEraser.h"
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#include "memoryAlloc.h"
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#include "completion.h"
|
|
Packit Service |
75d76b |
#include "constants.h"
|
|
Packit Service |
75d76b |
#include "extent.h"
|
|
Packit Service |
75d76b |
#include "slab.h"
|
|
Packit Service |
75d76b |
#include "slabDepot.h"
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
typedef struct {
|
|
Packit Service |
75d76b |
VDOCompletion *parent;
|
|
Packit Service |
75d76b |
VDOExtent *extent;
|
|
Packit Service |
75d76b |
char *zeroBuffer;
|
|
Packit Service |
75d76b |
SlabIterator slabs;
|
|
Packit Service |
75d76b |
} SlabJournalEraser;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Free the eraser and finish the parent.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param eraser The eraser that is done
|
|
Packit Service |
75d76b |
* @param result The result to return to the parent
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static void finishErasing(SlabJournalEraser *eraser, int result)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
VDOCompletion *parent = eraser->parent;
|
|
Packit Service |
75d76b |
freeExtent(&eraser->extent);
|
|
Packit Service |
75d76b |
FREE(eraser->zeroBuffer);
|
|
Packit Service |
75d76b |
FREE(eraser);
|
|
Packit Service |
75d76b |
finishCompletion(parent, result);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Finish erasing slab journals with an error.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param completion A completion whose parent is the eraser
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static void handleErasingError(VDOCompletion *completion)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
SlabJournalEraser *eraser = completion->parent;
|
|
Packit Service |
75d76b |
finishErasing(eraser, eraser->extent->completion.result);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Erase the next slab journal.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param extentCompletion A completion whose parent is the eraser
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static void eraseNextSlabJournal(VDOCompletion *extentCompletion)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
SlabJournalEraser *eraser = extentCompletion->parent;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
if (!hasNextSlab(&eraser->slabs)) {
|
|
Packit Service |
75d76b |
finishErasing(eraser, VDO_SUCCESS);
|
|
Packit Service |
75d76b |
return;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
Slab *slab = nextSlab(&eraser->slabs);
|
|
Packit Service |
75d76b |
writeMetadataExtent(eraser->extent, slab->journalOrigin);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**********************************************************************/
|
|
Packit Service |
75d76b |
void eraseSlabJournals(SlabDepot *depot,
|
|
Packit Service |
75d76b |
SlabIterator slabs,
|
|
Packit Service |
75d76b |
VDOCompletion *parent)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
SlabJournalEraser *eraser;
|
|
Packit Service |
75d76b |
int result = ALLOCATE(1, SlabJournalEraser, __func__, &eraser);
|
|
Packit Service |
75d76b |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
75d76b |
finishCompletion(parent, result);
|
|
Packit Service |
75d76b |
return;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
eraser->parent = parent;
|
|
Packit Service |
75d76b |
eraser->slabs = slabs;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
BlockCount journalSize = getSlabConfig(depot)->slabJournalBlocks;
|
|
Packit Service |
75d76b |
result = ALLOCATE(journalSize * VDO_BLOCK_SIZE, char, __func__,
|
|
Packit Service |
75d76b |
&eraser->zeroBuffer);
|
|
Packit Service |
75d76b |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
75d76b |
finishErasing(eraser, result);
|
|
Packit Service |
75d76b |
return;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
result = createExtent(parent->layer, VIO_TYPE_SLAB_JOURNAL,
|
|
Packit Service |
75d76b |
VIO_PRIORITY_METADATA, journalSize, eraser->zeroBuffer,
|
|
Packit Service |
75d76b |
&eraser->extent);
|
|
Packit Service |
75d76b |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
75d76b |
finishErasing(eraser, result);
|
|
Packit Service |
75d76b |
return;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
VDOCompletion *extentCompletion = &eraser->extent->completion;
|
|
Packit Service |
75d76b |
prepareCompletion(extentCompletion, eraseNextSlabJournal,
|
|
Packit Service |
75d76b |
handleErasingError, getCallbackThreadID(), eraser);
|
|
Packit Service |
75d76b |
eraseNextSlabJournal(extentCompletion);
|
|
Packit Service |
75d76b |
}
|