Blame source/uds/volume.h

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/uds-releases/jasper/src/uds/volume.h#14 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#ifndef VOLUME_H
Packit Service 310c69
#define VOLUME_H
Packit Service 310c69
Packit Service 310c69
#include "cacheCounters.h"
Packit Service 310c69
#include "common.h"
Packit Service 310c69
#include "chapterIndex.h"
Packit Service 310c69
#include "indexConfig.h"
Packit Service 310c69
#include "indexLayout.h"
Packit Service 310c69
#include "indexPageMap.h"
Packit Service 310c69
#include "pageCache.h"
Packit Service 310c69
#include "request.h"
Packit Service 310c69
#include "sparseCache.h"
Packit Service 310c69
#include "uds.h"
Packit Service 310c69
#include "util/radixSort.h"
Packit Service 310c69
#include "volumeStore.h"
Packit Service 310c69
Packit Service 310c69
typedef enum {
Packit Service 310c69
  READER_STATE_RUN   = 1,
Packit Service 310c69
  READER_STATE_EXIT  = 2,
Packit Service 310c69
  READER_STATE_STOP  = 4
Packit Service 310c69
} ReaderState;
Packit Service 310c69
Packit Service 310c69
typedef enum indexLookupMode {
Packit Service 310c69
  /* Always do lookups in all chapters normally.  */
Packit Service 310c69
  LOOKUP_NORMAL,
Packit Service 310c69
  /*
Packit Service 310c69
   * Don't do lookups in closed chapters; assume records not in the
Packit Service 310c69
   * open chapter are always new.  You don't want this normally; it's
Packit Service 310c69
   * for programs like albfill.  (Even then, with multiple runs using
Packit Service 310c69
   * the same tag, we may actually duplicate older records, but if
Packit Service 310c69
   * it's in a separate chapter it won't really matter.)
Packit Service 310c69
   */
Packit Service 310c69
  LOOKUP_CURRENT_CHAPTER_ONLY,
Packit Service 310c69
  /*
Packit Service 310c69
   * Only do a subset of lookups needed when rebuilding an index.
Packit Service 310c69
   * This cannot be set externally.
Packit Service 310c69
   */
Packit Service 310c69
  LOOKUP_FOR_REBUILD
Packit Service 310c69
} IndexLookupMode;
Packit Service 310c69
Packit Service 310c69
typedef struct volume {
Packit Service 310c69
  /* The layout of the volume */
Packit Service 310c69
  Geometry              *geometry;
Packit Service 310c69
  /* The configuration of the volume */
Packit Service 310c69
  Configuration         *config;
Packit Service 310c69
  /* The access to the volume's backing store */
Packit Service 310c69
  struct volume_store    volumeStore;
Packit Service 310c69
  /* A single page used for writing to the volume */
Packit Service 310c69
  struct volume_page     scratchPage;
Packit Service 310c69
  /* The nonce used to save the volume */
Packit Service 310c69
  uint64_t               nonce;
Packit Service 310c69
  /* A single page's records, for sorting */
Packit Service 310c69
  const UdsChunkRecord **recordPointers;
Packit Service 310c69
  /* For sorting record pages */
Packit Service 310c69
  RadixSorter           *radixSorter;
Packit Service 310c69
  /* The sparse chapter index cache */
Packit Service 310c69
  SparseCache           *sparseCache;
Packit Service 310c69
  /* The page cache */
Packit Service 310c69
  PageCache             *pageCache;
Packit Service 310c69
  /* The index page map maps delta list numbers to index page numbers */
Packit Service 310c69
  IndexPageMap          *indexPageMap;
Packit Service 310c69
  /* Mutex to sync between read threads and index thread */
Packit Service 310c69
  Mutex                  readThreadsMutex;
Packit Service 310c69
  /* Condvar to indicate when read threads should start working */
Packit Service 310c69
  CondVar                readThreadsCond;
Packit Service 310c69
  /* Condvar to indicate when a read thread has finished a read */
Packit Service 310c69
  CondVar                readThreadsReadDoneCond;
Packit Service 310c69
  /* Threads to read data from disk */
Packit Service 310c69
  Thread                *readerThreads;
Packit Service 310c69
  /* Number of threads busy with reads */
Packit Service 310c69
  unsigned int           busyReaderThreads;
Packit Service 310c69
  /* The state of the reader threads */
Packit Service 310c69
  ReaderState            readerState;
Packit Service 310c69
  /* The lookup mode for the index */
Packit Service 310c69
  IndexLookupMode        lookupMode;
Packit Service 310c69
  /* Number of read threads to use (run-time parameter) */
Packit Service 310c69
  unsigned int           numReadThreads;
Packit Service 310c69
} Volume;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Create a volume.
Packit Service 310c69
 *
Packit Service 310c69
 * @param config            The configuration to use.
