diff --git a/modules/cas_cache/cas_cache.h b/modules/cas_cache/cas_cache.h index 1cc0b22..3ecf554 100644 --- a/modules/cas_cache/cas_cache.h +++ b/modules/cas_cache/cas_cache.h @@ -72,6 +72,7 @@ struct casdsk_functions_mapper { int (*casdsk_exp_obj_destroy)(struct casdsk_disk *dsk); int (*casdsk_exp_obj_create)(struct casdsk_disk *dsk, const char *dev_name, struct module *owner, struct casdsk_exp_obj_ops *ops); + void(*casdsk_exp_obj_free)(struct casdsk_disk *dsk); struct request_queue *(*casdsk_disk_get_queue)(struct casdsk_disk *dsk); void (*casdsk_store_config)(size_t n_blobs, struct casdsk_props_conf *blobs); struct block_device *(*casdsk_disk_get_blkdev)(struct casdsk_disk *dsk); diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 7a032b4..b88972d 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -1565,13 +1565,11 @@ out: } /** - * @brief routine implements --remove-cache command. - * @param[in] device caching device to be removed + * @brief routine implements --stop-cache command. + * @param[in] cache_id caching device id to be removed * @param[in] flush Boolean: shall we flush dirty data before removing cache. * if yes, flushing may still be interrupted by user (in which case * device won't be actually removed and error will be returned) - * @param[in] allow_interruption shall we allow interruption of dirty - * data flushing */ int cache_mngt_exit_instance(ocf_cache_id_t id, int flush) { @@ -1648,7 +1646,7 @@ int cache_mngt_exit_instance(ocf_cache_id_t id, int flush) /* Stop cache device */ status = _cache_mngt_cache_stop_sync(cache); if (status && status != -OCF_ERR_WRITE_CACHE) - goto unlock; + goto restore_exp_obj; if (!status && flush_status) status = -KCAS_ERR_STOPPED_DIRTY; @@ -1660,6 +1658,24 @@ int cache_mngt_exit_instance(ocf_cache_id_t id, int flush) ocf_queue_put(cache_priv->mngt_queue); vfree(cache_priv); + ocf_mngt_cache_unlock(cache); + ocf_mngt_cache_put(cache); + + return status; + +restore_exp_obj: + if (block_dev_create_all_exported_objects(cache)) { + /* Print error msg but do not change return err code to inform user why + * stop failed originally. */ + printk(KERN_WARNING + "Failed to restore (create) all exported objects!\n"); + goto unlock; + } + if (block_dev_activate_all_exported_objects(cache)) { + block_dev_destroy_all_exported_objects(cache); + printk(KERN_WARNING + "Failed to restore (activate) all exported objects!\n"); + } unlock: ocf_mngt_cache_unlock(cache); put: diff --git a/modules/cas_cache/main.c b/modules/cas_cache/main.c index c46dd1d..2c285ec 100644 --- a/modules/cas_cache/main.c +++ b/modules/cas_cache/main.c @@ -79,6 +79,7 @@ int static cas_casdisk_lookup_funtions(void) cas_lookup_symbol(casdsk_disk_dettach); cas_lookup_symbol(casdsk_exp_obj_destroy); cas_lookup_symbol(casdsk_exp_obj_create); + cas_lookup_symbol(casdsk_exp_obj_free); cas_lookup_symbol(casdsk_disk_get_queue); cas_lookup_symbol(casdsk_store_config); cas_lookup_symbol(casdsk_disk_get_blkdev); diff --git a/modules/cas_cache/volume/vol_block_dev_bottom.c b/modules/cas_cache/volume/vol_block_dev_bottom.c index 756a74b..7978fc0 100644 --- a/modules/cas_cache/volume/vol_block_dev_bottom.c +++ b/modules/cas_cache/volume/vol_block_dev_bottom.c @@ -29,7 +29,7 @@ int block_dev_open_object(ocf_volume_t vol, void *volume_params) struct casdsk_disk *dsk; if (bdobj->opened_by_bdev) { - /* Bdev has beed set manually, so there is nothing to do. */ + /* Bdev has been set manually, so there is nothing to do. */ return 0; } diff --git a/modules/cas_cache/volume/vol_block_dev_top.c b/modules/cas_cache/volume/vol_block_dev_top.c index 4de5bd6..98480fa 100644 --- a/modules/cas_cache/volume/vol_block_dev_top.c +++ b/modules/cas_cache/volume/vol_block_dev_top.c @@ -884,6 +884,17 @@ int block_dev_activate_exported_object(ocf_core_t core) return ret; } +static int _block_dev_activate_exported_object(ocf_core_t core, void *cntx) +{ + return block_dev_activate_exported_object(core); +} + +int block_dev_activate_all_exported_objects(ocf_cache_t cache) +{ + return ocf_core_visit(cache, _block_dev_activate_exported_object, NULL, + true); +} + int block_dev_create_exported_object(ocf_core_t core) { ocf_volume_t obj = ocf_core_get_volume(core); @@ -915,6 +926,17 @@ int block_dev_create_exported_object(ocf_core_t core) return result; } +static int _block_dev_create_exported_object_visitor(ocf_core_t core, void *cntx) +{ + return block_dev_create_exported_object(core); +} + +int block_dev_create_all_exported_objects(ocf_cache_t cache) +{ + return ocf_core_visit(cache, _block_dev_create_exported_object_visitor, NULL, + true); +} + int block_dev_destroy_exported_object(ocf_core_t core) { int ret = 0; @@ -1014,5 +1036,21 @@ int block_dev_destroy_all_exported_objects(ocf_cache_t cache) ocf_core_visit(cache, _block_dev_stop_exported_object, NULL, true); + block_dev_free_all_exported_objects(cache); return 0; } + +static int _block_dev_free_exported_object(ocf_core_t core, void *cntx) +{ + struct bd_object *bvol = bd_object( + ocf_core_get_volume(core)); + + casdisk_functions.casdsk_exp_obj_free(bvol->dsk); + return 0; +} + +int block_dev_free_all_exported_objects(ocf_cache_t cache) +{ + return ocf_core_visit(cache, _block_dev_free_exported_object, NULL, + true); +} diff --git a/modules/cas_cache/volume/vol_block_dev_top.h b/modules/cas_cache/volume/vol_block_dev_top.h index aef7b30..dc3a3c2 100644 --- a/modules/cas_cache/volume/vol_block_dev_top.h +++ b/modules/cas_cache/volume/vol_block_dev_top.h @@ -6,12 +6,15 @@ #ifndef __VOL_BLOCK_DEV_TOP_H__ #define __VOL_BLOCK_DEV_TOP_H__ +int block_dev_activate_all_exported_objects(ocf_cache_t cache); int block_dev_activate_exported_object(ocf_core_t core); +int block_dev_create_all_exported_objects(ocf_cache_t cache); int block_dev_create_exported_object(ocf_core_t core); +int block_dev_destroy_all_exported_objects(ocf_cache_t cache); int block_dev_destroy_exported_object(ocf_core_t core); -int block_dev_destroy_all_exported_objects(ocf_cache_t cache); +int block_dev_free_all_exported_objects(ocf_cache_t cache); #endif /* __VOL_BLOCK_DEV_TOP_H__ */ diff --git a/modules/cas_disk/exp_obj.c b/modules/cas_disk/exp_obj.c index 0a6608b..17202f8 100644 --- a/modules/cas_disk/exp_obj.c +++ b/modules/cas_disk/exp_obj.c @@ -421,6 +421,7 @@ void casdsk_exp_obj_free(struct casdsk_disk *dsk) kobject_put(&exp_obj->kobj); dsk->exp_obj = NULL; } +EXPORT_SYMBOL(casdsk_exp_obj_free); static void __casdsk_exp_obj_release(struct casdsk_exp_obj *exp_obj) { @@ -723,7 +724,10 @@ int casdsk_exp_obj_destroy(struct casdsk_disk *dsk) struct casdsk_exp_obj *exp_obj; BUG_ON(!dsk); - BUG_ON(!dsk->exp_obj); + + if (!dsk->exp_obj) + return -ENODEV; + BUG_ON(!dsk->exp_obj->locked_bd); CASDSK_DEBUG_DISK_TRACE(dsk);