Blame source/vdo/base/slabJournalEraser.c

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
}