diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index 1d3f44e..d1c0397 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -1540,6 +1540,32 @@ bool ocf_metadata_##what(struct ocf_cache *cache, \ _ocf_metadata_funcs(dirty) _ocf_metadata_funcs(valid) +bool ocf_metadata_clear_valid_if_clean(struct ocf_cache *cache, + ocf_cache_line_t line, uint8_t start, uint8_t stop) +{ + switch (cache->metadata.line_size) { + case ocf_cache_line_size_4: + return _ocf_metadata_clear_valid_if_clean_u8(cache, + line, start, stop); + case ocf_cache_line_size_8: + return _ocf_metadata_clear_valid_if_clean_u16(cache, + line, start, stop); + case ocf_cache_line_size_16: + return _ocf_metadata_clear_valid_if_clean_u32(cache, + line, start, stop); + case ocf_cache_line_size_32: + return _ocf_metadata_clear_valid_if_clean_u64(cache, + line, start, stop); + case ocf_cache_line_size_64: + return _ocf_metadata_clear_valid_if_clean_u128(cache, + line, start, stop); + case ocf_cache_line_size_none: + default: + ENV_BUG_ON(1); + return false; + } +} + int ocf_metadata_init(struct ocf_cache *cache, ocf_cache_line_size_t cache_line_size) { diff --git a/src/metadata/metadata_bit.h b/src/metadata/metadata_bit.h index d825726..2a2a586 100644 --- a/src/metadata/metadata_bit.h +++ b/src/metadata/metadata_bit.h @@ -221,10 +221,36 @@ static bool _ocf_metadata_test_and_clear_##what##_##type( \ return test; \ } \ +#define ocf_metadata_bit_func_basic(type) \ +static bool _ocf_metadata_clear_valid_if_clean_##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_ctrl *ctrl = \ + (struct ocf_metadata_ctrl *) cache->metadata.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); \ +\ + map[line].valid &= ~mask & map[line].dirty; \ +\ + if (map[line].valid) { \ + return true; \ + } else { \ + return false; \ + } \ +} \ + #define ocf_metadata_bit_funcs(type) \ ocf_metadata_bit_struct(type); \ ocf_metadata_bit_func(dirty, type); \ ocf_metadata_bit_func(valid, type); \ +ocf_metadata_bit_func_basic(type); \ ocf_metadata_bit_funcs(u8); ocf_metadata_bit_funcs(u16); diff --git a/src/metadata/metadata_status.h b/src/metadata/metadata_status.h index bacf980..be34eb3 100644 --- a/src/metadata/metadata_status.h +++ b/src/metadata/metadata_status.h @@ -26,6 +26,8 @@ bool ocf_metadata_clear_valid(struct ocf_cache *cache, ocf_cache_line_t line, ui bool ocf_metadata_set_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop); bool ocf_metadata_test_and_set_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all); bool ocf_metadata_test_and_clear_valid(struct ocf_cache *cache, ocf_cache_line_t line, uint8_t start, uint8_t stop, bool all); +bool ocf_metadata_clear_valid_if_clean(struct ocf_cache *cache, + ocf_cache_line_t line, uint8_t start, uint8_t stop); static inline void metadata_init_status_bits(struct ocf_cache *cache, ocf_cache_line_t line) @@ -214,6 +216,13 @@ static inline void metadata_clear_valid(struct ocf_cache *cache, ocf_metadata_clear_valid(cache, line, 0, ocf_line_end_sector(cache)); } +static inline void metadata_clear_valid_if_clean(struct ocf_cache *cache, + ocf_cache_line_t line) +{ + ocf_metadata_clear_valid_if_clean(cache, line, 0, + ocf_line_end_sector(cache)); +} + static inline bool metadata_test_and_clear_valid( struct ocf_cache *cache, ocf_cache_line_t line) {