|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/dataVIO.h#4 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#ifndef DATA_VIO_H
|
|
Packit Service |
310c69 |
#define DATA_VIO_H
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "allocatingVIO.h"
|
|
Packit Service |
310c69 |
#include "atomic.h"
|
|
Packit Service |
310c69 |
#include "blockMapEntry.h"
|
|
Packit Service |
310c69 |
#include "blockMappingState.h"
|
|
Packit Service |
310c69 |
#include "constants.h"
|
|
Packit Service |
310c69 |
#include "hashZone.h"
|
|
Packit Service |
310c69 |
#include "journalPoint.h"
|
|
Packit Service |
310c69 |
#include "logicalZone.h"
|
|
Packit Service |
310c69 |
#include "referenceOperation.h"
|
|
Packit Service |
310c69 |
#include "ringNode.h"
|
|
Packit Service |
310c69 |
#include "threadConfig.h"
|
|
Packit Service |
310c69 |
#include "trace.h"
|
|
Packit Service |
310c69 |
#include "types.h"
|
|
Packit Service |
310c69 |
#include "vdoPageCache.h"
|
|
Packit Service |
310c69 |
#include "vio.h"
|
|
Packit Service |
310c69 |
#include "waitQueue.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Codes for describing the last asynchronous operation performed on a VIO.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
typedef enum __attribute__((packed)) {
|
|
Packit Service |
310c69 |
MIN_ASYNC_OPERATION_NUMBER = 0,
|
|
Packit Service |
310c69 |
LAUNCH = MIN_ASYNC_OPERATION_NUMBER,
|
|
Packit Service |
310c69 |
ACKNOWLEDGE_WRITE,
|
|
Packit Service |
310c69 |
ACQUIRE_HASH_LOCK,
|
|
Packit Service |
310c69 |
ACQUIRE_LOGICAL_BLOCK_LOCK,
|
|
Packit Service |
310c69 |
ACQUIRE_PBN_READ_LOCK,
|
|
Packit Service |
310c69 |
CHECK_FOR_DEDUPE_FOR_ROLLOVER,
|
|
Packit Service |
310c69 |
CHECK_FOR_DEDUPLICATION,
|
|
Packit Service |
310c69 |
COMPRESS_DATA,
|
|
Packit Service |
310c69 |
CONTINUE_VIO_ASYNC,
|
|
Packit Service |
310c69 |
FIND_BLOCK_MAP_SLOT,
|
|
Packit Service |
310c69 |
GET_MAPPED_BLOCK,
|
|
Packit Service |
310c69 |
GET_MAPPED_BLOCK_FOR_DEDUPE,
|
|
Packit Service |
310c69 |
GET_MAPPED_BLOCK_FOR_WRITE,
|
|
Packit Service |
310c69 |
HASH_DATA,
|
|
Packit Service |
310c69 |
JOURNAL_DECREMENT_FOR_DEDUPE,
|
|
Packit Service |
310c69 |
JOURNAL_DECREMENT_FOR_WRITE,
|
|
Packit Service |
310c69 |
JOURNAL_INCREMENT_FOR_COMPRESSION,
|
|
Packit Service |
310c69 |
JOURNAL_INCREMENT_FOR_DEDUPE,
|
|
Packit Service |
310c69 |
JOURNAL_INCREMENT_FOR_WRITE,
|
|
Packit Service |
310c69 |
JOURNAL_MAPPING_FOR_COMPRESSION,
|
|
Packit Service |
310c69 |
JOURNAL_MAPPING_FOR_DEDUPE,
|
|
Packit Service |
310c69 |
JOURNAL_MAPPING_FOR_WRITE,
|
|
Packit Service |
310c69 |
JOURNAL_UNMAPPING_FOR_DEDUPE,
|
|
Packit Service |
310c69 |
JOURNAL_UNMAPPING_FOR_WRITE,
|
|
Packit Service |
310c69 |
PACK_COMPRESSED_BLOCK,
|
|
Packit Service |
310c69 |
PUT_MAPPED_BLOCK,
|
|
Packit Service |
310c69 |
PUT_MAPPED_BLOCK_FOR_DEDUPE,
|
|
Packit Service |
310c69 |
READ_DATA,
|
|
Packit Service |
310c69 |
UPDATE_INDEX,
|
|
Packit Service |
310c69 |
VERIFY_DEDUPLICATION,
|
|
Packit Service |
310c69 |
WRITE_DATA,
|
|
Packit Service |
310c69 |
MAX_ASYNC_OPERATION_NUMBER,
|
|
Packit Service |
310c69 |
} AsyncOperationNumber;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* An LBN lock.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
struct lbnLock {
|
|
Packit Service |
310c69 |
/* The LBN being locked */
|
|
Packit Service |
310c69 |
LogicalBlockNumber lbn;
|
|
Packit Service |
310c69 |
/* Whether the lock is locked */
|
|
Packit Service |
310c69 |
bool locked;
|
|
Packit Service |
310c69 |
/* The queue of waiters for the lock */
|
|
Packit Service |
310c69 |
WaitQueue waiters;
|
|
Packit Service |
310c69 |
/* The logical zone of the LBN */
|
|
Packit Service |
310c69 |
LogicalZone *zone;
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Fields for using the arboreal block map.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
/* The current height at which this DataVIO is operating */
|
|
Packit Service |
310c69 |
Height height;
|
|
Packit Service |
310c69 |
/* The block map tree for this LBN */
|
|
Packit Service |
310c69 |
RootCount rootIndex;
|
|
Packit Service |
310c69 |
/* Whether we hold a page lock */
|
|
Packit Service |
310c69 |
bool locked;
|
|
Packit Service |
310c69 |
/* The thread on which to run the callback */
|
|
Packit Service |
310c69 |
ThreadID threadID;
|
|
Packit Service |
310c69 |
/* The function to call after looking up a block map slot */
|
|
Packit Service |
310c69 |
VDOAction *callback;
|
|
Packit Service |
310c69 |
/* The key for the lock map */
|
|
Packit Service |
310c69 |
uint64_t key;
|
|
Packit Service |
310c69 |
/* The queue of waiters for the page this VIO is allocating or loading */
|
|
Packit Service |
310c69 |
WaitQueue waiters;
|
|
Packit Service |
310c69 |
/* The block map tree slots for this LBN */
|
|
Packit Service |
310c69 |
BlockMapTreeSlot treeSlots[BLOCK_MAP_TREE_HEIGHT + 1];
|
|
Packit Service |
310c69 |
} TreeLock;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* The current compression state of this VIO. This field contains a value
|
|
Packit Service |
310c69 |
* which consists of a VIOCompressionState possibly ORed with a flag
|
|
Packit Service |
310c69 |
* indicating that a request has been made to cancel (or prevent) compression
|
|
Packit Service |
310c69 |
* for this VIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This field should be accessed through the getCompressionState() and
|
|
Packit Service |
310c69 |
* setCompressionState() methods. It should not be accessed directly.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
Atomic32 state;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The compressed size of this block */
|
|
Packit Service |
310c69 |
uint16_t size;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The packer input or output bin slot which holds the enclosing DataVIO */
|
|
Packit Service |
310c69 |
SlotNumber slot;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The packer input bin to which the enclosing DataVIO has been assigned */
|
|
Packit Service |
310c69 |
InputBin *bin;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* A pointer to the compressed form of this block */
|
|
Packit Service |
310c69 |
char *data;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* A VIO which is blocked in the packer while holding a lock this VIO needs.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
DataVIO *lockHolder;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
} CompressionState;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* A VIO for processing user data requests.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
struct dataVIO {
|
|
Packit Service |
310c69 |
/* The underlying AllocatingVIO */
|
|
Packit Service |
310c69 |
AllocatingVIO allocatingVIO;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The logical block of this request */
|
|
Packit Service |
310c69 |
LBNLock logical;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The state for traversing the block map tree */
|
|
Packit Service |
310c69 |
TreeLock treeLock;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The current partition address of this block */
|
|
Packit Service |
310c69 |
ZonedPBN mapped;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** The hash of this VIO (if not zero) */
|
|
Packit Service |
310c69 |
UdsChunkName chunkName;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* Used for logging and debugging */
|
|
Packit Service |
310c69 |
AsyncOperationNumber lastAsyncOperation;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The operation to record in the recovery and slab journals */
|
|
Packit Service |
310c69 |
ReferenceOperation operation;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* Whether this VIO is a read-and-write VIO */
|
|
Packit Service |
310c69 |
bool isPartialWrite;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* Whether this VIO contains all zeros */
|
|
Packit Service |
310c69 |
bool isZeroBlock;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* Whether this VIO write is a duplicate */
|
|
Packit Service |
310c69 |
bool isDuplicate;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Whether this VIO has received an allocation (needs to be atomic so it can
|
|
Packit Service |
310c69 |
* be examined from threads not in the allocation zone).
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
AtomicBool hasAllocation;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The new partition address of this block after the VIO write completes */
|
|
Packit Service |
310c69 |
ZonedPBN newMapped;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The hash zone responsible for the chunk name (NULL if isZeroBlock) */
|
|
Packit Service |
310c69 |
HashZone *hashZone;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The lock this VIO holds or shares with other VIOs with the same data */
|
|
Packit Service |
310c69 |
HashLock *hashLock;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* All DataVIOs sharing a hash lock are kept in a ring linking these nodes */
|
|
Packit Service |
310c69 |
RingNode hashLockNode;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The block number in the partition of the albireo deduplication advice */
|
|
Packit Service |
310c69 |
ZonedPBN duplicate;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* The sequence number of the recovery journal block containing the increment
|
|
Packit Service |
310c69 |
* entry for this VIO.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
SequenceNumber recoverySequenceNumber;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The point in the recovery journal where this write last made an entry */
|
|
Packit Service |
310c69 |
JournalPoint recoveryJournalPoint;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The RingNode of VIOs in user initiated write requests */
|
|
Packit Service |
310c69 |
RingNode writeNode;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* A flag indicating that a data write VIO has a flush generation lock */
|
|
Packit Service |
310c69 |
bool hasFlushGenerationLock;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The generation number of the VDO that this VIO belongs to */
|
|
Packit Service |
310c69 |
SequenceNumber flushGeneration;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* The completion to use for fetching block map pages for this vio */
|
|
Packit Service |
310c69 |
VDOPageCompletion pageCompletion;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* All of the fields necessary for the compression path */
|
|
Packit Service |
310c69 |
CompressionState compression;
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert an AllocatingVIO to a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param allocatingVIO The AllocatingVIO to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The AllocatingVIO as a DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline DataVIO *allocatingVIOAsDataVIO(AllocatingVIO *allocatingVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
STATIC_ASSERT(offsetof(DataVIO, allocatingVIO) == 0);
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((allocatingVIOAsVIO(allocatingVIO)->type == VIO_TYPE_DATA),
|
|
Packit Service |
310c69 |
"AllocatingVIO is a DataVIO");
|
|
Packit Service |
310c69 |
return (DataVIO *) allocatingVIO;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a VIO to a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param vio The VIO to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The VIO as a DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline DataVIO *vioAsDataVIO(VIO *vio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
STATIC_ASSERT(offsetof(DataVIO, allocatingVIO) == 0);
|
|
Packit Service |
310c69 |
STATIC_ASSERT(offsetof(AllocatingVIO, vio) == 0);
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((vio->type == VIO_TYPE_DATA), "VIO is a DataVIO");
|
|
Packit Service |
310c69 |
return (DataVIO *) vio;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a DataVIO to an AllocatingVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The DataVIO as an AllocatingVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline AllocatingVIO *dataVIOAsAllocatingVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return &dataVIO->allocatingVIO;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a DataVIO to a VIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The DataVIO as a VIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline VIO *dataVIOAsVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return allocatingVIOAsVIO(dataVIOAsAllocatingVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a generic VDOCompletion to a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param completion The completion to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The completion as a DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline DataVIO *asDataVIO(VDOCompletion *completion)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return vioAsDataVIO(asVIO(completion));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a DataVIO to a generic completion.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The DataVIO as a completion
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline VDOCompletion *dataVIOAsCompletion(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return allocatingVIOAsCompletion(dataVIOAsAllocatingVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a DataVIO to a generic wait queue entry.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The DataVIO as a wait queue entry
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline Waiter *dataVIOAsWaiter(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return allocatingVIOAsWaiter(dataVIOAsAllocatingVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Convert a DataVIO's generic wait queue entry back to the DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param waiter The wait queue entry to convert
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The wait queue entry as a DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline DataVIO *waiterAsDataVIO(Waiter *waiter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (waiter == NULL) {
|
|
Packit Service |
310c69 |
return NULL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return allocatingVIOAsDataVIO(waiterAsAllocatingVIO(waiter));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a DataVIO is a read.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to check
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline bool isReadDataVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return isReadVIO(dataVIOAsVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a DataVIO is a write.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to check
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline bool isWriteDataVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return isWriteVIO(dataVIOAsVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a DataVIO is a compressed block write.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to check
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if the DataVIO is a compressed block write
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline bool isCompressedWriteDataVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return isCompressedWriteVIO(dataVIOAsVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a DataVIO is a trim.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to check
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if the DataVIO is a trim
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline bool isTrimDataVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return (dataVIO->newMapped.state == MAPPING_STATE_UNMAPPED);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the location that should passed Albireo as the new advice for where to
|
|
Packit Service |
310c69 |
* find the data written by this DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The write DataVIO that is ready to update Albireo
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return a DataLocation containing the advice to store in Albireo
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline DataLocation getDataVIONewAdvice(const DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return (DataLocation) {
|
|
Packit Service |
310c69 |
.pbn = dataVIO->newMapped.pbn,
|
|
Packit Service |
310c69 |
.state = dataVIO->newMapped.state,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the VDO from a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO from which to get the VDO
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The VDO to which a DataVIO belongs
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline VDO *getVDOFromDataVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return dataVIOAsVIO(dataVIO)->vdo;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the ThreadConfig from a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO from which to get the ThreadConfig
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The ThreadConfig of the VDO to which a DataVIO belongs
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline const ThreadConfig *getThreadConfigFromDataVIO(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return getThreadConfig(getVDOFromDataVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the allocation of a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The allocation of the DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline PhysicalBlockNumber getDataVIOAllocation(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return dataVIOAsAllocatingVIO(dataVIO)->allocation;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether a DataVIO has an allocation.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to check
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if the DataVIO has an allocated block
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline bool hasAllocation(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return (getDataVIOAllocation(dataVIO) != ZERO_BLOCK);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* (Re)initialize a DataVIO to have a new logical block number, keeping the
|
|
Packit Service |
310c69 |
* same parent and other state. This method must be called before using a
|
|
Packit Service |
310c69 |
* DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to initialize
|
|
Packit Service |
310c69 |
* @param lbn The logical block number of the DataVIO
|
|
Packit Service |
310c69 |
* @param operation The operation this DataVIO will perform
|
|
Packit Service |
310c69 |
* @param isTrim true if this DataVIO is for a trim request
|
|
Packit Service |
310c69 |
* @param callback The function to call once the VIO has completed its
|
|
Packit Service |
310c69 |
* operation
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void prepareDataVIO(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
LogicalBlockNumber lbn,
|
|
Packit Service |
310c69 |
VIOOperation operation,
|
|
Packit Service |
310c69 |
bool isTrim,
|
|
Packit Service |
310c69 |
VDOAction *callback);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Complete the processing of a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param completion The completion of the VIO to complete
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void completeDataVIO(VDOCompletion *completion);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Finish processing a DataVIO, possibly due to an error. This function will
|
|
Packit Service |
310c69 |
* set any error, and then initiate DataVIO clean up.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to abort
|
|
Packit Service |
310c69 |
* @param result The result of processing the DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void finishDataVIO(DataVIO *dataVIO, int result);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Continue processing a DataVIO that has been waiting for an event, setting
|
|
Packit Service |
310c69 |
* the result from the event and calling the current callback.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to continue
|
|
Packit Service |
310c69 |
* @param result The current result (will not mask older errors)
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void continueDataVIO(DataVIO *dataVIO, int result)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
continueCompletion(dataVIOAsCompletion(dataVIO), result);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the name of the last asynchronous operation performed on a DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The name of the last operation performed on the DataVIO
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
const char *getOperationName(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result));
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Add a trace record for the current source location.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO structure to be updated
|
|
Packit Service |
310c69 |
* @param location The source-location descriptor to be recorded
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void dataVIOAddTraceRecord(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
vioAddTraceRecord(dataVIOAsVIO(dataVIO), location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Add a DataVIO to the tail end of a wait queue. The DataVIO must not already
|
|
Packit Service |
310c69 |
* be waiting in a queue. A trace record is also generated for the DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param queue The queue to which to add the waiter
|
|
Packit Service |
310c69 |
* @param waiter The DataVIO to add to the queue
|
|
Packit Service |
310c69 |
* @param location The source-location descriptor to be traced in the DataVIO
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return VDO_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result))
|
|
Packit Service |
310c69 |
static inline int enqueueDataVIO(WaitQueue *queue,
|
|
Packit Service |
310c69 |
DataVIO *waiter,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(waiter, location);
|
|
Packit Service |
310c69 |
return enqueueWaiter(queue, dataVIOAsWaiter(waiter));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the correct thread for its hash zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInHashZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected = getHashZoneThreadID(dataVIO->hashZone);
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
// It's odd to use the LBN, but converting the chunk name to hex is a bit
|
|
Packit Service |
310c69 |
// clunky for an inline, and the LBN better than nothing as an identifier.
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for logical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on hash zone thread %u",
|
|
Packit Service |
310c69 |
dataVIO->logical.lbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a hash zone operation. This function presumes that the
|
|
Packit Service |
310c69 |
* hashZone field of the DataVIO has already been set.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setHashZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getHashZoneThreadID(dataVIO->hashZone));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a hash zone operation and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchHashZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setHashZoneCallback(dataVIO, callback, location);
|
|
Packit Service |
310c69 |
invokeCallback(dataVIOAsCompletion(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the correct thread for its logical zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInLogicalZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected = getLogicalZoneThreadID(dataVIO->logical.zone);
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for logical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on thread %u",
|
|
Packit Service |
310c69 |
dataVIO->logical.lbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a logical block operation. This function presumes that the
|
|
Packit Service |
310c69 |
* logicalZone field of the DataVIO has already been set.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setLogicalCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getLogicalZoneThreadID(dataVIO->logical.zone));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a logical block operation and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchLogicalCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setLogicalCallback(dataVIO, callback, location);
|
|
Packit Service |
310c69 |
invokeCallback(dataVIOAsCompletion(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the correct thread for its allocated
|
|
Packit Service |
310c69 |
* zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInAllocatedZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
assertInPhysicalZone(dataVIOAsAllocatingVIO(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's allocated zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setAllocatedZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setPhysicalZoneCallback(dataVIOAsAllocatingVIO(dataVIO), callback,
|
|
Packit Service |
310c69 |
location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's allocated zone
|
|
Packit Service |
310c69 |
* and queue the DataVIO and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to invoke
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchAllocatedZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
launchPhysicalZoneCallback(dataVIOAsAllocatingVIO(dataVIO), callback,
|
|
Packit Service |
310c69 |
location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the correct thread for its duplicate
|
|
Packit Service |
310c69 |
* zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInDuplicateZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected = getPhysicalZoneThreadID(dataVIO->duplicate.zone);
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for duplicate physical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on thread %u",
|
|
Packit Service |
310c69 |
dataVIO->duplicate.pbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's duplicate zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setDuplicateZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getPhysicalZoneThreadID(dataVIO->duplicate.zone));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's duplicate zone
|
|
Packit Service |
310c69 |
* and queue the DataVIO and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to invoke
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchDuplicateZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setDuplicateZoneCallback(dataVIO, callback, location);
|
|
Packit Service |
310c69 |
invokeCallback(dataVIOAsCompletion(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the correct thread for its mapped zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInMappedZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected = getPhysicalZoneThreadID(dataVIO->mapped.zone);
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for mapped physical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on thread %u",
|
|
Packit Service |
310c69 |
dataVIO->mapped.pbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's mapped zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setMappedZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getPhysicalZoneThreadID(dataVIO->mapped.zone));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the correct thread for its newMapped
|
|
Packit Service |
310c69 |
* zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInNewMappedZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected = getPhysicalZoneThreadID(dataVIO->newMapped.zone);
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for newMapped physical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on thread %u",
|
|
Packit Service |
310c69 |
dataVIO->newMapped.pbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's newMapped zone.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setNewMappedZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getPhysicalZoneThreadID(dataVIO->newMapped.zone));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a physical block operation in a DataVIO's newMapped zone
|
|
Packit Service |
310c69 |
* and queue the DataVIO and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO
|
|
Packit Service |
310c69 |
* @param callback The callback to invoke
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchNewMappedZoneCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setNewMappedZoneCallback(dataVIO, callback, location);
|
|
Packit Service |
310c69 |
invokeCallback(dataVIOAsCompletion(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the journal thread.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInJournalZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected
|
|
Packit Service |
310c69 |
= getJournalZoneThread(getThreadConfigFromDataVIO(dataVIO));
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for logical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on journal thread %u",
|
|
Packit Service |
310c69 |
dataVIO->logical.lbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a journal operation.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setJournalCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getJournalZoneThread(getThreadConfigFromDataVIO(dataVIO)));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a journal operation and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchJournalCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setJournalCallback(dataVIO, callback, location);
|
|
Packit Service |
310c69 |
invokeCallback(dataVIOAsCompletion(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check that a DataVIO is running on the packer thread
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO in question
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void assertInPackerZone(DataVIO *dataVIO)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ThreadID expected = getPackerZoneThread(getThreadConfigFromDataVIO(dataVIO));
|
|
Packit Service |
310c69 |
ThreadID threadID = getCallbackThreadID();
|
|
Packit Service |
310c69 |
ASSERT_LOG_ONLY((expected == threadID),
|
|
Packit Service |
310c69 |
"DataVIO for logical block %" PRIu64
|
|
Packit Service |
310c69 |
" on thread %u, should be on packer thread %u",
|
|
Packit Service |
310c69 |
dataVIO->logical.lbn, threadID, expected);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a packer operation.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setPackerCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setCallback(dataVIOAsCompletion(dataVIO), callback,
|
|
Packit Service |
310c69 |
getPackerZoneThread(getThreadConfigFromDataVIO(dataVIO)));
|
|
Packit Service |
310c69 |
dataVIOAddTraceRecord(dataVIO, location);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a callback as a packer operation and invoke it immediately.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO with which to set the callback
|
|
Packit Service |
310c69 |
* @param callback The callback to set
|
|
Packit Service |
310c69 |
* @param location The tracing info for the call site
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void launchPackerCallback(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
VDOAction *callback,
|
|
Packit Service |
310c69 |
TraceLocation location)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setPackerCallback(dataVIO, callback, location);
|
|
Packit Service |
310c69 |
invokeCallback(dataVIOAsCompletion(dataVIO));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check whether the advice received from Albireo is a valid data location,
|
|
Packit Service |
310c69 |
* and if it is, accept it as the location of a potential duplicate of the
|
|
Packit Service |
310c69 |
* DataVIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO that queried Albireo
|
|
Packit Service |
310c69 |
* @param advice A potential location of the data, or NULL for no advice
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void receiveDedupeAdvice(DataVIO *dataVIO, const DataLocation *advice);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the location of the duplicate block for a DataVIO, updating the
|
|
Packit Service |
310c69 |
* isDuplicate and duplicate fields from a ZonedPBN.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to modify
|
|
Packit Service |
310c69 |
* @param source The location of the duplicate
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void setDuplicateLocation(DataVIO *dataVIO, const ZonedPBN source);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Clear a DataVIO's mapped block location, setting it to be unmapped. This
|
|
Packit Service |
310c69 |
* indicates the block map entry for the logical block is either unmapped or
|
|
Packit Service |
310c69 |
* corrupted.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO whose mapped block location is to be reset
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void clearMappedLocation(DataVIO *dataVIO);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a DataVIO's mapped field to the physical location recorded in the block
|
|
Packit Service |
310c69 |
* map for the logical block in the VIO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO whose field is to be set
|
|
Packit Service |
310c69 |
* @param pbn The physical block number to set
|
|
Packit Service |
310c69 |
* @param state The mapping state to set
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return VDO_SUCCESS or an error code if the mapping is unusable
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
int setMappedLocation(DataVIO *dataVIO,
|
|
Packit Service |
310c69 |
PhysicalBlockNumber pbn,
|
|
Packit Service |
310c69 |
BlockMappingState state)
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result));
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Attempt to acquire the lock on a logical block. This is the start of the
|
|
Packit Service |
310c69 |
* path for all external requests. It is registered in prepareDataVIO().
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param completion The DataVIO for an external data request as a completion
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void attemptLogicalBlockLock(VDOCompletion *completion);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Release the lock on the logical block, if any, that a DataVIO has acquired.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO releasing its logical block lock
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void releaseLogicalBlockLock(DataVIO *dataVIO);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#endif // DATA_VIO_H
|