/* * Copyright (c) 2020 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/slabSummary.h#5 $ */ #ifndef SLAB_SUMMARY_H #define SLAB_SUMMARY_H #include "completion.h" #include "fixedLayout.h" #include "slab.h" #include "statistics.h" #include "types.h" #include "waitQueue.h" /** * The SlabSummary provides hints during load and recovery about the state * of the slabs in order to avoid the need to read the slab journals in their * entirety before a VDO can come online. * * The information in the summary for each slab includes the rough number of * free blocks (which is used to prioritize scrubbing), the cleanliness of a * slab (so that clean slabs containing free space will be used on restart), * and the location of the tail block of the slab's journal. * * The SlabSummary has its own partition at the end of the volume which is * sized to allow for a complete copy of the summary for each of up to 16 * physical zones. * * During resize, the SlabSummary moves its backing partition and is saved once * moved; the SlabSummary is not permitted to overwrite the previous recovery * journal space. * * The SlabSummary does not have its own version information, but relies on the * master version number. **/ /** * The offset of a slab journal tail block. **/ typedef uint8_t TailBlockOffset; /** * A slab status is a very small structure for use in determining the ordering * of slabs in the scrubbing process. **/ typedef struct slabStatus { SlabCount slabNumber; bool isClean; uint8_t emptiness; } SlabStatus; /** * Returns the size on disk of the SlabSummary structure. * * @param blockSize The block size of the physical layer * * @return the blocks required to store the SlabSummary on disk **/ BlockCount getSlabSummarySize(BlockSize blockSize) __attribute__((warn_unused_result)); /** * Create a slab summary. * * @param [in] layer The layer * @param [in] partition The partition to hold the summary * @param [in] threadConfig The thread config of the VDO * @param [in] slabSizeShift The number of bits in the slab size * @param [in] maximumFreeBlocksPerSlab The maximum number of free blocks a * slab can have * @param [in] readOnlyNotifier The context for entering read-only * mode * @param [out] slabSummaryPtr A pointer to hold the summary * * @return VDO_SUCCESS or an error **/ int makeSlabSummary(PhysicalLayer *layer, Partition *partition, const ThreadConfig *threadConfig, unsigned int slabSizeShift, BlockCount maximumFreeBlocksPerSlab, ReadOnlyNotifier *readOnlyNotifier, SlabSummary **slabSummaryPtr) __attribute__((warn_unused_result)); /** * Destroy a SlabSummary and NULL out the reference to it. * * @param [in,out] slabSummaryPtr A pointer to the SlabSummary to free **/ void freeSlabSummary(SlabSummary **slabSummaryPtr); /** * Get the portion of the slab summary for a specified zone. * * @param summary The slab summary * @param zone The zone * * @return The portion of the slab summary for the specified zone **/ SlabSummaryZone *getSummaryForZone(SlabSummary *summary, ZoneCount zone) __attribute__((warn_unused_result)); /** * Drain a zone of the slab summary. * * @param summaryZone The zone to drain * @param operation The type of drain to perform * @param parent The object to notify when the suspend is complete **/ void drainSlabSummaryZone(SlabSummaryZone *summaryZone, AdminStateCode operation, VDOCompletion *parent); /** * Resume a zone of the slab summary. * * @param summaryZone The zone to resume * @param parent The object to notify when the zone is resumed **/ void resumeSlabSummaryZone(SlabSummaryZone *summaryZone, VDOCompletion *parent); /** * Update the entry for a slab. * * @param summaryZone The SlabSummaryZone for the zone of the slab * @param waiter The waiter that is updating the summary * @param slabNumber The slab number to update * @param tailBlockOffset The offset of slab journal's tail block * @param loadRefCounts Whether the refCounts must be loaded from the layer * on the next load * @param isClean Whether the slab is clean * @param freeBlocks The number of free blocks **/ void updateSlabSummaryEntry(SlabSummaryZone *summaryZone, Waiter *waiter, SlabCount slabNumber, TailBlockOffset tailBlockOffset, bool loadRefCounts, bool isClean, BlockCount freeBlocks); /** * Get the stored tail block offset for a slab. * * @param summaryZone The SlabSummaryZone to use * @param slabNumber The slab number to get the offset for * * @return The tail block offset for the slab **/ TailBlockOffset getSummarizedTailBlockOffset(SlabSummaryZone *summaryZone, SlabCount slabNumber) __attribute__((warn_unused_result)); /** * Whether refCounts must be loaded from the layer. * * @param summaryZone The SlabSummaryZone to use * @param slabNumber The slab number to get information for * * @return Whether refCounts must be loaded **/ bool mustLoadRefCounts(SlabSummaryZone *summaryZone, SlabCount slabNumber) __attribute__((warn_unused_result)); /** * Get the stored cleanliness information for a single slab. * * @param summaryZone The SlabSummaryZone to use * @param slabNumber The slab number to get information for * * @return Whether the slab is clean **/ bool getSummarizedCleanliness(SlabSummaryZone *summaryZone, SlabCount slabNumber) __attribute__((warn_unused_result)); /** * Get the stored emptiness information for a single slab. * * @param summaryZone The SlabSummaryZone to use * @param slabNumber The slab number to get information for * * @return An approximation to the free blocks in the slab **/ BlockCount getSummarizedFreeBlockCount(SlabSummaryZone *summaryZone, SlabCount slabNumber) __attribute__((warn_unused_result)); /** * Get the stored RefCounts state information for a single slab. Used * in testing only. * * @param [in] summaryZone The SlabSummaryZone to use * @param [in] slabNumber The slab number to get information for * @param [out] freeBlockHint The approximate number of free blocks * @param [out] isClean Whether the slab is clean **/ void getSummarizedRefCountsState(SlabSummaryZone *summaryZone, SlabCount slabNumber, size_t *freeBlockHint, bool *isClean); /** * Get the stored slab statuses for all slabs in a zone. * * @param [in] summaryZone The SlabSummaryZone to use * @param [in] slabCount The number of slabs to fetch * @param [in,out] statuses An array of SlabStatuses to populate **/ void getSummarizedSlabStatuses(SlabSummaryZone *summaryZone, SlabCount slabCount, SlabStatus *statuses); /** * Set the origin of the slab summary relative to the physical layer. * * @param summary The SlabSummary to update * @param partition The slab summary partition **/ void setSlabSummaryOrigin(SlabSummary *summary, Partition *partition); /** * Read in all the slab summary data from the slab summary partition, * combine all the previously used zones into a single zone, and then * write the combined summary back out to each possible zones' summary * region. * * @param summary The summary to load * @param operation The type of load to perform * @param zonesToCombine The number of zones to be combined; if set to 0, * all of the summary will be initialized as new. * @param parent The parent of this operation **/ void loadSlabSummary(SlabSummary *summary, AdminStateCode operation, ZoneCount zonesToCombine, VDOCompletion *parent); /** * Fetch the cumulative statistics for all slab summary zones in a summary. * * @param summary The summary in question * * @return the cumulative slab summary statistics for the summary **/ SlabSummaryStatistics getSlabSummaryStatistics(const SlabSummary *summary) __attribute__((warn_unused_result)); #endif // SLAB_SUMMARY_H