Packit Service 310c69
 * @param layout            The index layout
Packit Service 310c69
 * @param userParams        The index session parameters.  If NULL, the default
Packit Service 310c69
 *                          session parameters will be used.
Packit Service 310c69
 * @param readQueueMaxSize  The maximum size of the read queue.
Packit Service 310c69
 * @param zoneCount         The number of zones to use.
Packit Service 310c69
 * @param newVolume         A pointer to hold a pointer to the new volume.
Packit Service 310c69
 *
Packit Service 310c69
 * @return          UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int makeVolume(const Configuration          *config,
Packit Service 310c69
               IndexLayout                  *layout,
Packit Service 310c69
               const struct uds_parameters  *userParams,
Packit Service 310c69
               unsigned int                  readQueueMaxSize,
Packit Service 310c69
               unsigned int                  zoneCount,
Packit Service 310c69
               Volume                      **newVolume)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Clean up a volume and its memory.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume  The volume to destroy.
Packit Service 310c69
 **/
Packit Service 310c69
void freeVolume(Volume *volume);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Enqueue a page read.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume       the volume
Packit Service 310c69
 * @param request      the request to waiting on the read
Packit Service 310c69
 * @param physicalPage the page number to read
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_QUEUED if successful, or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int enqueuePageRead(Volume *volume, Request *request, int physicalPage)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Find the lowest and highest contiguous chapters and determine their
Packit Service 310c69
 * virtual chapter numbers.
Packit Service 310c69
 *
Packit Service 310c69
 * @param [in]  volume      The volume to probe.
Packit Service 310c69
 * @param [out] lowestVCN   Pointer for lowest virtual chapter number.
Packit Service 310c69
 * @param [out] highestVCN  Pointer for highest virtual chapter number.
Packit Service 310c69
 * @param [out] isEmpty     Pointer to a bool indicating whether or not the
Packit Service 310c69
 *                          volume is empty.
Packit Service 310c69
 *
Packit Service 310c69
 * @return              UDS_SUCCESS, or an error code.
Packit Service 310c69
 *
Packit Service 310c69
 * @note        This routine does something similar to a binary search to find
Packit Service 310c69
 *              the location in the volume file where the discontinuity of
Packit Service 310c69
 *              chapter numbers occurs.  In a good save, the discontinuity is
Packit Service 310c69
 *              a sharp cliff, but if write failures occured during saving
Packit Service 310c69
 *              there may be one or more chapters which are partially written.
Packit Service 310c69
 *
Packit Service 310c69
 * @note        This method takes advantage of the fact that the physical
Packit Service 310c69
 *              chapter number in which the index pages are found should have
Packit Service 310c69
 *              headers which state that the virtual chapter number are all
Packit Service 310c69
 *              identical and maintain the invariant that
Packit Service 310c69
 *              pcn == vcn % chaptersPerVolume.
Packit Service 310c69
 **/
Packit Service 310c69
int findVolumeChapterBoundaries(Volume   *volume,
Packit Service 310c69
                                uint64_t *lowestVCN,
Packit Service 310c69
                                uint64_t *highestVCN,
Packit Service 310c69
                                bool     *isEmpty)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Find any matching metadata for the given name within a given physical
Packit Service 310c69
 * chapter.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume          The volume.
Packit Service 310c69
 * @param request         The request originating the search.
Packit Service 310c69
 * @param name            The block name of interest.
Packit Service 310c69
 * @param virtualChapter  The number of the chapter to search.
Packit Service 310c69
 * @param metadata        The old metadata for the name.
Packit Service 310c69
 * @param found           A pointer which will be set to
Packit Service 310c69
 *                        true if a match was found.
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error
Packit Service 310c69
 **/
Packit Service 310c69
int searchVolumePageCache(Volume             *volume,
Packit Service 310c69
                          Request            *request,
Packit Service 310c69
                          const UdsChunkName *name,
Packit Service 310c69
                          uint64_t            virtualChapter,
Packit Service 310c69
                          UdsChunkData       *metadata,
Packit Service 310c69
                          bool               *found)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Fetch a record page from the cache or read it from the volume and search it
Packit Service 310c69
 * for a chunk name.
Packit Service 310c69
 *
Packit Service 310c69
 * If a match is found, optionally returns the metadata from the stored
Packit Service 310c69
 * record. If the requested record page is not cached, the page fetch may be
Packit Service 310c69
 * asynchronously completed on the slow lane, in which case UDS_QUEUED will be
Packit Service 310c69
 * returned and the request will be requeued for continued processing after
Packit Service 310c69
 * the page is read and added to the cache.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume           the volume containing the record page to search
Packit Service 310c69
 * @param request          the request originating the search (may be NULL for
Packit Service 310c69
 *                         a direct query from volume replay)
