Blame source/vdo/base/physicalLayer.h

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/physicalLayer.h#2 $
Packit Service 75d76b
 */
Packit Service 75d76b
Packit Service 75d76b
#ifndef PHYSICAL_LAYER_H
Packit Service 75d76b
#define PHYSICAL_LAYER_H
Packit Service 75d76b
Packit Service 75d76b
#include "types.h"
Packit Service 75d76b
Packit Service 75d76b
static const CRC32Checksum INITIAL_CHECKSUM = 0xffffffff;
Packit Service 75d76b
Packit Service 75d76b
enum {
Packit Service 75d76b
  /* The size of a CRC-32 checksum */
Packit Service 75d76b
  CHECKSUM_SIZE = sizeof(CRC32Checksum),
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to destroy a physical layer and NULL out the reference to it.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param layerPtr  A pointer to the layer to destroy
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void LayerDestructor(PhysicalLayer **layerPtr);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to update a running CRC-32 checksum.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param crc     The current value of the crc
Packit Service 75d76b
 * @param buffer  The data to add to the checksum
Packit Service 75d76b
 * @param length  The length of the data
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return The updated value of the checksum
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef uint32_t CRC32Updater(CRC32Checksum  crc,
Packit Service 75d76b
                              const byte    *buffer,
Packit Service 75d76b
                              size_t         length);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to report the block count of a physicalLayer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param layer  The layer
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return The block count of the layer
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef BlockCount BlockCountGetter(PhysicalLayer *layer);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function which can allocate a buffer suitable for use in an
Packit Service 75d76b
 * ExtentReader or ExtentWriter.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param [in]  layer      The physical layer in question
Packit Service 75d76b
 * @param [in]  bytes      The size of the buffer, in bytes.
Packit Service 75d76b
 * @param [in]  why        The occasion for allocating the buffer
Packit Service 75d76b
 * @param [out] bufferPtr  A pointer to hold the buffer
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return a success or error code
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef int BufferAllocator(PhysicalLayer  *layer,
Packit Service 75d76b
                            size_t          bytes,
Packit Service 75d76b
                            const char     *why,
Packit Service 75d76b
                            char          **bufferPtr);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function which can read an extent from a physicalLayer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param [in]  layer       The physical layer from which to read
Packit Service 75d76b
 * @param [in]  startBlock  The physical block number of the start of the
Packit Service 75d76b
 *                          extent
Packit Service 75d76b
 * @param [in]  blockCount  The number of blocks in the extent
Packit Service 75d76b
 * @param [out] buffer      A buffer to hold the extent
Packit Service 75d76b
 * @param [out] blocksRead  A pointer to hold the number of blocks read (may be
Packit Service 75d76b
 *                          NULL)
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return a success or error code
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef int ExtentReader(PhysicalLayer       *layer,
Packit Service 75d76b
                         PhysicalBlockNumber  startBlock,
Packit Service 75d76b
                         size_t               blockCount,
Packit Service 75d76b
                         char                *buffer,
Packit Service 75d76b
                         size_t              *blocksRead);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function which can write an extent to a physicalLayer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param [in]  layer          The physical layer to which to write
Packit Service 75d76b
 * @param [in]  startBlock     The physical block number of the start of the
Packit Service 75d76b
 *                             extent
Packit Service 75d76b
 * @param [in]  blockCount     The number of blocks in the extent
Packit Service 75d76b
 * @param [in]  buffer         The buffer which contains the data
Packit Service 75d76b
 * @param [out] blocksWritten  A pointer to hold the number of blocks written
Packit Service 75d76b
 *                             (may be NULL)
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return a success or error code
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef int ExtentWriter(PhysicalLayer       *layer,
Packit Service 75d76b
                         PhysicalBlockNumber  startBlock,
Packit Service 75d76b
                         size_t               blockCount,
Packit Service 75d76b
                         char                *buffer,
Packit Service 75d76b
                         size_t              *blocksWritten);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to allocate a metadata VIO.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param [in]  layer     The physical layer
Packit Service 75d76b
 * @param [in]  vioType   The type of VIO to create
Packit Service 75d76b
 * @param [in]  priority  The relative priority to assign to the VIOs
Packit Service 75d76b
 * @param [in]  parent    The parent of this VIO
Packit Service 75d76b
 * @param [in]  data      The buffer
Packit Service 75d76b
 * @param [out] vioPtr    A pointer to hold the new VIO
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return VDO_SUCCESS or an error
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef int MetadataVIOCreator(PhysicalLayer  *layer,
Packit Service 75d76b
                               VIOType         vioType,
Packit Service 75d76b
                               VIOPriority     priority,
Packit Service 75d76b
                               void           *parent,
Packit Service 75d76b
                               char           *data,
Packit Service 75d76b
                               VIO           **vioPtr);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to allocate an AllocatingVIO for compressed writes.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param [in]  layer             The physical layer
Packit Service 75d76b
 * @param [in]  parent            The parent of this VIO
Packit Service 75d76b
 * @param [in]  data              The buffer
Packit Service 75d76b
 * @param [out] allocatingVIOPtr  A pointer to hold the new AllocatingVIO
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return VDO_SUCCESS or an error
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef int CompressedWriteVIOCreator(PhysicalLayer  *layer,
Packit Service 75d76b
                                      void           *parent,
Packit Service 75d76b
                                      char           *data,
Packit Service 75d76b
                                      AllocatingVIO **allocatingVIOPtr);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to destroy a VIO. The pointer to the VIO will be nulled out.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param vioPtr  A pointer to the VIO to destroy
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void VIODestructor(VIO **vioPtr);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to zero the contents of a DataVIO.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO to zero
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataVIOZeroer;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to copy the contents of a DataVIO into another DataVIO.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param source       The dataVIO to copy from
Packit Service 75d76b
 * @param destination  The dataVIO to copy to
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void DataCopier(DataVIO *source, DataVIO *destination);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to apply a partial write to a DataVIO which has completed the
Packit Service 75d76b
 * read portion of a read-modify-write operation.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The dataVIO to modify
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataModifier;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to asynchronously hash the block data, setting the chunk name of
Packit Service 75d76b
 * the DataVIO. This is asynchronous to allow the computation to be done on
Packit Service 75d76b
 * different threads.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO to hash
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataHasher;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to determine whether a block is a duplicate. This function
Packit Service 75d76b
 * expects the 'physical' field of the DataVIO to be set to the physical block
Packit Service 75d76b
 * where the block will be written if it is not a duplicate. If the block does
Packit Service 75d76b
 * turn out to be a duplicate, the DataVIO's 'isDuplicate' field will be set to
Packit Service 75d76b
 * true, and the DataVIO's 'advice' field will be set to the physical block and
Packit Service 75d76b
 * mapping state of the already stored copy of the block.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO containing the block to check.
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DuplicationChecker;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to verify the duplication advice by examining an already-stored
Packit Service 75d76b
 * data block. This function expects the 'physical' field of the DataVIO to be
Packit Service 75d76b
 * set to the physical block where the block will be written if it is not a
Packit Service 75d76b
 * duplicate, and the 'duplicate' field to be set to the physical block and
Packit Service 75d76b
 * mapping state where a copy of the data may already exist. If the block is
Packit Service 75d76b
 * not a duplicate, the DataVIO's 'isDuplicate' field will be cleared.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The dataVIO containing the block to check.
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DuplicationVerifier;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to read a single DataVIO from the layer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * If the DataVIO does not describe a read-modify-write operation, the
Packit Service 75d76b
 * physical layer may safely acknowledge the related user I/O request
Packit Service 75d76b
 * as complete.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO to read
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataReader;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to read a single metadata VIO from the layer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param vio  The vio to read
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncOperation MetadataReader;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to write a single DataVIO to the layer
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO to write
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataWriter;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to write a single metadata VIO from the layer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param vio  The vio to write
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncOperation MetadataWriter;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to inform the layer that a DataVIO's related I/O request can be
Packit Service 75d76b
 * safely acknowledged as complete, even though the DataVIO itself may have
Packit Service 75d76b
 * further processing to do.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO to acknowledge
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataAcknowledger;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to compare the contents of a DataVIO to another DataVIO.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param first   The first DataVIO to compare
Packit Service 75d76b
 * @param second  The second DataVIO to compare
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return true if the contents of the two DataVIOs are the same
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef bool DataVIOComparator(DataVIO *first, DataVIO *second);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to compress the data in a DataVIO.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO to compress
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation DataCompressor;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Update albireo.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param dataVIO  The DataVIO which needs to change the entry for its data
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef AsyncDataOperation AlbireoUpdater;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to finish flush requests
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param vdoFlush  The flush requests
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void FlushComplete(VDOFlush **vdoFlush);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to query the write policy of the layer.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param layer  The layer to query
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return the write policy of the layer
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef WritePolicy WritePolicyGetter(PhysicalLayer *layer);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to create an object that can be enqueued to run in a specified
Packit Service 75d76b
 * thread. The Enqueueable will be put into the 'enqueueable' field of the
Packit Service 75d76b
 * supplied completion.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param completion  The completion to invoke the callback of
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return VDO_SUCCESS or an error code
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef int EnqueueableCreator(VDOCompletion *completion);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to destroy and deallocate an Enqueueable object.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param enqueueablePtr  Pointer to the object pointer to be destroyed
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void EnqueueableDestructor(Enqueueable **enqueueablePtr);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to enqueue the Enqueueable object to run on the thread specified
Packit Service 75d76b
 * by its associated completion.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param enqueueable  The object to be enqueued
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void Enqueuer(Enqueueable *enqueueable);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to wait for an admin operation to complete. This function should
Packit Service 75d76b
 * not be called from a base-code thread.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param layer  The layer on which to wait
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void OperationWaiter(PhysicalLayer *layer);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to inform the layer of the result of an admin operation.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param layer  The layer to inform
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef void OperationComplete(PhysicalLayer *layer);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to get the id of the current thread.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return The id of the current thread
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef ThreadID ThreadIDGetter(void);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A function to return the physical layer pointer for the current thread.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return The physical layer pointer
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef PhysicalLayer *PhysicalLayerGetter(void);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * An abstraction representing the underlying physical layer.
Packit Service 75d76b
 **/
Packit Service 75d76b
struct physicalLayer {
Packit Service 75d76b
  // Management interface
Packit Service 75d76b
  LayerDestructor           *destroy;
Packit Service 75d76b
Packit Service 75d76b
  // Synchronous interface
Packit Service 75d76b
  CRC32Updater              *updateCRC32;
Packit Service 75d76b
  BlockCountGetter          *getBlockCount;
Packit Service 75d76b
Packit Service 75d76b
  // Synchronous IO interface
Packit Service 75d76b
  BufferAllocator           *allocateIOBuffer;
Packit Service 75d76b
  ExtentReader              *reader;
Packit Service 75d76b
  ExtentWriter              *writer;
Packit Service 75d76b
Packit Service 75d76b
  WritePolicyGetter         *getWritePolicy;
Packit Service 75d76b
Packit Service 75d76b
  // Synchronous interfaces (vio-based)
Packit Service 75d76b
  MetadataVIOCreator        *createMetadataVIO;
Packit Service 75d76b
  CompressedWriteVIOCreator *createCompressedWriteVIO;
Packit Service 75d76b
  VIODestructor             *freeVIO;
Packit Service 75d76b
  DataVIOZeroer             *zeroDataVIO;
Packit Service 75d76b
  DataCopier                *copyData;
Packit Service 75d76b
  DataModifier              *applyPartialWrite;
Packit Service 75d76b
Packit Service 75d76b
  // Asynchronous interface (vio-based)
Packit Service 75d76b
  DataHasher                *hashData;
Packit Service 75d76b
  DuplicationChecker        *checkForDuplication;
Packit Service 75d76b
  DuplicationVerifier       *verifyDuplication;
Packit Service 75d76b
  DataReader                *readData;
Packit Service 75d76b
  DataWriter                *writeData;
Packit Service 75d76b
  CompressedWriter          *writeCompressedBlock;
Packit Service 75d76b
  MetadataReader            *readMetadata;
Packit Service 75d76b
  MetadataWriter            *writeMetadata;
Packit Service 75d76b
  MetadataWriter            *flush;
Packit Service 75d76b
  DataAcknowledger          *acknowledgeDataVIO;
Packit Service 75d76b
  DataVIOComparator         *compareDataVIOs;
Packit Service 75d76b
  DataCompressor            *compressDataVIO;
Packit Service 75d76b
  AlbireoUpdater            *updateAlbireo;
Packit Service 75d76b
Packit Service 75d76b
  // Asynchronous interface (other)
Packit Service 75d76b
  FlushComplete             *completeFlush;
Packit Service 75d76b
  EnqueueableCreator        *createEnqueueable;
Packit Service 75d76b
  EnqueueableDestructor     *destroyEnqueueable;
Packit Service 75d76b
  Enqueuer                  *enqueue;
Packit Service 75d76b
  OperationWaiter           *waitForAdminOperation;
Packit Service 75d76b
  OperationComplete         *completeAdminOperation;
Packit Service 75d76b
Packit Service 75d76b
  // Thread specific interface
Packit Service 75d76b
  ThreadIDGetter            *getCurrentThreadID;
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Register the layer-specific implementation of getPhysicalLayer().
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param getter  The function to be called
Packit Service 75d76b
 **/
Packit Service 75d76b
void registerPhysicalLayerGetter(PhysicalLayerGetter *getter);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Fetch the physical layer pointer for the current thread.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return The physical layer pointer
Packit Service 75d76b
 **/
Packit Service 75d76b
PhysicalLayer *getPhysicalLayer(void);
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Get the id of the callback thread on which a completion is current running.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return the current thread ID
Packit Service 75d76b
 **/
Packit Service 75d76b
static inline ThreadID getCallbackThreadID(void)
Packit Service 75d76b
{
Packit Service 75d76b
  return getPhysicalLayer()->getCurrentThreadID();
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
#endif // PHYSICAL_LAYER_H