|
Packit Service |
7e342f |
/*
|
|
Packit Service |
7e342f |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
7e342f |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
7e342f |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
7e342f |
* of the License, or (at your option) any later version.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
7e342f |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
7e342f |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
7e342f |
* GNU General Public License for more details.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
7e342f |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
7e342f |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
7e342f |
* 02110-1301, USA.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kvio.c#7 $
|
|
Packit Service |
7e342f |
*/
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
#include "kvio.h"
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
#include "logger.h"
|
|
Packit Service |
7e342f |
#include "memoryAlloc.h"
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
#include "numUtils.h"
|
|
Packit Service |
7e342f |
#include "vdo.h"
|
|
Packit Service |
7e342f |
#include "waitQueue.h"
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
#include "bio.h"
|
|
Packit Service |
7e342f |
#include "ioSubmitter.h"
|
|
Packit Service |
7e342f |
#include "kvdoFlush.h"
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**
|
|
Packit Service |
7e342f |
* A function to tell vdo that we have completed the requested async
|
|
Packit Service |
7e342f |
* operation for a vio
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param item The work item of the VIO to complete
|
|
Packit Service |
7e342f |
**/
|
|
Packit Service |
7e342f |
static void kvdoHandleVIOCallback(KvdoWorkItem *item)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
KVIO *kvio = workItemAsKVIO(item);
|
|
Packit Service |
7e342f |
runCallback(vioAsCompletion(kvio->vio));
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void kvdoEnqueueVIOCallback(KVIO *kvio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
enqueueKVIO(kvio, kvdoHandleVIOCallback,
|
|
Packit Service |
7e342f |
(KvdoWorkFunction) vioAsCompletion(kvio->vio)->callback,
|
|
Packit Service |
7e342f |
REQ_Q_ACTION_VIO_CALLBACK);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void kvdoContinueKvio(KVIO *kvio, int error)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
if (unlikely(error != VDO_SUCCESS)) {
|
|
Packit Service |
7e342f |
setCompletionResult(vioAsCompletion(kvio->vio), error);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
kvdoEnqueueVIOCallback(kvio);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
// noinline ensures systemtap can hook in here
|
|
Packit Service |
7e342f |
static noinline void maybeLogKvioTrace(KVIO *kvio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
if (kvio->layer->traceLogging) {
|
|
Packit Service |
7e342f |
logKvioTrace(kvio);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
static void freeKVIO(KVIO **kvioPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
KVIO *kvio = *kvioPtr;
|
|
Packit Service |
7e342f |
if (kvio == NULL) {
|
|
Packit Service |
7e342f |
return;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
if (unlikely(kvio->vio->trace != NULL)) {
|
|
Packit Service |
7e342f |
maybeLogKvioTrace(kvio);
|
|
Packit Service |
7e342f |
FREE(kvio->vio->trace);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
freeBio(kvio->bio, kvio->layer);
|
|
Packit Service |
7e342f |
FREE(kvio);
|
|
Packit Service |
7e342f |
*kvioPtr = NULL;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void freeMetadataKVIO(MetadataKVIO **metadataKVIOPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
freeKVIO((KVIO **) metadataKVIOPtr);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void freeCompressedWriteKVIO(CompressedWriteKVIO **compressedWriteKVIOPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
freeKVIO((KVIO **) compressedWriteKVIOPtr);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void kvdoWriteCompressedBlock(AllocatingVIO *allocatingVIO)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
// This method assumes that compressed writes never set the flush or FUA
|
|
Packit Service |
7e342f |
// bits.
|
|
Packit Service |
7e342f |
CompressedWriteKVIO *compressedWriteKVIO
|
|
Packit Service |
7e342f |
= allocatingVIOAsCompressedWriteKVIO(allocatingVIO);
|
|
Packit Service |
7e342f |
KVIO *kvio = compressedWriteKVIOAsKVIO(compressedWriteKVIO);
|
|
Packit Service |
7e342f |
BIO *bio = kvio->bio;
|
|
Packit Service |
7e342f |
resetBio(bio, kvio->layer);
|
|
Packit Service |
7e342f |
setBioOperationWrite(bio);
|
|
Packit Service |
7e342f |
setBioSector(bio, blockToSector(kvio->layer, kvio->vio->physical));
|
|
Packit Service |
7e342f |
submitBio(bio, BIO_Q_ACTION_COMPRESSED_DATA);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**
|
|
Packit Service |
7e342f |
* Get the BioQueue action for a metadata VIO based on that VIO's priority.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param vio The VIO
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @return The action with which to submit the VIO's BIO.
|
|
Packit Service |
7e342f |
**/
|
|
Packit Service |
7e342f |
static inline BioQAction getMetadataAction(VIO *vio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
return ((vio->priority == VIO_PRIORITY_HIGH)
|
|
Packit Service |
7e342f |
? BIO_Q_ACTION_HIGH : BIO_Q_ACTION_METADATA);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void kvdoSubmitMetadataVIO(VIO *vio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
KVIO *kvio = metadataKVIOAsKVIO(vioAsMetadataKVIO(vio));
|
|
Packit Service |
7e342f |
BIO *bio = kvio->bio;
|
|
Packit Service |
7e342f |
resetBio(bio, kvio->layer);
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
setBioSector(bio, blockToSector(kvio->layer, vio->physical));
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
// Metadata I/Os bypass the read cache.
|
|
Packit Service |
7e342f |
if (isReadVIO(vio)) {
|
|
Packit Service |
7e342f |
ASSERT_LOG_ONLY(!vioRequiresFlushBefore(vio),
|
|
Packit Service |
7e342f |
"read VIO does not require flush before");
|
|
Packit Service |
7e342f |
vioAddTraceRecord(vio, THIS_LOCATION("$F;io=readMeta"));
|
|
Packit Service |
7e342f |
setBioOperationRead(bio);
|
|
Packit Service |
7e342f |
} else {
|
|
Packit Service |
7e342f |
KernelLayerState state = getKernelLayerState(kvio->layer);
|
|
Packit Service |
7e342f |
ASSERT_LOG_ONLY(((state == LAYER_RUNNING)
|
|
Packit Service |
7e342f |
|| (state == LAYER_RESUMING)
|
|
Packit Service |
7e342f |
|| (state = LAYER_STARTING)),
|
|
Packit Service |
7e342f |
"write metadata in allowed state %d", state);
|
|
Packit Service |
7e342f |
if (vioRequiresFlushBefore(vio)) {
|
|
Packit Service |
7e342f |
setBioOperationWrite(bio);
|
|
Packit Service |
7e342f |
setBioOperationFlagPreflush(bio);
|
|
Packit Service |
7e342f |
vioAddTraceRecord(vio, THIS_LOCATION("$F;io=flushWriteMeta"));
|
|
Packit Service |
7e342f |
} else {
|
|
Packit Service |
7e342f |
setBioOperationWrite(bio);
|
|
Packit Service |
7e342f |
vioAddTraceRecord(vio, THIS_LOCATION("$F;io=writeMeta"));
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
if (vioRequiresFlushAfter(vio)) {
|
|
Packit Service |
7e342f |
setBioOperationFlagFua(bio);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
submitBio(bio, getMetadataAction(vio));
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
|
|
Packit Service |
7e342f |
/**
|
|
Packit Service |
7e342f |
* Handle the completion of a base-code initiated flush by continuing the flush
|
|
Packit Service |
7e342f |
* VIO.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param bio The bio to complete
|
|
Packit Service |
7e342f |
**/
|
|
Packit Service |
7e342f |
static void completeFlushBio(BIO *bio)
|
|
Packit Service |
7e342f |
#else
|
|
Packit Service |
7e342f |
/**
|
|
Packit Service |
7e342f |
* Handle the completion of a base-code initiated flush by continuing the flush
|
|
Packit Service |
7e342f |
* VIO.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param bio The bio to complete
|
|
Packit Service |
7e342f |
* @param error Possible error from underlying block device
|
|
Packit Service |
7e342f |
**/
|
|
Packit Service |
7e342f |
static void completeFlushBio(BIO *bio, int error)
|
|
Packit Service |
7e342f |
#endif
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
|
|
Packit Service |
7e342f |
int error = getBioResult(bio);
|
|
Packit Service |
7e342f |
#endif
|
|
Packit Service |
7e342f |
KVIO *kvio = (KVIO *) bio->bi_private;
|
|
Packit Service |
7e342f |
// XXX This assumes a VDO-created bio around a buffer contains exactly 1
|
|
Packit Service |
7e342f |
// page, which we believe is true, but do not assert.
|
|
Packit Service |
7e342f |
bio->bi_vcnt = 1;
|
|
Packit Service |
7e342f |
// Restore the bio's notion of its own data.
|
|
Packit Service |
7e342f |
resetBio(bio, kvio->layer);
|
|
Packit Service |
7e342f |
kvdoContinueKvio(kvio, error);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void kvdoFlushVIO(VIO *vio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
KVIO *kvio = metadataKVIOAsKVIO(vioAsMetadataKVIO(vio));
|
|
Packit Service |
7e342f |
BIO *bio = kvio->bio;
|
|
Packit Service |
7e342f |
KernelLayer *layer = kvio->layer;
|
|
Packit Service |
7e342f |
resetBio(bio, layer);
|
|
Packit Service |
7e342f |
prepareFlushBIO(bio, kvio, getKernelLayerBdev(layer), completeFlushBio);
|
|
Packit Service |
7e342f |
submitBio(bio, getMetadataAction(vio));
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/*
|
|
Packit Service |
7e342f |
* Hook for a SystemTap probe to potentially restrict the choices
|
|
Packit Service |
7e342f |
* of which VIOs should have their latencies tracked.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* Normally returns true. Even if true is returned, sampleThisOne may
|
|
Packit Service |
7e342f |
* cut down the monitored VIOs by some fraction so as to reduce the
|
|
Packit Service |
7e342f |
* impact on system performance.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* Must be "noinline" so that SystemTap can find the return
|
|
Packit Service |
7e342f |
* instruction and modify the return value.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param kvio The KVIO being initialized
|
|
Packit Service |
7e342f |
* @param layer The kernel layer
|
|
Packit Service |
7e342f |
* @param bio The incoming I/O request
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @return whether it's useful to track latency for VIOs looking like
|
|
Packit Service |
7e342f |
* this one
|
|
Packit Service |
7e342f |
*/
|
|
Packit Service |
7e342f |
static noinline bool
|
|
Packit Service |
7e342f |
sampleThisVIO(KVIO *kvio, KernelLayer *layer, BIO *bio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
bool result = true;
|
|
Packit Service |
7e342f |
// Ensure the arguments and result exist at the same time, for SystemTap.
|
|
Packit Service |
7e342f |
__asm__ __volatile__(""
|
|
Packit Service |
7e342f |
: "=g" (result)
|
|
Packit Service |
7e342f |
: "0" (result),
|
|
Packit Service |
7e342f |
"g" (kvio),
|
|
Packit Service |
7e342f |
"g" (layer),
|
|
Packit Service |
7e342f |
"g" (bio)
|
|
Packit Service |
7e342f |
: "memory");
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
void initializeKVIO(KVIO *kvio,
|
|
Packit Service |
7e342f |
KernelLayer *layer,
|
|
Packit Service |
7e342f |
VIOType vioType,
|
|
Packit Service |
7e342f |
VIOPriority priority,
|
|
Packit Service |
7e342f |
void *parent,
|
|
Packit Service |
7e342f |
BIO *bio)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
if (layer->vioTraceRecording
|
|
Packit Service |
7e342f |
&& sampleThisVIO(kvio, layer, bio)
|
|
Packit Service |
7e342f |
&& sampleThisOne(&layer->traceSampleCounter)) {
|
|
Packit Service |
7e342f |
int result = (isDataVIOType(vioType)
|
|
Packit Service |
7e342f |
? allocTraceFromPool(layer, &kvio->vio->trace)
|
|
Packit Service |
7e342f |
: ALLOCATE(1, Trace, "trace", &kvio->vio->trace));
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
logError("trace record allocation failure %d", result);
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
kvio->bio = bio;
|
|
Packit Service |
7e342f |
kvio->layer = layer;
|
|
Packit Service |
7e342f |
if (bio != NULL) {
|
|
Packit Service |
7e342f |
bio->bi_private = kvio;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
initializeVIO(kvio->vio, vioType, priority, parent, getVDO(&layer->kvdo),
|
|
Packit Service |
7e342f |
&layer->common);
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
// XXX: The "init" label should be replaced depending on the
|
|
Packit Service |
7e342f |
// write/read/flush path followed.
|
|
Packit Service |
7e342f |
kvioAddTraceRecord(kvio, THIS_LOCATION("$F;io=?init;j=normal"));
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
VDOCompletion *completion = vioAsCompletion(kvio->vio);
|
|
Packit Service |
7e342f |
kvio->enqueueable.enqueueable.completion = completion;
|
|
Packit Service |
7e342f |
completion->enqueueable = &kvio->enqueueable.enqueueable;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**
|
|
Packit Service |
7e342f |
* Construct a metadata KVIO.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param [in] layer The physical layer
|
|
Packit Service |
7e342f |
* @param [in] vioType The type of VIO to create
|
|
Packit Service |
7e342f |
* @param [in] priority The relative priority to assign to the
|
|
Packit Service |
7e342f |
* MetadataKVIO
|
|
Packit Service |
7e342f |
* @param [in] parent The parent of the MetadataKVIO completion
|
|
Packit Service |
7e342f |
* @param [in] bio The bio to associate with this MetadataKVIO
|
|
Packit Service |
7e342f |
* @param [out] metadataKVIOPtr A pointer to hold the new MetadataKVIO
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @return VDO_SUCCESS or an error
|
|
Packit Service |
7e342f |
**/
|
|
Packit Service |
7e342f |
__attribute__((warn_unused_result))
|
|
Packit Service |
7e342f |
static int makeMetadataKVIO(KernelLayer *layer,
|
|
Packit Service |
7e342f |
VIOType vioType,
|
|
Packit Service |
7e342f |
VIOPriority priority,
|
|
Packit Service |
7e342f |
void *parent,
|
|
Packit Service |
7e342f |
BIO *bio,
|
|
Packit Service |
7e342f |
MetadataKVIO **metadataKVIOPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
// If MetadataKVIO grows past 256 bytes, we'll lose benefits of VDOSTORY-176.
|
|
Packit Service |
7e342f |
STATIC_ASSERT(sizeof(MetadataKVIO) <= 256);
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
// Metadata VIOs should use direct allocation and not use the buffer pool,
|
|
Packit Service |
7e342f |
// which is reserved for submissions from the linux block layer.
|
|
Packit Service |
7e342f |
MetadataKVIO *metadataKVIO;
|
|
Packit Service |
7e342f |
int result = ALLOCATE(1, MetadataKVIO, __func__, &metadataKVIO);
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
logError("metadata KVIO allocation failure %d", result);
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
KVIO *kvio = &metadataKVIO->kvio;
|
|
Packit Service |
7e342f |
kvio->vio = &metadataKVIO->vio;
|
|
Packit Service |
7e342f |
initializeKVIO(kvio, layer, vioType, priority, parent, bio);
|
|
Packit Service |
7e342f |
*metadataKVIOPtr = metadataKVIO;
|
|
Packit Service |
7e342f |
return VDO_SUCCESS;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**
|
|
Packit Service |
7e342f |
* Construct a CompressedWriteKVIO.
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @param [in] layer The physical layer
|
|
Packit Service |
7e342f |
* @param [in] parent The parent of the CompressedWriteKVIO
|
|
Packit Service |
7e342f |
* completion
|
|
Packit Service |
7e342f |
* @param [in] bio The bio to associate with this
|
|
Packit Service |
7e342f |
* CompressedWriteKVIO
|
|
Packit Service |
7e342f |
* @param [out] compressedWriteKVIOPtr A pointer to hold the new
|
|
Packit Service |
7e342f |
* CompressedWriteKVIO
|
|
Packit Service |
7e342f |
*
|
|
Packit Service |
7e342f |
* @return VDO_SUCCESS or an error
|
|
Packit Service |
7e342f |
**/
|
|
Packit Service |
7e342f |
__attribute__((warn_unused_result))
|
|
Packit Service |
7e342f |
static int
|
|
Packit Service |
7e342f |
makeCompressedWriteKVIO(KernelLayer *layer,
|
|
Packit Service |
7e342f |
void *parent,
|
|
Packit Service |
7e342f |
BIO *bio,
|
|
Packit Service |
7e342f |
CompressedWriteKVIO **compressedWriteKVIOPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
// Compressed write VIOs should use direct allocation and not use the buffer
|
|
Packit Service |
7e342f |
// pool, which is reserved for submissions from the linux block layer.
|
|
Packit Service |
7e342f |
CompressedWriteKVIO *compressedWriteKVIO;
|
|
Packit Service |
7e342f |
int result = ALLOCATE(1, CompressedWriteKVIO, __func__,
|
|
Packit Service |
7e342f |
&compressedWriteKVIO);
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
logError("compressed write KVIO allocation failure %d", result);
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
KVIO *kvio = &compressedWriteKVIO->kvio;
|
|
Packit Service |
7e342f |
kvio->vio = allocatingVIOAsVIO(&compressedWriteKVIO->allocatingVIO);
|
|
Packit Service |
7e342f |
initializeKVIO(kvio, layer, VIO_TYPE_COMPRESSED_BLOCK,
|
|
Packit Service |
7e342f |
VIO_PRIORITY_COMPRESSED_DATA, parent, bio);
|
|
Packit Service |
7e342f |
*compressedWriteKVIOPtr = compressedWriteKVIO;
|
|
Packit Service |
7e342f |
return VDO_SUCCESS;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
int kvdoCreateMetadataVIO(PhysicalLayer *layer,
|
|
Packit Service |
7e342f |
VIOType vioType,
|
|
Packit Service |
7e342f |
VIOPriority priority,
|
|
Packit Service |
7e342f |
void *parent,
|
|
Packit Service |
7e342f |
char *data,
|
|
Packit Service |
7e342f |
VIO **vioPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
int result = ASSERT(isMetadataVIOType(vioType),
|
|
Packit Service |
7e342f |
"%d is a metadata type", vioType);
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
BIO *bio;
|
|
Packit Service |
7e342f |
KernelLayer *kernelLayer = asKernelLayer(layer);
|
|
Packit Service |
7e342f |
result = createBio(kernelLayer, data, &bio;;
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
MetadataKVIO *metadataKVIO;
|
|
Packit Service |
7e342f |
result = makeMetadataKVIO(kernelLayer, vioType, priority, parent, bio,
|
|
Packit Service |
7e342f |
&metadataKVIO);
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
freeBio(bio, kernelLayer);
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
*vioPtr = &metadataKVIO->vio;
|
|
Packit Service |
7e342f |
return VDO_SUCCESS;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
/**********************************************************************/
|
|
Packit Service |
7e342f |
int kvdoCreateCompressedWriteVIO(PhysicalLayer *layer,
|
|
Packit Service |
7e342f |
void *parent,
|
|
Packit Service |
7e342f |
char *data,
|
|
Packit Service |
7e342f |
AllocatingVIO **allocatingVIOPtr)
|
|
Packit Service |
7e342f |
{
|
|
Packit Service |
7e342f |
BIO *bio;
|
|
Packit Service |
7e342f |
KernelLayer *kernelLayer = asKernelLayer(layer);
|
|
Packit Service |
7e342f |
int result = createBio(kernelLayer, data, &bio;;
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
CompressedWriteKVIO *compressedWriteKVIO;
|
|
Packit Service |
7e342f |
result = makeCompressedWriteKVIO(kernelLayer, parent, bio,
|
|
Packit Service |
7e342f |
&compressedWriteKVIO);
|
|
Packit Service |
7e342f |
if (result != VDO_SUCCESS) {
|
|
Packit Service |
7e342f |
freeBio(bio, kernelLayer);
|
|
Packit Service |
7e342f |
return result;
|
|
Packit Service |
7e342f |
}
|
|
Packit Service |
7e342f |
|
|
Packit Service |
7e342f |
*allocatingVIOPtr = &compressedWriteKVIO->allocatingVIO;
|
|
Packit Service |
7e342f |
return VDO_SUCCESS;
|
|
Packit Service |
7e342f |
}
|