Packit Service 310c69
 * @param name             the name of the block or chunk
Packit Service 310c69
 * @param chapter          the chapter to search
Packit Service 310c69
 * @param recordPageNumber the record page number of the page to search
Packit Service 310c69
 * @param duplicate        an array in which to place the metadata of the
Packit Service 310c69
 *                         duplicate, if one was found
Packit Service 310c69
 * @param found            a (bool *) which will be set to true if the chunk
Packit Service 310c69
 *                         was found
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS, UDS_QUEUED, or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int searchCachedRecordPage(Volume             *volume,
Packit Service 310c69
                           Request            *request,
Packit Service 310c69
                           const UdsChunkName *name,
Packit Service 310c69
                           unsigned int        chapter,
Packit Service 310c69
                           int                 recordPageNumber,
Packit Service 310c69
                           UdsChunkData       *duplicate,
Packit Service 310c69
                           bool               *found)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Forget the contents of a chapter. Invalidates any cached state for the
Packit Service 310c69
 * specified chapter.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume   the volume containing the chapter
Packit Service 310c69
 * @param chapter  the virtual chapter number
Packit Service 310c69
 * @param reason   the reason for invalidation
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int forgetChapter(Volume             *volume,
Packit Service 310c69
                  uint64_t            chapter,
Packit Service 310c69
                  InvalidationReason  reason)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Write a chapter's worth of index pages to a volume
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume        the volume containing the chapter
Packit Service 310c69
 * @param physicalPage  the page number in the volume for the chapter
Packit Service 310c69
 * @param chapterIndex  the populated delta chapter index
Packit Service 310c69
 * @param pages         pointer to array of page pointers. Used only in testing
Packit Service 310c69
 *                      to return what data has been written to disk.
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int writeIndexPages(Volume            *volume,
Packit Service 310c69
                    int                physicalPage,
Packit Service 310c69
                    OpenChapterIndex  *chapterIndex,
Packit Service 310c69
                    byte             **pages)
Packit Service 310c69
__attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Write a chapter's worth of record pages to a volume
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume        the volume containing the chapter
Packit Service 310c69
 * @param physicalPage  the page number in the volume for the chapter
Packit Service 310c69
 * @param records       a 1-based array of chunk records in the chapter
Packit Service 310c69
 * @param pages         pointer to array of page pointers. Used only in testing
Packit Service 310c69
 *                      to return what data has been written to disk.
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int writeRecordPages(Volume                *volume,
Packit Service 310c69
                     int                    physicalPage,
Packit Service 310c69
                     const UdsChunkRecord   records[],
Packit Service 310c69
                     byte                 **pages)
Packit Service 310c69
__attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Write the index and records from the most recently filled chapter to the
Packit Service 310c69
 * volume.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume                the volume containing the chapter
Packit Service 310c69
 * @param chapterIndex          the populated delta chapter index
Packit Service 310c69
 * @param records               a 1-based array of chunk records in the chapter
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int writeChapter(Volume               *volume,
Packit Service 310c69
                 OpenChapterIndex     *chapterIndex,
Packit Service 310c69
                 const UdsChunkRecord  records[])
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Read all the index pages for a chapter from the volume and initialize an
Packit Service 310c69
 * array of ChapterIndexPages to represent them.
Packit Service 310c69
 *
Packit Service 310c69
 * @param [in]  volume          the volume containing the chapter
Packit Service 310c69
 * @param [in]  virtualChapter  the virtual chapter number of the index to read
Packit Service 310c69
 * @param [out] volumePages     an array to receive the raw index page data
Packit Service 310c69
 * @param [out] indexPages      an array of ChapterIndexPages to initialize
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int readChapterIndexFromVolume(const Volume       *volume,
Packit Service 310c69
                               uint64_t            virtualChapter,
Packit Service 310c69
                               struct volume_page  volumePages[],
Packit Service 310c69
                               DeltaIndexPage      indexPages[])
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Retrieve a page either from the cache (if we can) or from disk. If a read
Packit Service 310c69
 * from disk is required, this is done immediately in the same thread and the
Packit Service 310c69
 * page is then returned.
Packit Service 310c69
 *
Packit Service 310c69
 * The caller of this function must be holding the volume read mutex before
Packit Service 310c69
 * calling this function.
Packit Service 310c69
 *
Packit Service 310c69
 * As a side-effect, the retrieved page will become the most recent page in
Packit Service 310c69
 * the cache.
Packit Service 310c69
 *
Packit Service 310c69
 * This function is only exposed for the use of unit tests.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume       The volume containing the page
Packit Service 310c69
 * @param request      The request originating the search
Packit Service 310c69
 * @param physicalPage The physical page number
Packit Service 310c69
 * @param probeType    The type of cache access being done
