Compare properties of a new cache device during cache attach
New cache device must have all the same properties then the previously attached one. Keeping cache properties in cache priv also allows to add new cores to detached cache instance. Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com> Signed-off-by: Rafal Stefanowski <rafal.stefanowski@huawei.com>
This commit is contained in:
parent
e0ef8c1b8d
commit
cef13315d0
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2022 Intel Corporation
|
||||
* Copyright(c) 2024 Huawei Technologies
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
@ -70,6 +71,11 @@ struct cache_priv {
|
||||
ocf_queue_t mngt_queue;
|
||||
void *attach_context;
|
||||
bool cache_exp_obj_initialized;
|
||||
struct {
|
||||
struct queue_limits queue_limits;
|
||||
bool fua;
|
||||
bool flush;
|
||||
} device_properties;
|
||||
ocf_queue_t io_queues[];
|
||||
};
|
||||
|
||||
|
@ -2220,6 +2220,24 @@ static void volume_set_no_merges_flag_helper(ocf_cache_t cache)
|
||||
cas_cache_set_no_merges_flag(cache_q);
|
||||
}
|
||||
|
||||
static void _cache_save_device_properties(ocf_cache_t cache)
|
||||
{
|
||||
struct block_device *bd;
|
||||
struct bd_object *bvol;
|
||||
struct request_queue *cache_q;
|
||||
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
||||
|
||||
bvol = bd_object(ocf_cache_get_volume(cache));
|
||||
bd = cas_disk_get_blkdev(bvol->dsk);
|
||||
cache_q = bd->bd_disk->queue;
|
||||
|
||||
cache_priv->device_properties.queue_limits = cache_q->limits;
|
||||
cache_priv->device_properties.flush =
|
||||
CAS_CHECK_QUEUE_FLUSH(cache_q);
|
||||
cache_priv->device_properties.fua =
|
||||
CAS_CHECK_QUEUE_FUA(cache_q);
|
||||
}
|
||||
|
||||
static int _cache_start_finalize(ocf_cache_t cache, int init_mode,
|
||||
bool activate)
|
||||
{
|
||||
@ -2239,6 +2257,8 @@ static int _cache_start_finalize(ocf_cache_t cache, int init_mode,
|
||||
ctx->cls_inited = true;
|
||||
|
||||
volume_set_no_merges_flag_helper(cache);
|
||||
|
||||
_cache_save_device_properties(cache);
|
||||
}
|
||||
|
||||
if (activate)
|
||||
@ -2278,14 +2298,21 @@ static int _cache_start_finalize(ocf_cache_t cache, int init_mode,
|
||||
}
|
||||
|
||||
static int cache_mngt_check_bdev(struct ocf_mngt_cache_device_config *cfg,
|
||||
bool force)
|
||||
bool force, bool reattach, ocf_cache_t cache)
|
||||
{
|
||||
char holder[] = "CAS START\n";
|
||||
cas_bdev_handle_t bdev_handle;
|
||||
struct block_device *bdev;
|
||||
int part_count;
|
||||
bool is_part;
|
||||
bool reattach_properties_diff = false;
|
||||
struct cache_priv *cache_priv;
|
||||
const struct ocf_volume_uuid *uuid = ocf_volume_get_uuid(cfg->volume);
|
||||
/* The only reason to use blk_stack_limits() is checking compatibility of
|
||||
* the new device with the original cache. But since the functions modifies
|
||||
* content of queue_limits, we use copy of the original struct.
|
||||
*/
|
||||
struct queue_limits tmp_limits;
|
||||
|
||||
bdev_handle = cas_bdev_open_by_path(uuid->data,
|
||||
(CAS_BLK_MODE_EXCL | CAS_BLK_MODE_READ), holder);
|
||||
@ -2298,12 +2325,48 @@ static int cache_mngt_check_bdev(struct ocf_mngt_cache_device_config *cfg,
|
||||
|
||||
is_part = (cas_bdev_whole(bdev) != bdev);
|
||||
part_count = cas_blk_get_part_count(bdev);
|
||||
|
||||
if (reattach) {
|
||||
ENV_BUG_ON(!cache);
|
||||
|
||||
cache_priv = ocf_cache_get_priv(cache);
|
||||
tmp_limits = cache_priv->device_properties.queue_limits;
|
||||
|
||||
if (blk_stack_limits(&tmp_limits, &bdev->bd_disk->queue->limits, 0)) {
|
||||
reattach_properties_diff = true;
|
||||
printk(KERN_WARNING "New cache device block properties "
|
||||
"differ from the previous one.\n");
|
||||
}
|
||||
if (tmp_limits.misaligned) {
|
||||
reattach_properties_diff = true;
|
||||
printk(KERN_WARNING "New cache device block interval "
|
||||
"doesn't line up with the previous one.\n");
|
||||
}
|
||||
if (CAS_CHECK_QUEUE_FLUSH(bdev->bd_disk->queue) !=
|
||||
cache_priv->device_properties.flush) {
|
||||
reattach_properties_diff = true;
|
||||
printk(KERN_WARNING "New cache device %s support flush "
|
||||
"in contrary to the previous cache device.\n",
|
||||
cache_priv->device_properties.flush ? "doesn't" : "does");
|
||||
}
|
||||
if (CAS_CHECK_QUEUE_FUA(bdev->bd_disk->queue) !=
|
||||
cache_priv->device_properties.fua) {
|
||||
reattach_properties_diff = true;
|
||||
printk(KERN_WARNING "New cache device %s support fua "
|
||||
"in contrary to the previous cache device.\n",
|
||||
cache_priv->device_properties.fua ? "doesn't" : "does");
|
||||
}
|
||||
}
|
||||
|
||||
cas_bdev_release(bdev_handle,
|
||||
(CAS_BLK_MODE_EXCL | CAS_BLK_MODE_READ), holder);
|
||||
|
||||
if (!is_part && part_count > 1 && !force)
|
||||
return -KCAS_ERR_CONTAINS_PART;
|
||||
|
||||
if (reattach_properties_diff)
|
||||
return -KCAS_ERR_DEVICE_PROPERTIES_MISMATCH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2416,7 +2479,7 @@ int cache_mngt_activate(struct ocf_mngt_cache_standby_activate_config *cfg,
|
||||
* to compare data on drive and in DRAM to provide more specific
|
||||
* error code.
|
||||
*/
|
||||
result = cache_mngt_check_bdev(&cfg->device, true);
|
||||
result = cache_mngt_check_bdev(&cfg->device, true, false, NULL);
|
||||
if (result)
|
||||
goto out_cache_unlock;
|
||||
|
||||
@ -2513,7 +2576,7 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return -KCAS_ERR_SYSTEM;
|
||||
|
||||
result = cache_mngt_check_bdev(&attach_cfg->device, attach_cfg->force);
|
||||
result = cache_mngt_check_bdev(&attach_cfg->device, attach_cfg->force, false, NULL);
|
||||
if (result) {
|
||||
module_put(THIS_MODULE);
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user