Blame source/vdo/kernel/kernelLayer.h

Packit Service d40955
/*
Packit Service d40955
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service d40955
 *
Packit Service d40955
 * This program is free software; you can redistribute it and/or
Packit Service d40955
 * modify it under the terms of the GNU General Public License
Packit Service d40955
 * as published by the Free Software Foundation; either version 2
Packit Service d40955
 * of the License, or (at your option) any later version.
Packit Service d40955
 * 
Packit Service d40955
 * This program is distributed in the hope that it will be useful,
Packit Service d40955
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d40955
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d40955
 * GNU General Public License for more details.
Packit Service d40955
 * 
Packit Service d40955
 * You should have received a copy of the GNU General Public License
Packit Service d40955
 * along with this program; if not, write to the Free Software
Packit Service d40955
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service d40955
 * 02110-1301, USA. 
Packit Service d40955
 *
Packit Service d40955
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/kernelLayer.h#18 $
Packit Service d40955
 */
Packit Service d40955
Packit Service d40955
#ifndef KERNELLAYER_H
Packit Service d40955
#define KERNELLAYER_H
Packit Service d40955
Packit Service d40955
#include <linux/device-mapper.h>
Packit Service d40955
Packit Service d40955
#include "atomic.h"
Packit Service d40955
#include "constants.h"
Packit Service d40955
#include "flush.h"
Packit Service d40955
#include "intMap.h"
Packit Service d40955
#include "physicalLayer.h"
Packit Service d40955
#include "ringNode.h"
Packit Service d40955
#include "volumeGeometry.h"
Packit Service d40955
#include "waitQueue.h"
Packit Service d40955
Packit Service d40955
#include "batchProcessor.h"
Packit Service d40955
#include "bufferPool.h"
Packit Service d40955
#include "deadlockQueue.h"
Packit Service d40955
#include "deviceConfig.h"
Packit Service d40955
#include "histogram.h"
Packit Service d40955
#include "kernelStatistics.h"
Packit Service d40955
#include "kernelTypes.h"
Packit Service d40955
#include "kernelVDO.h"
Packit Service d40955
#include "ktrace.h"
Packit Service d40955
#include "limiter.h"
Packit Service d40955
#include "statistics.h"
Packit Service d40955
#include "workQueue.h"
Packit Service d40955
Packit Service d40955
enum {
Packit Service d40955
  VDO_SECTORS_PER_BLOCK = (VDO_BLOCK_SIZE >> SECTOR_SHIFT)
Packit Service d40955
};
Packit Service d40955
Packit Service d40955
typedef enum {
Packit Service d40955
  LAYER_SIMPLE_THINGS_INITIALIZED,
Packit Service d40955
  LAYER_BUFFER_POOLS_INITIALIZED,
Packit Service d40955
  LAYER_REQUEST_QUEUE_INITIALIZED,
Packit Service d40955
  LAYER_CPU_QUEUE_INITIALIZED,
Packit Service d40955
  LAYER_BIO_ACK_QUEUE_INITIALIZED,
Packit Service d40955
  LAYER_BIO_DATA_INITIALIZED,
Packit Service d40955
  LAYER_STARTING,
Packit Service d40955
  LAYER_RUNNING,
Packit Service d40955
  LAYER_SUSPENDED,
Packit Service d40955
  LAYER_STOPPING,
Packit Service d40955
  LAYER_STOPPED,
Packit Service d40955
  LAYER_RESUMING,
Packit Service d40955
} KernelLayerState;
Packit Service d40955
Packit Service d40955
/* Keep BIO statistics atomically */
Packit Service d40955
struct atomicBioStats {
Packit Service d40955
  atomic64_t read;              // Number of not REQ_WRITE bios
Packit Service d40955
  atomic64_t write;             // Number of REQ_WRITE bios
Packit Service d40955
  atomic64_t discard;           // Number of REQ_DISCARD bios
Packit Service d40955
  atomic64_t flush;             // Number of REQ_FLUSH bios
Packit Service d40955
  atomic64_t fua;               // Number of REQ_FUA bios
Packit Service d40955
};
Packit Service d40955
Packit Service d40955
// Data managing the reporting of Albireo timeouts
Packit Service d40955
typedef struct periodicEventReporter {
Packit Service d40955
  uint64_t             lastReportedValue;
Packit Service d40955
  const char          *format;
Packit Service d40955
  atomic64_t           value;
Packit Service d40955
  Jiffies              reportingInterval; // jiffies
Packit Service d40955
  /*
Packit Service d40955
   * Just an approximation.  If nonzero, then either the work item has
Packit Service d40955
   * been queued to run, or some other thread currently has
Packit Service d40955
   * responsibility for enqueueing it, or the reporter function is
Packit Service d40955
   * running but hasn't looked at the current value yet.
Packit Service d40955
   *
Packit Service d40955
   * If this is set, don't set the timer again, because we don't want
Packit Service d40955
   * the work item queued twice.  Use an atomic xchg or cmpxchg to
Packit Service d40955
   * test-and-set it, and an atomic store to clear it.
Packit Service d40955
   */
Packit Service d40955
  atomic_t             workItemQueued;
Packit Service d40955
  KvdoWorkItem         workItem;
Packit Service d40955
  KernelLayer         *layer;
Packit Service d40955
} PeriodicEventReporter;
Packit Service d40955
Packit Service d40955
static inline uint64_t getEventCount(PeriodicEventReporter *reporter)
Packit Service d40955
{
Packit Service d40955
  return atomic64_read(&reporter->value);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * The VDO representation of the target device
Packit Service d40955
 **/
Packit Service d40955
struct kernelLayer {
Packit Service d40955
  PhysicalLayer           common;
Packit Service d40955
  // Layer specific info
Packit Service d40955
  DeviceConfig           *deviceConfig;
Packit Service d40955
  /** A ring of all DeviceConfigs referencing this layer */
Packit Service d40955
  RingNode                deviceConfigRing;
Packit Service d40955
  char                    threadNamePrefix[MAX_QUEUE_NAME_LEN];
Packit Service d40955
  struct kobject          kobj;
Packit Service d40955
  struct kobject          wqDirectory;
Packit Service d40955
  struct kobject          statsDirectory;
Packit Service d40955
  /**
Packit Service d40955
   * A counter value to attach to thread names and log messages to
Packit Service d40955
   * identify the individual device.
Packit Service d40955
   **/
Packit Service d40955
  unsigned int            instance;
Packit Service d40955
  /** Contains the current KernelLayerState, which rarely changes */
Packit Service d40955
  Atomic32                state;
Packit Service d40955
  bool                    noFlushSuspend;
Packit Service d40955
  bool                    allocationsAllowed;
Packit Service d40955
  AtomicBool              processingMessage;
Packit Service d40955
  /** Limit the number of requests that are being processed. */
Packit Service d40955
  Limiter                 requestLimiter;
Packit Service d40955
  Limiter                 discardLimiter;
Packit Service d40955
  KVDO                    kvdo;
Packit Service d40955
  /** Incoming bios we've had to buffer to avoid deadlock. */
Packit Service d40955
  DeadlockQueue           deadlockQueue;
Packit Service d40955
  // for REQ_FLUSH processing
Packit Service d40955
  struct bio_list         waitingFlushes;
Packit Service d40955
  KVDOFlush              *spareKVDOFlush;
Packit Service d40955
  spinlock_t              flushLock;
Packit Service d40955
  Jiffies                 flushArrivalTime;
Packit Service d40955
  /**
Packit Service d40955
   * Bio submission manager used for sending bios to the storage
Packit Service d40955
   * device.
Packit Service d40955
   **/
Packit Service d40955
  IOSubmitter            *ioSubmitter;
Packit Service d40955
  /**
Packit Service d40955
   * Work queue (possibly with multiple threads) for miscellaneous
Packit Service d40955
   * CPU-intensive, non-blocking work.
Packit Service d40955
   **/
Packit Service d40955
  KvdoWorkQueue          *cpuQueue;
Packit Service d40955
  /** N blobs of context data for LZ4 code, one per CPU thread. */
Packit Service d40955
  char                  **compressionContext;
Packit Service d40955
  Atomic32                compressionContextIndex;
Packit Service d40955
  /** Optional work queue for calling bio_endio. */
Packit Service d40955
  KvdoWorkQueue          *bioAckQueue;
Packit Service d40955
  /** Underlying block device info. */
Packit Service d40955
  uint64_t                startingSectorOffset;
Packit Service d40955
  VolumeGeometry          geometry;
Packit Service d40955
  // Memory allocation
Packit Service d40955
  BufferPool             *dataKVIOPool;
Packit Service d40955
  struct bio_set         *bioset;
Packit Service d40955
  // Albireo specific info
Packit Service d40955
  DedupeIndex            *dedupeIndex;
Packit Service d40955
  // Statistics
Packit Service d40955
  atomic64_t              biosSubmitted;
Packit Service d40955
  atomic64_t              biosCompleted;
Packit Service d40955
  atomic64_t              dedupeContextBusy;
Packit Service d40955
  atomic64_t              flushOut;
Packit Service d40955
  AtomicBioStats          biosIn;
Packit Service d40955
  AtomicBioStats          biosInPartial;
Packit Service d40955
  AtomicBioStats          biosOut;
Packit Service d40955
  AtomicBioStats          biosOutCompleted;
Packit Service d40955
  AtomicBioStats          biosAcknowledged;
Packit Service d40955
  AtomicBioStats          biosAcknowledgedPartial;
Packit Service d40955
  AtomicBioStats          biosMeta;
Packit Service d40955
  AtomicBioStats          biosMetaCompleted;
Packit Service d40955
  AtomicBioStats          biosJournal;
Packit Service d40955
  AtomicBioStats          biosPageCache;
Packit Service d40955
  AtomicBioStats          biosJournalCompleted;
Packit Service d40955
  AtomicBioStats          biosPageCacheCompleted;
Packit Service d40955
  // for reporting Albireo timeouts
Packit Service d40955
  PeriodicEventReporter   albireoTimeoutReporter;
Packit Service d40955
  // Debugging
Packit Service d40955
  /* Whether to dump VDO state on shutdown */
Packit Service d40955
  bool                    dumpOnShutdown;
Packit Service d40955
  /**
Packit Service d40955
   * Whether we should collect tracing info. (Actually, this controls
Packit Service d40955
   * allocations; non-null record pointers cause recording.)
Packit Service d40955
   **/
Packit Service d40955
  bool                    vioTraceRecording;
Packit Service d40955
  SampleCounter           traceSampleCounter;
Packit Service d40955
  /* Should we log tracing info? */
Packit Service d40955
  bool                    traceLogging;
Packit Service d40955
  /* Storage for trace data. */
Packit Service d40955
  BufferPool             *traceBufferPool;
Packit Service d40955
  /* Private storage for procfs. */
Packit Service d40955
  void                   *procfsPrivate;
Packit Service d40955
  /* For returning batches of DataKVIOs to their pool */
Packit Service d40955
  BatchProcessor         *dataKVIOReleaser;
Packit Service d40955
Packit Service d40955
  // Administrative operations
Packit Service d40955
  /* The object used to wait for administrative operations to complete */
Packit Service d40955
  struct completion       callbackSync;
Packit Service d40955
Packit Service d40955
  // Statistics reporting
Packit Service d40955
  /* Protects the *statsStorage structs */
Packit Service d40955
  struct mutex            statsMutex;
Packit Service d40955
  /* Used when shutting down the sysfs statistics */
Packit Service d40955
  struct completion       statsShutdown;;
Packit Service d40955
  /* true if sysfs statistics directory is set up */
Packit Service d40955
  bool                    statsAdded;
Packit Service d40955
  /* Used to gather statistics without allocating memory */
Packit Service d40955
  VDOStatistics           vdoStatsStorage;
Packit Service d40955
  KernelStatistics        kernelStatsStorage;
Packit Service d40955
};
Packit Service d40955
Packit Service d40955
typedef enum bioQAction {
Packit Service d40955
  BIO_Q_ACTION_COMPRESSED_DATA,
Packit Service d40955
  BIO_Q_ACTION_DATA,
Packit Service d40955
  BIO_Q_ACTION_FLUSH,
Packit Service d40955
  BIO_Q_ACTION_HIGH,
Packit Service d40955
  BIO_Q_ACTION_METADATA,
Packit Service d40955
  BIO_Q_ACTION_READCACHE,
Packit Service d40955
  BIO_Q_ACTION_VERIFY
Packit Service d40955
} BioQAction;
Packit Service d40955
Packit Service d40955
typedef enum cpuQAction {
Packit Service d40955
  CPU_Q_ACTION_COMPLETE_KVIO,
Packit Service d40955
  CPU_Q_ACTION_COMPRESS_BLOCK,
Packit Service d40955
  CPU_Q_ACTION_EVENT_REPORTER,
Packit Service d40955
  CPU_Q_ACTION_HASH_BLOCK,
Packit Service d40955
} CPUQAction;
Packit Service d40955
Packit Service d40955
typedef enum bioAckQAction {
Packit Service d40955
  BIO_ACK_Q_ACTION_ACK,
Packit Service d40955
} BioAckQAction;
Packit Service d40955
Packit Service d40955
typedef void (*DedupeShutdownCallbackFunction)(KernelLayer *layer);
Packit Service d40955
Packit Service d40955
/*
Packit Service d40955
 * Wrapper for the Enqueueable object, to associate it with a kernel
Packit Service d40955
 * layer work item.
Packit Service d40955
 */
Packit Service d40955
typedef struct kvdoEnqueueable {
Packit Service d40955
  KvdoWorkItem workItem;
Packit Service d40955
  Enqueueable  enqueueable;
Packit Service d40955
} KvdoEnqueueable;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Implements LayerFilter.
Packit Service d40955
 **/
Packit Service d40955
bool layerIsNamed(KernelLayer *layer, void *context)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Creates a kernel specific physical layer to be used by VDO
Packit Service d40955
 *
Packit Service d40955
 * @param startingSector        The sector offset of our table entry in the
Packit Service d40955
 *                              DM device
Packit Service d40955
 * @param instance              Device instantiation counter
Packit Service d40955
 * @param parentKobject         The parent sysfs node
Packit Service d40955
 * @param config                The device configuration
Packit Service d40955
 * @param threadConfigPointer   Where to store the new threadConfig handle
Packit Service d40955
 * @param reason                The reason for any failure during this call
Packit Service d40955
 * @param layerPtr              A pointer to hold the created layer
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int makeKernelLayer(uint64_t        startingSector,
Packit Service d40955
                    unsigned int    instance,
Packit Service d40955
                    DeviceConfig   *config,
Packit Service d40955
                    struct kobject *parentKobject,
Packit Service d40955
                    ThreadConfig  **threadConfigPointer,
Packit Service d40955
                    char          **reason,
Packit Service d40955
                    KernelLayer   **layerPtr)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Prepare to modify a kernel layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer     The layer to modify
Packit Service d40955
 * @param config    The new device configuration
Packit Service d40955
 * @param errorPtr  A pointer to store the reason for any failure
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int prepareToModifyKernelLayer(KernelLayer       *layer,
Packit Service d40955
                               DeviceConfig      *config,
Packit Service d40955
                               char             **errorPtr)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Modify a kernel physical layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer   The layer to modify
Packit Service d40955
 * @param config  The new device configuration
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int modifyKernelLayer(KernelLayer       *layer,
Packit Service d40955
                      DeviceConfig      *config)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Free a kernel physical layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer    The layer, which must have been created by
Packit Service d40955
 *                 makeKernelLayer
Packit Service d40955
 **/
Packit Service d40955
void freeKernelLayer(KernelLayer *layer);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Make and configure a kernel layer. This method does not alter the VDO state
Packit Service d40955
 * on disk. It should be run from the VDO constructor for devices which have
Packit Service d40955
 * not been started.
Packit Service d40955
 *
Packit Service d40955
 * @param layer       The kernel layer
Packit Service d40955
 * @param loadConfig  Load-time parameters for the VDO
Packit Service d40955
 * @param reason      The reason for any failure during this call
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 *
Packit Service d40955
 * @note redundant starts are silently ignored
Packit Service d40955
 **/
Packit Service d40955
int preloadKernelLayer(KernelLayer          *layer,
Packit Service d40955
                       const VDOLoadConfig  *loadConfig,
Packit Service d40955
                       char                **reason);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Start the kernel layer. This method finishes bringing a VDO online now that
Packit Service d40955
 * a table is being resumed for the first time.
Packit Service d40955
 *
Packit Service d40955
 * @param layer   The kernel layer
Packit Service d40955
 * @param reason  The reason for any failure during this call
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int startKernelLayer(KernelLayer *layer, char **reason);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Stop the kernel layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer
Packit Service d40955
 **/
Packit Service d40955
void stopKernelLayer(KernelLayer *layer);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Suspend the kernel layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int suspendKernelLayer(KernelLayer *layer);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Resume the kernel layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 **/
Packit Service d40955
int resumeKernelLayer(KernelLayer *layer);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Get the kernel layer state.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer
Packit Service d40955
 *
Packit Service d40955
 * @return the instantaneously correct kernel layer state
Packit Service d40955
 **/
Packit Service d40955
static inline KernelLayerState getKernelLayerState(const KernelLayer *layer)
Packit Service d40955
{
Packit Service d40955
  return atomicLoad32(&layer->state);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Function call to begin processing a bio passed in from the block layer
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The physical layer
Packit Service d40955
 * @param bio    The bio from the block layer
Packit Service d40955
 *
Packit Service d40955
 * @return value to return from the VDO map function.  Either an error code
Packit Service d40955
 *         or DM_MAPIO_REMAPPED or DM_MAPPED_SUBMITTED (see vdoMapBio for
Packit Service d40955
 *         details).
Packit Service d40955
 **/
Packit Service d40955
int kvdoMapBio(KernelLayer *layer, BIO *bio);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Convert a generic PhysicalLayer to a kernelLayer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer The PhysicalLayer to convert
Packit Service d40955
 *
Packit Service d40955
 * @return The PhysicalLayer as a KernelLayer
Packit Service d40955
 **/
Packit Service d40955
static inline KernelLayer *asKernelLayer(PhysicalLayer *layer)
Packit Service d40955
{
Packit Service d40955
  return container_of(layer, KernelLayer, common);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Convert a block number (or count) to a (512-byte-)sector number.
Packit Service d40955
 *
Packit Service d40955
 * The argument type is sector_t to force conversion to the type we
Packit Service d40955
 * want, although the actual values passed are of various integral
Packit Service d40955
 * types.  It's just too easy to forget and do the multiplication
Packit Service d40955
 * without casting, resulting in 32-bit arithmetic that accidentally
Packit Service d40955
 * produces wrong results in devices over 2TB (2**32 sectors).
Packit Service d40955
 *
Packit Service d40955
 * @param [in] layer        the physical layer
Packit Service d40955
 * @param [in] blockNumber  the block number/count
Packit Service d40955
 *
Packit Service d40955
 * @return      the sector number/count
Packit Service d40955
 **/
Packit Service d40955
static inline sector_t blockToSector(KernelLayer *layer, sector_t blockNumber)
Packit Service d40955
{
Packit Service d40955
  return (blockNumber * VDO_SECTORS_PER_BLOCK);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Convert a sector number (or count) to a block number. Does not
Packit Service d40955
 * check to make sure the sector number is an integral number of
Packit Service d40955
 * blocks.
Packit Service d40955
 *
Packit Service d40955
 * @param [in] layer         the physical layer
Packit Service d40955
 * @param [in] sectorNumber  the sector number/count
Packit Service d40955
 *
Packit Service d40955
 * @return      the block number/count
Packit Service d40955
 **/
Packit Service d40955
static inline sector_t sectorToBlock(KernelLayer *layer, sector_t sectorNumber)
Packit Service d40955
{
Packit Service d40955
  return (sectorNumber / VDO_SECTORS_PER_BLOCK);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Convert a sector number to an offset within a block.
Packit Service d40955
 *
Packit Service d40955
 * @param [in] layer         the physical layer
Packit Service d40955
 * @param [in] sectorNumber  the sector number
Packit Service d40955
 *
Packit Service d40955
 * @return      the offset within the block
Packit Service d40955
 **/
Packit Service d40955
static inline BlockSize sectorToBlockOffset(KernelLayer *layer,
Packit Service d40955
                                            sector_t     sectorNumber)
Packit Service d40955
{
Packit Service d40955
  unsigned int sectorsPerBlockMask = VDO_SECTORS_PER_BLOCK - 1;
Packit Service d40955
  return to_bytes(sectorNumber & sectorsPerBlockMask);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Get the block device object currently underlying a kernel layer.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer in question
Packit Service d40955
 *
Packit Service d40955
 * @return The block device object under the layer
Packit Service d40955
 **/
Packit Service d40955
struct block_device *getKernelLayerBdev(const KernelLayer *layer)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Set the layer's active config.
Packit Service d40955
 *
Packit Service d40955
 * @param layer   The kernel layer in question
Packit Service d40955
 * @param config  The config in question
Packit Service d40955
 **/
Packit Service d40955
static inline void setKernelLayerActiveConfig(KernelLayer  *layer,
Packit Service d40955
                                              DeviceConfig *config)
Packit Service d40955
{
Packit Service d40955
  layer->deviceConfig = config;
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Given an error code, return a value we can return to the OS.  The
Packit Service d40955
 * input error code may be a system-generated value (such as -EIO), an
Packit Service d40955
 * errno macro used in our code (such as EIO), or a UDS or VDO status
Packit Service d40955
 * code; the result must be something the rest of the OS can consume
Packit Service d40955
 * (negative errno values such as -EIO, in the case of the kernel).
Packit Service d40955
 *
Packit Service d40955
 * @param error    the error code to convert
Packit Service d40955
 *
Packit Service d40955
 * @return   a system error code value
Packit Service d40955
 **/
Packit Service d40955
int mapToSystemError(int error);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Record and eventually report that some number of dedupe requests
Packit Service d40955
 * reached their expiration time without getting an answer, so we
Packit Service d40955
 * timed out on them.
Packit Service d40955
 *
Packit Service d40955
 * This is called in a timer context, so it shouldn't do the reporting
Packit Service d40955
 * directly.
Packit Service d40955
 *
Packit Service d40955
 * @param layer          The kernel layer for the device
Packit Service d40955
 * @param expiredCount   The number of expired requests we timed out on
Packit Service d40955
 **/
Packit Service d40955
void kvdoReportDedupeTimeout(KernelLayer *layer, unsigned int expiredCount);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Wait until there are no requests in progress.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer for the device
Packit Service d40955
 **/
Packit Service d40955
void waitForNoRequestsActive(KernelLayer *layer);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Enqueues an item on our internal "cpu queues". Since there is more than
Packit Service d40955
 * one, we rotate through them in hopes of creating some general balance.
Packit Service d40955
 *
Packit Service d40955
 * @param layer The kernel layer
Packit Service d40955
 * @param item  The work item to enqueue
Packit Service d40955
 */
Packit Service d40955
static inline void enqueueCPUWorkQueue(KernelLayer *layer, KvdoWorkItem *item)
Packit Service d40955
{
Packit Service d40955
  enqueueWorkQueue(layer->cpuQueue, item);
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Adjust parameters to prepare to use a larger physical space.
Packit Service d40955
 * The size must be larger than the current size.
Packit Service d40955
 *
Packit Service d40955
 * @param layer          the kernel layer
Packit Service d40955
 * @param physicalCount  the new physical size in blocks
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 */
Packit Service d40955
int prepareToResizePhysical(KernelLayer *layer, BlockCount physicalCount);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Adjusts parameters to reflect resizing the underlying device.
Packit Service d40955
 * The size must be larger than the current size.
Packit Service d40955
 *
Packit Service d40955
 * @param layer            the kernel layer
Packit Service d40955
 * @param physicalCount    the new physical count in blocks
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 */
Packit Service d40955
int resizePhysical(KernelLayer *layer, BlockCount physicalCount);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Adjust parameters to prepare to present a larger logical space.
Packit Service d40955
 * The size must be larger than the current size.
Packit Service d40955
 *
Packit Service d40955
 * @param layer         the kernel layer
Packit Service d40955
 * @param logicalCount  the new logical size in blocks
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 */
Packit Service d40955
int prepareToResizeLogical(KernelLayer *layer, BlockCount logicalCount);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Adjust parameters to present a larger logical space.
Packit Service d40955
 * The size must be larger than the current size.
Packit Service d40955
 *
Packit Service d40955
 * @param layer         the kernel layer
Packit Service d40955
 * @param logicalCount  the new logical size in blocks
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS or an error
Packit Service d40955
 */
Packit Service d40955
int resizeLogical(KernelLayer *layer, BlockCount logicalCount);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Indicate whether the kernel layer is configured to use a separate
Packit Service d40955
 * work queue for acknowledging received and processed bios.
Packit Service d40955
 *
Packit Service d40955
 * Note that this directly controls handling of write operations, but
Packit Service d40955
 * the compile-time flag USE_BIO_ACK_QUEUE_FOR_READ is also checked
Packit Service d40955
 * for read operations.
Packit Service d40955
 *
Packit Service d40955
 * @param  layer  The kernel layer
Packit Service d40955
 *
Packit Service d40955
 * @return   Whether a bio-acknowledgement work queue is in use
Packit Service d40955
 **/
Packit Service d40955
static inline bool useBioAckQueue(KernelLayer *layer)
Packit Service d40955
{
Packit Service d40955
  return layer->deviceConfig->threadCounts.bioAckThreads > 0;
Packit Service d40955
}
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Update bookkeeping for the completion of some number of requests, so that
Packit Service d40955
 * more incoming requests can be accepted.
Packit Service d40955
 *
Packit Service d40955
 * @param layer  The kernel layer
Packit Service d40955
 * @param count  The number of completed requests
Packit Service d40955
 **/
Packit Service d40955
void completeManyRequests(KernelLayer *layer, uint32_t count);
Packit Service d40955
Packit Service d40955
#endif /* KERNELLAYER_H */