Skip to content

Commit ba4b81a

Browse files
Merge pull request #863 from Deixx/detach-zero-superblock
Zero metadata superblock on detach
2 parents c200c24 + 3263503 commit ba4b81a

File tree

3 files changed

+65
-21
lines changed

3 files changed

+65
-21
lines changed

src/metadata/metadata_structs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright(c) 2012-2022 Intel Corporation
3+
* Copyright(c) 2025 Huawei Technologies
34
* SPDX-License-Identifier: BSD-3-Clause
45
*/
56

@@ -21,9 +22,8 @@
2122
* @brief Metadata shutdown status
2223
*/
2324
enum ocf_metadata_shutdown_status {
24-
ocf_metadata_clean_shutdown = 1, /*!< OCF shutdown graceful*/
2525
ocf_metadata_dirty_shutdown = 0, /*!< Dirty OCF shutdown*/
26-
ocf_metadata_detached = 2, /*!< Cache device detached */
26+
ocf_metadata_clean_shutdown = 1, /*!< OCF shutdown graceful*/
2727
};
2828

2929
/**

src/mngt/ocf_mngt_cache.c

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright(c) 2012-2022 Intel Corporation
3-
* Copyright(c) 2023-2024 Huawei Technologies
3+
* Copyright(c) 2023-2025 Huawei Technologies
44
* SPDX-License-Identifier: BSD-3-Clause
55
*/
66

@@ -1760,7 +1760,7 @@ static void _ocf_mngt_init_promotion(ocf_pipeline_t pipeline,
17601760
ocf_pipeline_next(pipeline);
17611761
}
17621762

1763-
static void _ocf_mngt_zero_superblock_complete(void *priv, int error)
1763+
static void _ocf_mngt_attach_zero_superblock_complete(void *priv, int error)
17641764
{
17651765
struct ocf_cache_attach_context *context = priv;
17661766
ocf_cache_t cache = context->cache;
@@ -1774,14 +1774,14 @@ static void _ocf_mngt_zero_superblock_complete(void *priv, int error)
17741774
ocf_pipeline_next(context->pipeline);
17751775
}
17761776

1777-
static void _ocf_mngt_zero_superblock(ocf_pipeline_t pipeline,
1777+
static void _ocf_mngt_attach_zero_superblock(ocf_pipeline_t pipeline,
17781778
void *priv, ocf_pipeline_arg_t arg)
17791779
{
17801780
struct ocf_cache_attach_context *context = priv;
17811781
ocf_cache_t cache = context->cache;
17821782

17831783
ocf_metadata_zero_superblock(cache,
1784-
_ocf_mngt_zero_superblock_complete, context);
1784+
_ocf_mngt_attach_zero_superblock_complete, context);
17851785
}
17861786

17871787
static void _ocf_mngt_attach_flush_metadata_complete(void *priv, int error)
@@ -2011,7 +2011,7 @@ struct ocf_pipeline_properties _ocf_mngt_cache_attach_pipeline_properties = {
20112011
OCF_PL_STEP(_ocf_mngt_attach_init_metadata),
20122012
OCF_PL_STEP(_ocf_mngt_attach_populate_free),
20132013
OCF_PL_STEP(_ocf_mngt_attach_init_services),
2014-
OCF_PL_STEP(_ocf_mngt_zero_superblock),
2014+
OCF_PL_STEP(_ocf_mngt_attach_zero_superblock),
20152015
OCF_PL_STEP(_ocf_mngt_attach_flush_metadata),
20162016
OCF_PL_STEP(_ocf_mngt_attach_discard),
20172017
OCF_PL_STEP(_ocf_mngt_attach_flush),
@@ -2172,6 +2172,31 @@ static void ocf_mngt_cache_stop_unplug(ocf_pipeline_t pipeline,
21722172
ocf_mngt_cache_stop_unplug_complete, context);
21732173
}
21742174

