105 lines
2.3 KiB
C
105 lines
2.3 KiB
C
/*
|
|
* Copyright(c) 2012-2018 Intel Corporation
|
|
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
*/
|
|
#include "ocf_priv.h"
|
|
#include "ocf_cache_priv.h"
|
|
#include "utils/utils_cache_line.h"
|
|
|
|
static inline ocf_cache_line_t ocf_atomic_addr2line(
|
|
struct ocf_cache *cache, uint64_t addr)
|
|
{
|
|
addr -= cache->device->metadata_offset;
|
|
addr = ocf_bytes_2_lines(cache, addr);
|
|
return ocf_metadata_map_phy2lg(cache, addr);
|
|
}
|
|
|
|
static inline uint8_t ocf_atomic_addr2pos(struct ocf_cache *cache,
|
|
uint64_t addr)
|
|
{
|
|
addr -= cache->device->metadata_offset;
|
|
addr = BYTES_TO_SECTORS(addr);
|
|
addr %= ocf_line_sectors(cache);
|
|
|
|
return addr;
|
|
}
|
|
|
|
int ocf_metadata_get_atomic_entry(ocf_cache_t cache,
|
|
uint64_t addr, struct ocf_atomic_metadata *entry)
|
|
{
|
|
OCF_CHECK_NULL(cache);
|
|
OCF_CHECK_NULL(entry);
|
|
|
|
if (addr > ocf_volume_get_length(&cache->device->volume))
|
|
return -EFAULT;
|
|
|
|
if (addr < cache->device->metadata_offset) {
|
|
/* Metadata IO of OCF */
|
|
ENV_BUG_ON(env_memset(entry, sizeof(*entry), 0));
|
|
} else {
|
|
ocf_cache_line_t line = ocf_atomic_addr2line(cache, addr);
|
|
uint8_t pos = ocf_atomic_addr2pos(cache, addr);
|
|
ocf_core_id_t core_id = OCF_CORE_MAX;
|
|
ocf_core_t core;
|
|
uint64_t core_line = 0;
|
|
|
|
ocf_metadata_get_core_info(cache, line, &core_id, &core_line);
|
|
core = ocf_cache_get_core(cache, core_id);
|
|
|
|
entry->core_seq_no = core->conf_meta->seq_no;
|
|
entry->core_line = core_line;
|
|
|
|
entry->valid = metadata_test_valid_one(cache, line, pos);
|
|
entry->dirty = metadata_test_dirty_one(cache, line, pos);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ocf_metadata_check_invalid_before(ocf_cache_t cache, uint64_t addr)
|
|
{
|
|
ocf_cache_line_t line;
|
|
uint8_t pos;
|
|
int i;
|
|
|
|
OCF_CHECK_NULL(cache);
|
|
|
|
line = ocf_atomic_addr2line(cache, addr);
|
|
pos = ocf_atomic_addr2pos(cache, addr);
|
|
|
|
if (!pos || addr < cache->device->metadata_offset)
|
|
return 0;
|
|
|
|
for (i = 0; i < pos; i++) {
|
|
if (metadata_test_valid_one(cache, line, i))
|
|
return 0;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
int ocf_metadata_check_invalid_after(ocf_cache_t cache, uint64_t addr,
|
|
uint32_t bytes)
|
|
{
|
|
ocf_cache_line_t line;
|
|
uint8_t pos;
|
|
int i, count = 0;
|
|
|
|
OCF_CHECK_NULL(cache);
|
|
|
|
line = ocf_atomic_addr2line(cache, addr + bytes);
|
|
pos = ocf_atomic_addr2pos(cache, addr + bytes);
|
|
|
|
if (!pos || addr < cache->device->metadata_offset)
|
|
return 0;
|
|
|
|
for (i = pos; i < ocf_line_sectors(cache); i++) {
|
|
if (metadata_test_valid_one(cache, line, i))
|
|
return 0;
|
|
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|