Blame source/vdo/kernel/kernelLayer.h

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