/* * Copyright (C) 2012 Red Hat, Inc. * * This file is released under the GPL. */#include"dm-cache-metadata.h"#include"persistent-data/dm-array.h"#include"persistent-data/dm-bitset.h"#include"persistent-data/dm-space-map.h"#include"persistent-data/dm-space-map-disk.h"#include"persistent-data/dm-transaction-manager.h"#include <linux/device-mapper.h>/*----------------------------------------------------------------*/#define DM_MSG_PREFIX"cache metadata"#define CACHE_SUPERBLOCK_MAGIC 06142003#define CACHE_SUPERBLOCK_LOCATION 0/* * defines a range of metadata versions that this module can handle. */#define MIN_CACHE_VERSION 1#define MAX_CACHE_VERSION 1#define CACHE_METADATA_CACHE_SIZE 64/* * 3 for btree insert + * 2 for btree lookup used within space map */#define CACHE_MAX_CONCURRENT_LOCKS 5#define SPACE_MAP_ROOT_SIZE 128enum superblock_flag_bits {/* for spotting crashes that would invalidate the dirty bitset */
CLEAN_SHUTDOWN,};/* * Each mapping from cache block -> origin block carries a set of flags. */enum mapping_bits {/* * A valid mapping. Because we're using an array we clear this * flag for an non existant mapping. */
M_VALID =1,/* * The data on the cache is different from that on the origin. */
M_DIRTY =2};struct cache_disk_superblock {
__le32 csum;
__le32 flags;
__le64 blocknr;
__u8 uuid[16];
__le64 magic;
__le32 version;
__u8 policy_name[CACHE_POLICY_NAME_SIZE];
__le32 policy_hint_size;
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
__le64 mapping_root;
__le64 hint_root;
__le64 discard_root;
__le64 discard_block_size;
__le64 discard_nr_blocks;
__le32 data_block_size;
__le32 metadata_block_size;
__le32 cache_blocks;
__le32 compat_flags;
__le32 compat_ro_flags;
__le32 incompat_flags;
__le32 read_hits;
__le32 read_misses;
__le32 write_hits;
__le32 write_misses;
__le32 policy_version[CACHE_POLICY_VERSION_SIZE];} __packed;struct dm_cache_metadata {
atomic_t ref_count;struct list_head list;struct block_device *bdev;struct dm_block_manager *bm;struct dm_space_map *metadata_sm;struct dm_transaction_manager *tm;struct dm_array_info info;struct dm_array_info hint_info;struct dm_disk_bitset discard_info;struct rw_semaphore root_lock;
dm_block_t root;
dm_block_t hint_root;
dm_block_t discard_root;
sector_t discard_block_size;
dm_dblock_t discard_nr_blocks;
sector_t data_block_size;
dm_cblock_t cache_blocks;bool changed:1;bool clean_when_opened:1;char policy_name[CACHE_POLICY_NAME_SIZE];unsigned policy_version[CACHE_POLICY_VERSION_SIZE];size_t policy_hint_size;struct dm_cache_statistics stats;/* * Reading the space map root can fail, so we read it into this * buffer before the superblock is locked and updated. */
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];};/*-------------------------------------------------------------------