162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2012 Red Hat, Inc. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This file is released under the GPL. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef DM_CACHE_METADATA_H 962306a36Sopenharmony_ci#define DM_CACHE_METADATA_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "dm-cache-block-types.h" 1262306a36Sopenharmony_ci#include "dm-cache-policy-internal.h" 1362306a36Sopenharmony_ci#include "persistent-data/dm-space-map-metadata.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/*----------------------------------------------------------------*/ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define DM_CACHE_METADATA_BLOCK_SIZE DM_SM_METADATA_BLOCK_SIZE 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* FIXME: remove this restriction */ 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * The metadata device is currently limited in size. 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define DM_CACHE_METADATA_MAX_SECTORS DM_SM_METADATA_MAX_SECTORS 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* 2662306a36Sopenharmony_ci * A metadata device larger than 16GB triggers a warning. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci#define DM_CACHE_METADATA_MAX_SECTORS_WARNING (16 * (1024 * 1024 * 1024 >> SECTOR_SHIFT)) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/*----------------------------------------------------------------*/ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * Ext[234]-style compat feature flags. 3462306a36Sopenharmony_ci * 3562306a36Sopenharmony_ci * A new feature which old metadata will still be compatible with should 3662306a36Sopenharmony_ci * define a DM_CACHE_FEATURE_COMPAT_* flag (rarely useful). 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * A new feature that is not compatible with old code should define a 3962306a36Sopenharmony_ci * DM_CACHE_FEATURE_INCOMPAT_* flag and guard the relevant code with 4062306a36Sopenharmony_ci * that flag. 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * A new feature that is not compatible with old code accessing the 4362306a36Sopenharmony_ci * metadata RDWR should define a DM_CACHE_FEATURE_RO_COMPAT_* flag and 4462306a36Sopenharmony_ci * guard the relevant code with that flag. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * As these various flags are defined they should be added to the 4762306a36Sopenharmony_ci * following masks. 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define DM_CACHE_FEATURE_COMPAT_SUPP 0UL 5162306a36Sopenharmony_ci#define DM_CACHE_FEATURE_COMPAT_RO_SUPP 0UL 5262306a36Sopenharmony_ci#define DM_CACHE_FEATURE_INCOMPAT_SUPP 0UL 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistruct dm_cache_metadata; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* 5762306a36Sopenharmony_ci * Reopens or creates a new, empty metadata volume. Returns an ERR_PTR on 5862306a36Sopenharmony_ci * failure. If reopening then features must match. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_cistruct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, 6162306a36Sopenharmony_ci sector_t data_block_size, 6262306a36Sopenharmony_ci bool may_format_device, 6362306a36Sopenharmony_ci size_t policy_hint_size, 6462306a36Sopenharmony_ci unsigned int metadata_version); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_civoid dm_cache_metadata_close(struct dm_cache_metadata *cmd); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* 6962306a36Sopenharmony_ci * The metadata needs to know how many cache blocks there are. We don't 7062306a36Sopenharmony_ci * care about the origin, assuming the core target is giving us valid 7162306a36Sopenharmony_ci * origin blocks to map to. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ciint dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size); 7462306a36Sopenharmony_ciint dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ciint dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd, 7762306a36Sopenharmony_ci sector_t discard_block_size, 7862306a36Sopenharmony_ci dm_dblock_t new_nr_entries); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_citypedef int (*load_discard_fn)(void *context, sector_t discard_block_size, 8162306a36Sopenharmony_ci dm_dblock_t dblock, bool discarded); 8262306a36Sopenharmony_ciint dm_cache_load_discards(struct dm_cache_metadata *cmd, 8362306a36Sopenharmony_ci load_discard_fn fn, void *context); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciint dm_cache_set_discard(struct dm_cache_metadata *cmd, dm_dblock_t dblock, bool discard); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ciint dm_cache_remove_mapping(struct dm_cache_metadata *cmd, dm_cblock_t cblock); 8862306a36Sopenharmony_ciint dm_cache_insert_mapping(struct dm_cache_metadata *cmd, dm_cblock_t cblock, dm_oblock_t oblock); 8962306a36Sopenharmony_ciint dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_citypedef int (*load_mapping_fn)(void *context, dm_oblock_t oblock, 9262306a36Sopenharmony_ci dm_cblock_t cblock, bool dirty, 9362306a36Sopenharmony_ci uint32_t hint, bool hint_valid); 9462306a36Sopenharmony_ciint dm_cache_load_mappings(struct dm_cache_metadata *cmd, 9562306a36Sopenharmony_ci struct dm_cache_policy *policy, 9662306a36Sopenharmony_ci load_mapping_fn fn, 9762306a36Sopenharmony_ci void *context); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ciint dm_cache_set_dirty_bits(struct dm_cache_metadata *cmd, 10062306a36Sopenharmony_ci unsigned int nr_bits, unsigned long *bits); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistruct dm_cache_statistics { 10362306a36Sopenharmony_ci uint32_t read_hits; 10462306a36Sopenharmony_ci uint32_t read_misses; 10562306a36Sopenharmony_ci uint32_t write_hits; 10662306a36Sopenharmony_ci uint32_t write_misses; 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_civoid dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd, 11062306a36Sopenharmony_ci struct dm_cache_statistics *stats); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/* 11362306a36Sopenharmony_ci * 'void' because it's no big deal if it fails. 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_civoid dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd, 11662306a36Sopenharmony_ci struct dm_cache_statistics *stats); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciint dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd, 12162306a36Sopenharmony_ci dm_block_t *result); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ciint dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd, 12462306a36Sopenharmony_ci dm_block_t *result); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_civoid dm_cache_dump(struct dm_cache_metadata *cmd); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/* 12962306a36Sopenharmony_ci * The policy is invited to save a 32bit hint value for every cblock (eg, 13062306a36Sopenharmony_ci * for a hit count). These are stored against the policy name. If 13162306a36Sopenharmony_ci * policies are changed, then hints will be lost. If the machine crashes, 13262306a36Sopenharmony_ci * hints will be lost. 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * The hints are indexed by the cblock, but many policies will not 13562306a36Sopenharmony_ci * necessarily have a fast way of accessing efficiently via cblock. So 13662306a36Sopenharmony_ci * rather than querying the policy for each cblock, we let it walk its data 13762306a36Sopenharmony_ci * structures and fill in the hints in whatever order it wishes. 13862306a36Sopenharmony_ci */ 13962306a36Sopenharmony_ciint dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *p); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* 14262306a36Sopenharmony_ci * Query method. Are all the blocks in the cache clean? 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ciint dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ciint dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result); 14762306a36Sopenharmony_ciint dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd); 14862306a36Sopenharmony_civoid dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd); 14962306a36Sopenharmony_civoid dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd); 15062306a36Sopenharmony_ciint dm_cache_metadata_abort(struct dm_cache_metadata *cmd); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci/*----------------------------------------------------------------*/ 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#endif /* DM_CACHE_METADATA_H */ 155