Packit Service 310c69
 * @param entryPtr     A pointer to hold the retrieved cached entry
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int getPageLocked(Volume          *volume,
Packit Service 310c69
                  Request         *request,
Packit Service 310c69
                  unsigned int     physicalPage,
Packit Service 310c69
                  CacheProbeType   probeType,
Packit Service 310c69
                  CachedPage     **entryPtr)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Retrieve a page either from the cache (if we can) or from disk. If a read
Packit Service 310c69
 * from disk is required, the read request is enqueued for later processing
Packit Service 310c69
 * by another thread. When that thread finally reads the page into the cache,
Packit Service 310c69
 * a callback function is called to inform the caller the read is complete.
Packit Service 310c69
 *
Packit Service 310c69
 * The caller of this function should not be holding the volume read lock.
Packit Service 310c69
 * Instead, the caller must call beingPendingSearch() for the given zone
Packit Service 310c69
 * the request is being processed in. That state will be maintained or
Packit Service 310c69
 * restored when the call returns, at which point the caller should call
Packit Service 310c69
 * endPendingSearch().
Packit Service 310c69
 *
Packit Service 310c69
 * As a side-effect, the retrieved page will become the most recent page in
Packit Service 310c69
 * the cache.
Packit Service 310c69
 *
Packit Service 310c69
 * This function is only exposed for the use of unit tests.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume       The volume containing the page
Packit Service 310c69
 * @param request      The request originating the search
Packit Service 310c69
 * @param physicalPage The physical page number
Packit Service 310c69
 * @param probeType    The type of cache access being done
Packit Service 310c69
 * @param entryPtr     A pointer to hold the retrieved cached entry
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int getPageProtected(Volume          *volume,
Packit Service 310c69
                     Request         *request,
Packit Service 310c69
                     unsigned int     physicalPage,
Packit Service 310c69
                     CacheProbeType   probeType,
Packit Service 310c69
                     CachedPage     **entryPtr)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Retrieve a page either from the cache (if we can) or from disk. If a read
Packit Service 310c69
 * from disk is required, this is done immediately in the same thread and the
Packit Service 310c69
 * page is then returned.
Packit Service 310c69
 *
Packit Service 310c69
 * The caller of this function must not be holding the volume read lock before
Packit Service 310c69
 * calling this function. This method will grab that lock and release it
Packit Service 310c69
 * when it returns.
Packit Service 310c69
 *
Packit Service 310c69
 * As a side-effect, the retrieved page will become the most recent page in
Packit Service 310c69
 * the cache.
Packit Service 310c69
 *
Packit Service 310c69
 * This function should only be called by areas of the code that do not use
Packit Service 310c69
 * multi-threading to access the volume. These include rebuild, volume
Packit Service 310c69
 * explorer, and certain unit tests.
Packit Service 310c69
 *
Packit Service 310c69
 * @param volume        The volume containing the page
Packit Service 310c69
 * @param chapter       The number of the chapter containing the page
Packit Service 310c69
 * @param pageNumber    The number of the page
Packit Service 310c69
 * @param probeType     The type of cache access being done
Packit Service 310c69
 * @param dataPtr       Pointer to hold the retrieved page, NULL if not wanted
Packit Service 310c69
 * @param indexPagePtr  Pointer to hold the retrieved chapter index page, or
Packit Service 310c69
 *                      NULL if not wanted
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int getPage(Volume          *volume,
Packit Service 310c69
            unsigned int     chapter,
Packit Service 310c69
            unsigned int     pageNumber,
Packit Service 310c69
            CacheProbeType   probeType,
Packit Service 310c69
            byte           **dataPtr,
Packit Service 310c69
            DeltaIndexPage **indexPagePtr)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
size_t getCacheSize(Volume *volume) __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int findVolumeChapterBoundariesImpl(unsigned int  chapterLimit,
Packit Service 310c69
                                    unsigned int  maxBadChapters,
Packit Service 310c69
                                    uint64_t     *lowestVCN,
Packit Service 310c69
                                    uint64_t     *highestVCN,
Packit Service 310c69
                                    int (*probeFunc)(void         *aux,
Packit Service 310c69
                                                     unsigned int  chapter,
Packit Service 310c69
                                                     uint64_t     *vcn),
Packit Service 310c69
                                    void *aux)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Map a chapter number and page number to a phsical volume page number.
Packit Service 310c69
 *
Packit Service 310c69
 * @param geometry the layout of the volume
Packit Service 310c69
 * @param chapter  the chapter number of the desired page
Packit Service 310c69
 * @param page     the chapter page number of the desired page
Packit Service 310c69
 *
Packit Service 310c69
 * @return the physical page number
Packit Service 310c69
 **/
Packit Service 310c69
int mapToPhysicalPage(const Geometry *geometry, int chapter, int page)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
#endif /* VOLUME_H */