2175+
static void _ocf_mngt_detach_zero_superblock_complete(void *priv, int error)
2176+
{
2177+
struct ocf_mngt_cache_unplug_context *context = priv;
2178+
ocf_cache_t cache = context->cache;
2179+
2180+
if (error) {
2181+
ocf_cache_log(cache, log_err,
2182+
"ERROR: Failed to clear the superblock on the detached device\n"
2183+
"The metadata on the device is in an invalid state"
2184+
" - manual superblock clearing is recommended.\n");
2185+
}
2186+
2187+
ocf_pipeline_next(context->pipeline);
2188+
}
2189+
2190+
static void _ocf_mngt_detach_zero_superblock(ocf_pipeline_t pipeline,
2191+
void *priv, ocf_pipeline_arg_t arg)
2192+
{
2193+
struct ocf_mngt_cache_unplug_context *context = priv;
2194+
ocf_cache_t cache = context->cache;
2195+
2196+
ocf_metadata_zero_superblock(cache,
2197+
_ocf_mngt_detach_zero_superblock_complete, context);
2198+
}
2199+
21752200
static void _ocf_mngt_cache_put_io_queues(ocf_cache_t cache)
21762201
{
21772202
ocf_queue_t queue, tmp_queue;
@@ -2443,7 +2468,7 @@ struct ocf_pipeline_properties _ocf_mngt_cache_standby_attach_pipeline_propertie
24432468
OCF_PL_STEP(_ocf_mngt_attach_populate_free),
24442469
OCF_PL_STEP(_ocf_mngt_standby_prepare_mempool),
24452470
OCF_PL_STEP(_ocf_mngt_standby_init_pio_concurrency),
2446-
OCF_PL_STEP(_ocf_mngt_zero_superblock),
2471+
OCF_PL_STEP(_ocf_mngt_attach_zero_superblock),
24472472
OCF_PL_STEP(_ocf_mngt_attach_flush_metadata),
24482473
OCF_PL_STEP(_ocf_mngt_attach_discard),
24492474
OCF_PL_STEP(_ocf_mngt_attach_flush),
@@ -3147,6 +3172,8 @@ static void _ocf_mngt_cache_unplug(ocf_cache_t cache, bool stop,
31473172
struct _ocf_mngt_cache_unplug_context *context,
31483173
_ocf_mngt_cache_unplug_end_t cmpl, void *priv)
31493174
{
3175+
struct ocf_mngt_cache_unplug_context *ctx = priv;
3176+
31503177
context->cmpl = cmpl;
31513178
context->priv = priv;
31523179
context->cache = cache;
@@ -3157,14 +3184,13 @@ static void _ocf_mngt_cache_unplug(ocf_cache_t cache, bool stop,
31573184
__deinit_promotion_policy(cache);
31583185

31593186
if (!stop) {
3160-
/* Just set correct shutdown status */
3161-
ocf_metadata_set_shutdown_status(cache, ocf_metadata_detached,
3162-
_ocf_mngt_cache_unplug_complete, context);
3163-
} else {
3164-
/* Flush metadata */
3165-
ocf_metadata_flush_all(cache,
3166-
_ocf_mngt_cache_unplug_complete, context);
3187+
/* Skip metadata update - will be zeroed later in the detach pipeline */
3188+
OCF_PL_NEXT_RET(ctx->pipeline);
31673189
}
3190+
3191+
/* Flush metadata */
3192+
ocf_metadata_flush_all(cache,
3193+
_ocf_mngt_cache_unplug_complete, context);
31683194
}
31693195

31703196
static int _ocf_mngt_cache_load_core_log(ocf_core_t core, void *cntx)
@@ -3850,6 +3876,7 @@ struct ocf_pipeline_properties ocf_mngt_cache_detach_pipeline_properties = {
38503876
OCF_PL_STEP(ocf_mngt_cache_stop_check_dirty),
38513877
OCF_PL_STEP(ocf_mngt_cache_detach_update_metadata),
38523878
OCF_PL_STEP(ocf_mngt_cache_detach_unplug),
3879+
OCF_PL_STEP(_ocf_mngt_detach_zero_superblock),
38533880
OCF_PL_STEP(ocf_mngt_cache_close_cache_volume),
38543881
OCF_PL_STEP(ocf_mngt_cache_deinit_metadata),
38553882
OCF_PL_STEP(ocf_mngt_cache_deinit_cache_volume),

tests/functional/tests/management/test_attach_cache.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
#
22
# Copyright(c) 2019-2022 Intel Corporation
3-
# Copyright(c) 2024 Huawei Technologies
3+
# Copyright(c) 2024-2025 Huawei Technologies
44
# SPDX-License-Identifier: BSD-3-Clause
55
#
66

77
import logging
8-
from ctypes import c_int, c_void_p, byref, c_uint32, memmove, cast
9-
from random import randrange
10-
from itertools import count
8+
from ctypes import c_void_p, memmove, cast
119

1210
import pytest
13-
1411
from pyocf.types.cache import (
1512
Cache,
1613
CacheMode,
@@ -70,12 +67,32 @@ def test_detach_cache_twice(pyocf_ctx):
7067
cache.stop()
7168

7269

70+
def test_detach_cache_zero_superblock(pyocf_ctx):
71+
"""Check if superblock is zeroed after detach and the cache device can be reattached without
72+
--force option.
73+
"""
74+
cache_device = RamVolume(Size.from_MiB(50))
75+
cache = Cache.start_on_device(cache_device)
76+
77+
cache.detach_device()
78+
79+
data = cache_device.get_bytes()
80+
81+
page_size = 4096
82+
assert data[:page_size] == b'\x00'*page_size
83+
84+
cache.attach_device(cache_device, force=False)
85+
cache.detach_device()
86+
87+
cache.stop()
88+
89+
7390
@pytest.mark.parametrize("cls", CacheLineSize)
7491
@pytest.mark.parametrize("mode", [CacheMode.WB, CacheMode.WT, CacheMode.WO])
7592
@pytest.mark.parametrize("new_cache_size", [80, 120])
7693
def test_attach_different_size(pyocf_ctx, new_cache_size, mode: CacheMode, cls: CacheLineSize):
7794
"""Start cache and add partition with limited occupancy. Fill partition with data,
78-
attach cache with different size and trigger IO. Verify if occupancy thresold is
95+
attach cache with different size and trigger IO. Verify if occupancy threshold is
7996
respected with both original and new cache device.
8097
"""
8198
cache_device = RamVolume(Size.from_MiB(100))

0 commit comments

Comments
 (0)