/*
* Copyright (c) 2020 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/extent.h#2 $
*/
#ifndef EXTENT_H
#define EXTENT_H
#include "permassert.h"
#include "completion.h"
#include "types.h"
#include "vio.h"
/**
* A chain of VIOs which are part of the same request. An extent contains
* a chain of at least 'count' VIOs. The 'next' pointer of the last VIO
* in the extent (as indicated by the count) may not be NULL, but it is not
* part of the extent. A VIO may belong to a single extent.
**/
struct vdoExtent {
// The completion for asynchronous extent processing
VDOCompletion completion;
// The number of VIOs in the extent
BlockCount count;
// The number of completed VIOs in the extent
BlockCount completeCount;
// The VIOs in the extent
VIO *vios[];
};
/**
* Convert a generic VDOCompletion to a VDOExtent.
*
* @param completion The completion to convert
*
* @return The completion as an extent
**/
static inline VDOExtent *asVDOExtent(VDOCompletion *completion)
{
STATIC_ASSERT(offsetof(VDOExtent, completion) == 0);
assertCompletionType(completion->type, VDO_EXTENT_COMPLETION);
return (VDOExtent *) completion;
}
/**
* Convert a VDOExtent to VDOCompletion.
*
* @param extent The extent to convert
*
* @return The extent as a VDOCompletion
**/
static inline VDOCompletion *extentAsCompletion(VDOExtent *extent)
{
return &extent->completion;
}
/**
* Create a VDOExtent.
*
* @param [in] layer The layer
* @param [in] vioType The usage type to assign to the VIOs in the extent
* (data / block map / journal)
* @param [in] priority The relative priority to assign to the VIOs
* @param [in] blockCount The number of blocks in the buffer
* @param [in] data The buffer
* @param [out] extentPtr A pointer to hold the new extent
*
* @return VDO_SUCCESS or an error
**/
int createExtent(PhysicalLayer *layer,
VIOType vioType,
VIOPriority priority,
BlockCount blockCount,
char *data,
VDOExtent **extentPtr)
__attribute__((warn_unused_result));
/**
* Free an extent and null out the reference to it.
*
* @param [in,out] extentPtr The reference to the extent to free
**/
void freeExtent(VDOExtent **extentPtr);
/**
* Read metadata from the underlying storage.
*
* @param extent The extent to read
* @param startBlock The physical block number of the first block
* in the extent
* @param count The number of blocks to read (must be less than or
* equal to the length of the extent)
**/
void readPartialMetadataExtent(VDOExtent *extent,
PhysicalBlockNumber startBlock,
BlockCount count);
/**
* Read metadata from the underlying storage.
*
* @param extent The extent to read
* @param startBlock The physical block number of the first block
* in the extent
**/
static inline void readMetadataExtent(VDOExtent *extent,
PhysicalBlockNumber startBlock)
{
readPartialMetadataExtent(extent, startBlock, extent->count);
}
/**
* Write metadata to the underlying storage.
*
* @param extent The extent to write
* @param startBlock The physical block number of the first block in the
* extent
* @param count The number of blocks to read (must be less than or
* equal to the length of the extent)
**/
void writePartialMetadataExtent(VDOExtent *extent,
PhysicalBlockNumber startBlock,
BlockCount count);
/**
* Write metadata to the underlying storage.
*
* @param extent The extent to write
* @param startBlock The physical block number of the first block in the
* extent
**/
static inline void writeMetadataExtent(VDOExtent *extent,
PhysicalBlockNumber startBlock)
{
writePartialMetadataExtent(extent, startBlock, extent->count);
}
/**
* Notify an extent that one of its VIOs has completed. If the signaling VIO
* is the last of the extent's VIOs to complete, the extent will finish. This
* function is set as the VIO callback in completeVIO().
*
* @param completion The completion of the VIO which has just finished
**/
void handleVIOCompletion(VDOCompletion *completion);
#endif /* EXTENT_H */