/* * Copyright(c) 2012-2018 Intel Corporation * SPDX-License-Identifier: BSD-3-Clause-Clear */ /******************************************************************************* * Sector mask getter ******************************************************************************/ static inline uint64_t _get_mask(uint8_t start, uint8_t stop) { uint64_t mask = 0; ENV_BUG_ON(start >= 64); ENV_BUG_ON(stop >= 64); ENV_BUG_ON(stop < start); mask = ~mask; mask >>= start + (63 - stop); mask <<= start; return mask; } #define _get_mask_u8(start, stop) _get_mask(start, stop) #define _get_mask_u16(start, stop) _get_mask(start, stop) #define _get_mask_u32(start, stop) _get_mask(start, stop) #define _get_mask_u64(start, stop) _get_mask(start, stop) typedef __uint128_t u128; static inline u128 _get_mask_u128(uint8_t start, uint8_t stop) { u128 mask = 0; ENV_BUG_ON(start >= 128); ENV_BUG_ON(stop >= 128); ENV_BUG_ON(stop < start); mask = ~mask; mask >>= start + (127 - stop); mask <<= start; return mask; } #define ocf_metadata_bit_struct(type) \ struct ocf_metadata_map_##type { \ struct ocf_metadata_map map; \ type valid; \ type dirty; \ } __attribute__((packed)) #define ocf_metadata_bit_func(what, type) \ static bool _ocf_metadata_test_##what##_##type(struct ocf_cache *cache, \ ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all) \ { \ type mask = _get_mask_##type(start, stop); \ \ struct ocf_metadata_hash_ctrl *ctrl = \ (struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ \ struct ocf_metadata_raw *raw = \ &ctrl->raw_desc[metadata_segment_collision]; \ \ const struct ocf_metadata_map_##type *map = raw->mem_pool; \ \ _raw_bug_on(raw, line, sizeof(*map)); \ \ if (all) { \ if (mask == (map[line].what & mask)) { \ return true; \ } else { \ return false; \ } \ } else { \ if (map[line].what & mask) { \ return true; \ } else { \ return false; \ } \ } \ } \ \ static bool _ocf_metadata_test_out_##what##_##type(struct ocf_cache *cache, \ ocf_cache_line_t line, uint8_t start, uint8_t stop) \ { \ type mask = _get_mask_##type(start, stop); \ \ struct ocf_metadata_hash_ctrl *ctrl = \ (struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ \ struct ocf_metadata_raw *raw = \ &ctrl->raw_desc[metadata_segment_collision]; \ \ const struct ocf_metadata_map_##type *map = raw->mem_pool; \ \ _raw_bug_on(raw, line, sizeof(*map)); \ \ if (map[line].what & ~mask) { \ return true; \ } else { \ return false; \ } \ } \ \ static bool _ocf_metadata_clear_##what##_##type(struct ocf_cache *cache, \ ocf_cache_line_t line, uint8_t start, uint8_t stop) \ { \ type mask = _get_mask_##type(start, stop); \ \ struct ocf_metadata_hash_ctrl *ctrl = \ (struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ \ struct ocf_metadata_raw *raw = \ &ctrl->raw_desc[metadata_segment_collision]; \ \ struct ocf_metadata_map_##type *map = raw->mem_pool; \ \ _raw_bug_on(raw, line, sizeof(*map)); \ \ map[line].what &= ~mask; \ \ if (map[line].what) { \ return true; \ } else { \ return false; \ } \ } \ \ static bool _ocf_metadata_set_##what##_##type(struct ocf_cache *cache, \ ocf_cache_line_t line, uint8_t start, uint8_t stop) \ { \ bool result; \ type mask = _get_mask_##type(start, stop); \ \ struct ocf_metadata_hash_ctrl *ctrl = \ (struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ \ struct ocf_metadata_raw *raw = \ &ctrl->raw_desc[metadata_segment_collision]; \ \ struct ocf_metadata_map_##type *map = raw->mem_pool; \ \ _raw_bug_on(raw, line, sizeof(*map)); \ \ result = map[line].what ? true : false; \ \ map[line].what |= mask; \ \ return result; \ } \ \ static bool _ocf_metadata_test_and_set_##what##_##type( \ struct ocf_cache *cache, ocf_cache_line_t line, \ uint8_t start, uint8_t stop, bool all) \ { \ bool test; \ type mask = _get_mask_##type(start, stop); \ \ struct ocf_metadata_hash_ctrl *ctrl = \ (struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ \ struct ocf_metadata_raw *raw = \ &ctrl->raw_desc[metadata_segment_collision]; \ \ struct ocf_metadata_map_##type *map = raw->mem_pool; \ \ _raw_bug_on(raw, line, sizeof(*map)); \ \ if (all) { \ if (mask == (map[line].what & mask)) { \ test = true; \ } else { \ test = false; \ } \ } else { \ if (map[line].what & mask) { \ test = true; \ } else { \ test = false; \ } \ } \ \ map[line].what |= mask; \ return test; \ } \ \ static bool _ocf_metadata_test_and_clear_##what##_##type( \ struct ocf_cache *cache, ocf_cache_line_t line, \ uint8_t start, uint8_t stop, bool all) \ { \ bool test; \ type mask = _get_mask_##type(start, stop); \ \ struct ocf_metadata_hash_ctrl *ctrl = \ (struct ocf_metadata_hash_ctrl *) cache->metadata.iface_priv; \ \ struct ocf_metadata_raw *raw = \ &ctrl->raw_desc[metadata_segment_collision]; \ \ struct ocf_metadata_map_##type *map = raw->mem_pool; \ \ _raw_bug_on(raw, line, sizeof(*map)); \ \ if (all) { \ if (mask == (map[line].what & mask)) { \ test = true; \ } else { \ test = false; \ } \ } else { \ if (map[line].what & mask) { \ test = true; \ } else { \ test = false; \ } \ } \ \ map[line].what &= ~mask; \ return test; \ } \ ocf_metadata_bit_struct(u8); ocf_metadata_bit_struct(u16); ocf_metadata_bit_struct(u32); ocf_metadata_bit_struct(u64); ocf_metadata_bit_struct(u128); ocf_metadata_bit_func(dirty, u8); ocf_metadata_bit_func(dirty, u16); ocf_metadata_bit_func(dirty, u32); ocf_metadata_bit_func(dirty, u64); ocf_metadata_bit_func(dirty, u128); ocf_metadata_bit_func(valid, u8); ocf_metadata_bit_func(valid, u16); ocf_metadata_bit_func(valid, u32); ocf_metadata_bit_func(valid, u64); ocf_metadata_bit_func(valid, u128);