LCOV - code coverage report
Current view: top level - module/bdev/ocf - vbdev_ocf.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 836 0.0 %
Date: 2024-11-05 10:06:02 Functions: 0 76 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2018 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include <ocf/ocf.h>
       7             : #include <ocf/ocf_types.h>
       8             : #include <ocf/ocf_mngt.h>
       9             : 
      10             : #include "ctx.h"
      11             : #include "data.h"
      12             : #include "volume.h"
      13             : #include "utils.h"
      14             : #include "vbdev_ocf.h"
      15             : 
      16             : #include "spdk/bdev_module.h"
      17             : #include "spdk/thread.h"
      18             : #include "spdk/string.h"
      19             : #include "spdk/log.h"
      20             : #include "spdk/cpuset.h"
      21             : 
      22             : /* This namespace UUID was generated using uuid_generate() method. */
      23             : #define BDEV_OCF_NAMESPACE_UUID "f92b7f49-f6c0-44c8-bd23-3205e8c3b6ad"
      24             : 
      25             : static struct spdk_bdev_module ocf_if;
      26             : 
      27             : static TAILQ_HEAD(, vbdev_ocf) g_ocf_vbdev_head
      28             :         = TAILQ_HEAD_INITIALIZER(g_ocf_vbdev_head);
      29             : 
      30             : static TAILQ_HEAD(, examining_bdev) g_ocf_examining_bdevs_head
      31             :         = TAILQ_HEAD_INITIALIZER(g_ocf_examining_bdevs_head);
      32             : 
      33             : static bool g_fini_started = false;
      34             : 
      35             : /* Structure for keeping list of bdevs that are claimed but not used yet */
      36             : struct examining_bdev {
      37             :         struct spdk_bdev           *bdev;
      38             :         TAILQ_ENTRY(examining_bdev) tailq;
      39             : };
      40             : 
      41             : /* Add bdev to list of claimed */
      42             : static void
      43           0 : examine_start(struct spdk_bdev *bdev)
      44             : {
      45           0 :         struct examining_bdev *entry = malloc(sizeof(*entry));
      46             : 
      47           0 :         assert(entry);
      48           0 :         entry->bdev = bdev;
      49           0 :         TAILQ_INSERT_TAIL(&g_ocf_examining_bdevs_head, entry, tailq);
      50           0 : }
      51             : 
      52             : /* Find bdev on list of claimed bdevs, then remove it,
      53             :  * if it was the last one on list then report examine done */
      54             : static void
      55           0 : examine_done(int status, struct vbdev_ocf *vbdev, void *cb_arg)
      56             : {
      57           0 :         struct spdk_bdev *bdev = cb_arg;
      58           0 :         struct examining_bdev *entry, *safe, *found = NULL;
      59             : 
      60           0 :         TAILQ_FOREACH_SAFE(entry, &g_ocf_examining_bdevs_head, tailq, safe) {
      61           0 :                 if (entry->bdev == bdev) {
      62           0 :                         if (found) {
      63           0 :                                 goto remove;
      64             :                         } else {
      65           0 :                                 found = entry;
      66             :                         }
      67             :                 }
      68             :         }
      69             : 
      70           0 :         assert(found);
      71           0 :         spdk_bdev_module_examine_done(&ocf_if);
      72             : 
      73           0 : remove:
      74           0 :         TAILQ_REMOVE(&g_ocf_examining_bdevs_head, found, tailq);
      75           0 :         free(found);
      76           0 : }
      77             : 
      78             : /* Free allocated strings and structure itself
      79             :  * Used at shutdown only */
      80             : static void
      81           0 : free_vbdev(struct vbdev_ocf *vbdev)
      82             : {
      83           0 :         if (!vbdev) {
      84           0 :                 return;
      85             :         }
      86             : 
      87           0 :         free(vbdev->name);
      88           0 :         free(vbdev->cache.name);
      89           0 :         free(vbdev->core.name);
      90           0 :         free(vbdev);
      91             : }
      92             : 
      93             : /* Get existing cache base
      94             :  * that is attached to other vbdev */
      95             : static struct vbdev_ocf_base *
      96           0 : get_other_cache_base(struct vbdev_ocf_base *base)
      97             : {
      98             :         struct vbdev_ocf *vbdev;
      99             : 
     100           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
     101           0 :                 if (&vbdev->cache == base || !vbdev->cache.attached) {
     102           0 :                         continue;
     103             :                 }
     104           0 :                 if (!strcmp(vbdev->cache.name, base->name)) {
     105           0 :                         return &vbdev->cache;
     106             :                 }
     107             :         }
     108             : 
     109           0 :         return NULL;
     110             : }
     111             : 
     112             : static bool
     113           0 : is_ocf_cache_running(struct vbdev_ocf *vbdev)
     114             : {
     115           0 :         if (vbdev->cache.attached && vbdev->ocf_cache) {
     116           0 :                 return ocf_cache_is_running(vbdev->ocf_cache);
     117             :         }
     118           0 :         return false;
     119             : }
     120             : 
     121             : static bool
     122           0 : is_ocf_cache_initializing(struct vbdev_ocf *vbdev)
     123             : {
     124           0 :         if (vbdev->cache.attached && vbdev->ocf_cache) {
     125           0 :                 return ocf_cache_is_initializing(vbdev->ocf_cache);
     126             :         }
     127           0 :         return false;
     128             : }
     129             : 
     130             : /* Get existing OCF cache instance
     131             :  * that is started by other vbdev */
     132             : static ocf_cache_t
     133           0 : get_other_cache_instance(struct vbdev_ocf *vbdev)
     134             : {
     135             :         struct vbdev_ocf *cmp;
     136             : 
     137           0 :         TAILQ_FOREACH(cmp, &g_ocf_vbdev_head, tailq) {
     138           0 :                 if (cmp->state.doing_finish || cmp == vbdev) {
     139           0 :                         continue;
     140             :                 }
     141           0 :                 if (strcmp(cmp->cache.name, vbdev->cache.name)) {
     142           0 :                         continue;
     143             :                 }
     144           0 :                 if (is_ocf_cache_running(cmp) || is_ocf_cache_initializing(cmp)) {
     145           0 :                         return cmp->ocf_cache;
     146             :                 }
     147             :         }
     148             : 
     149           0 :         return NULL;
     150             : }
     151             : 
     152             : static void
     153           0 : _remove_base_bdev(void *ctx)
     154             : {
     155           0 :         struct spdk_bdev_desc *desc = ctx;
     156             : 
     157           0 :         spdk_bdev_close(desc);
     158           0 : }
     159             : 
     160             : /* Close and unclaim base bdev */
     161             : static void
     162           0 : remove_base_bdev(struct vbdev_ocf_base *base)
     163             : {
     164           0 :         if (base->attached) {
     165           0 :                 if (base->management_channel) {
     166           0 :                         spdk_put_io_channel(base->management_channel);
     167             :                 }
     168             : 
     169           0 :                 spdk_bdev_module_release_bdev(base->bdev);
     170             :                 /* Close the underlying bdev on its same opened thread. */
     171           0 :                 if (base->thread && base->thread != spdk_get_thread()) {
     172           0 :                         spdk_thread_send_msg(base->thread, _remove_base_bdev, base->desc);
     173             :                 } else {
     174           0 :                         spdk_bdev_close(base->desc);
     175             :                 }
     176           0 :                 base->attached = false;
     177             :         }
     178           0 : }
     179             : 
     180             : /* Finish unregister operation */
     181             : static void
     182           0 : unregister_finish(struct vbdev_ocf *vbdev)
     183             : {
     184           0 :         spdk_bdev_destruct_done(&vbdev->exp_bdev, vbdev->state.stop_status);
     185             : 
     186           0 :         if (vbdev->ocf_cache) {
     187           0 :                 ocf_mngt_cache_put(vbdev->ocf_cache);
     188             :         }
     189             : 
     190           0 :         if (vbdev->cache_ctx) {
     191           0 :                 vbdev_ocf_cache_ctx_put(vbdev->cache_ctx);
     192             :         }
     193           0 :         vbdev_ocf_mngt_continue(vbdev, 0);
     194           0 : }
     195             : 
     196             : static void
     197           0 : close_core_bdev(struct vbdev_ocf *vbdev)
     198             : {
     199           0 :         remove_base_bdev(&vbdev->core);
     200           0 :         vbdev_ocf_mngt_continue(vbdev, 0);
     201           0 : }
     202             : 
     203             : static void
     204           0 : remove_core_cmpl(void *priv, int error)
     205             : {
     206           0 :         struct vbdev_ocf *vbdev = priv;
     207             : 
     208           0 :         ocf_mngt_cache_unlock(vbdev->ocf_cache);
     209           0 :         vbdev_ocf_mngt_continue(vbdev, error);
     210           0 : }
     211             : 
     212             : /* Try to lock cache, then remove core */
     213             : static void
     214           0 : remove_core_cache_lock_cmpl(ocf_cache_t cache, void *priv, int error)
     215             : {
     216           0 :         struct vbdev_ocf *vbdev = (struct vbdev_ocf *)priv;
     217             : 
     218           0 :         if (error) {
     219           0 :                 SPDK_ERRLOG("Error %d, can not lock cache instance %s\n",
     220             :                             error, vbdev->name);
     221           0 :                 vbdev_ocf_mngt_continue(vbdev, error);
     222           0 :                 return;
     223             :         }
     224             : 
     225           0 :         ocf_mngt_cache_remove_core(vbdev->ocf_core, remove_core_cmpl, vbdev);
     226             : }
     227             : 
     228             : /* Detach core base */
     229             : static void
     230           0 : detach_core(struct vbdev_ocf *vbdev)
     231             : {
     232           0 :         if (is_ocf_cache_running(vbdev)) {
     233           0 :                 ocf_mngt_cache_lock(vbdev->ocf_cache, remove_core_cache_lock_cmpl, vbdev);
     234             :         } else {
     235           0 :                 vbdev_ocf_mngt_continue(vbdev, 0);
     236             :         }
     237           0 : }
     238             : 
     239             : static void
     240           0 : close_cache_bdev(struct vbdev_ocf *vbdev)
     241             : {
     242           0 :         remove_base_bdev(&vbdev->cache);
     243           0 :         vbdev_ocf_mngt_continue(vbdev, 0);
     244           0 : }
     245             : 
     246             : /* Detach cache base */
     247             : static void
     248           0 : detach_cache(struct vbdev_ocf *vbdev)
     249             : {
     250           0 :         vbdev->state.stop_status = vbdev->mngt_ctx.status;
     251             : 
     252             :         /* If some other vbdev references this cache bdev,
     253             :          * we detach this only by changing the flag, without actual close */
     254           0 :         if (get_other_cache_base(&vbdev->cache)) {
     255           0 :                 vbdev->cache.attached = false;
     256             :         }
     257             : 
     258           0 :         vbdev_ocf_mngt_continue(vbdev, 0);
     259           0 : }
     260             : 
     261             : static void
     262           0 : stop_vbdev_cmpl(ocf_cache_t cache, void *priv, int error)
     263             : {
     264           0 :         struct vbdev_ocf *vbdev = priv;
     265             : 
     266           0 :         vbdev_ocf_queue_put(vbdev->cache_ctx->mngt_queue);
     267           0 :         ocf_mngt_cache_unlock(cache);
     268             : 
     269           0 :         vbdev_ocf_mngt_continue(vbdev, error);
     270           0 : }
     271             : 
     272             : /* Try to lock cache, then stop it */
     273             : static void
     274           0 : stop_vbdev_cache_lock_cmpl(ocf_cache_t cache, void *priv, int error)
     275             : {
     276           0 :         struct vbdev_ocf *vbdev = (struct vbdev_ocf *)priv;
     277             : 
     278           0 :         if (error) {
     279           0 :                 SPDK_ERRLOG("Error %d, can not lock cache instance %s\n",
     280             :                             error, vbdev->name);
     281           0 :                 vbdev_ocf_mngt_continue(vbdev, error);
     282           0 :                 return;
     283             :         }
     284             : 
     285           0 :         ocf_mngt_cache_stop(vbdev->ocf_cache, stop_vbdev_cmpl, vbdev);
     286             : }
     287             : 
     288             : /* Stop OCF cache object
     289             :  * vbdev_ocf is not operational after this */
     290             : static void
     291           0 : stop_vbdev(struct vbdev_ocf *vbdev)
     292             : {
     293           0 :         if (!is_ocf_cache_running(vbdev)) {
     294           0 :                 vbdev_ocf_mngt_continue(vbdev, 0);
     295           0 :                 return;
     296             :         }
     297             : 
     298           0 :         if (!g_fini_started && get_other_cache_instance(vbdev)) {
     299           0 :                 SPDK_NOTICELOG("Not stopping cache instance '%s'"
     300             :                                " because it is referenced by other OCF bdev\n",
     301             :                                vbdev->cache.name);
     302           0 :                 vbdev_ocf_mngt_continue(vbdev, 0);
     303           0 :                 return;
     304             :         }
     305             : 
     306           0 :         ocf_mngt_cache_lock(vbdev->ocf_cache, stop_vbdev_cache_lock_cmpl, vbdev);
     307             : }
     308             : 
     309             : static void
     310           0 : flush_vbdev_cmpl(ocf_cache_t cache, void *priv, int error)
     311             : {
     312           0 :         struct vbdev_ocf *vbdev = priv;
     313             : 
     314           0 :         ocf_mngt_cache_unlock(cache);
     315           0 :         vbdev_ocf_mngt_continue(vbdev, error);
     316           0 : }
     317             : 
     318             : static void
     319           0 : flush_vbdev_cache_lock_cmpl(ocf_cache_t cache, void *priv, int error)
     320             : {
     321           0 :         struct vbdev_ocf *vbdev = (struct vbdev_ocf *)priv;
     322             : 
     323           0 :         if (error) {
     324           0 :                 SPDK_ERRLOG("Error %d, can not lock cache instance %s\n",
     325             :                             error, vbdev->name);
     326           0 :                 vbdev_ocf_mngt_continue(vbdev, error);
     327           0 :                 return;
     328             :         }
     329             : 
     330           0 :         ocf_mngt_cache_flush(vbdev->ocf_cache, flush_vbdev_cmpl, vbdev);
     331             : }
     332             : 
     333             : static void
     334           0 : flush_vbdev(struct vbdev_ocf *vbdev)
     335             : {
     336           0 :         if (!is_ocf_cache_running(vbdev)) {
     337           0 :                 vbdev_ocf_mngt_continue(vbdev, -EINVAL);
     338           0 :                 return;
     339             :         }
     340             : 
     341           0 :         ocf_mngt_cache_lock(vbdev->ocf_cache, flush_vbdev_cache_lock_cmpl, vbdev);
     342             : }
     343             : 
     344             : /* Procedures called during dirty unregister */
     345             : vbdev_ocf_mngt_fn unregister_path_dirty[] = {
     346             :         flush_vbdev,
     347             :         stop_vbdev,
     348             :         detach_cache,
     349             :         close_cache_bdev,
     350             :         detach_core,
     351             :         close_core_bdev,
     352             :         unregister_finish,
     353             :         NULL
     354             : };
     355             : 
     356             : /* Procedures called during clean unregister */
     357             : vbdev_ocf_mngt_fn unregister_path_clean[] = {
     358             :         flush_vbdev,
     359             :         detach_core,
     360             :         close_core_bdev,
     361             :         stop_vbdev,
     362             :         detach_cache,
     363             :         close_cache_bdev,
     364             :         unregister_finish,
     365             :         NULL
     366             : };
     367             : 
     368             : /* Start asynchronous management operation using unregister_path */
     369             : static void
     370           0 : unregister_cb(void *opaque)
     371             : {
     372           0 :         struct vbdev_ocf *vbdev = opaque;
     373             :         vbdev_ocf_mngt_fn *unregister_path;
     374             :         int rc;
     375             : 
     376           0 :         unregister_path = vbdev->state.doing_clean_delete ?
     377           0 :                           unregister_path_clean : unregister_path_dirty;
     378             : 
     379           0 :         rc = vbdev_ocf_mngt_start(vbdev, unregister_path, NULL, NULL);
     380           0 :         if (rc) {
     381           0 :                 SPDK_ERRLOG("Unable to unregister OCF bdev: %d\n", rc);
     382           0 :                 spdk_bdev_destruct_done(&vbdev->exp_bdev, rc);
     383             :         }
     384           0 : }
     385             : 
     386             : /* Clean remove case - remove core and then cache, this order
     387             :  * will remove instance permanently */
     388             : static void
     389           0 : _vbdev_ocf_destruct_clean(struct vbdev_ocf *vbdev)
     390             : {
     391           0 :         if (vbdev->core.attached) {
     392           0 :                 detach_core(vbdev);
     393           0 :                 close_core_bdev(vbdev);
     394             :         }
     395             : 
     396           0 :         if (vbdev->cache.attached) {
     397           0 :                 detach_cache(vbdev);
     398           0 :                 close_cache_bdev(vbdev);
     399             :         }
     400           0 : }
     401             : 
     402             : /* Dirty shutdown/hot remove case - remove cache and then core, this order
     403             :  * will allow us to recover this instance in the future */
     404             : static void
     405           0 : _vbdev_ocf_destruct_dirty(struct vbdev_ocf *vbdev)
     406             : {
     407           0 :         if (vbdev->cache.attached) {
     408           0 :                 detach_cache(vbdev);
     409           0 :                 close_cache_bdev(vbdev);
     410             :         }
     411             : 
     412           0 :         if (vbdev->core.attached) {
     413           0 :                 detach_core(vbdev);
     414           0 :                 close_core_bdev(vbdev);
     415             :         }
     416           0 : }
     417             : 
     418             : /* Unregister io device with callback to unregister_cb
     419             :  * This function is called during spdk_bdev_unregister */
     420             : static int
     421           0 : vbdev_ocf_destruct(void *opaque)
     422             : {
     423           0 :         struct vbdev_ocf *vbdev = opaque;
     424             : 
     425           0 :         if (vbdev->state.doing_finish) {
     426           0 :                 return -EALREADY;
     427             :         }
     428             : 
     429           0 :         if (vbdev->state.starting && !vbdev->state.started) {
     430             :                 /* Prevent before detach cache/core during register path of
     431             :                   this bdev */
     432           0 :                 return -EBUSY;
     433             :         }
     434             : 
     435           0 :         vbdev->state.doing_finish = true;
     436             : 
     437           0 :         if (vbdev->state.started) {
     438           0 :                 spdk_io_device_unregister(vbdev, unregister_cb);
     439             :                 /* Return 1 because unregister is delayed */
     440           0 :                 return 1;
     441             :         }
     442             : 
     443           0 :         if (vbdev->state.doing_clean_delete) {
     444           0 :                 _vbdev_ocf_destruct_clean(vbdev);
     445             :         } else {
     446           0 :                 _vbdev_ocf_destruct_dirty(vbdev);
     447             :         }
     448             : 
     449           0 :         return 0;
     450             : }
     451             : 
     452             : /* Stop OCF cache and unregister SPDK bdev */
     453             : int
     454           0 : vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg)
     455             : {
     456           0 :         int rc = 0;
     457             : 
     458           0 :         if (vbdev->state.started) {
     459           0 :                 spdk_bdev_unregister(&vbdev->exp_bdev, cb, cb_arg);
     460             :         } else {
     461           0 :                 rc = vbdev_ocf_destruct(vbdev);
     462           0 :                 if (rc == 0 && cb) {
     463           0 :                         cb(cb_arg, 0);
     464             :                 }
     465             :         }
     466             : 
     467           0 :         return rc;
     468             : }
     469             : 
     470             : /* Remove cores permanently and then stop OCF cache and unregister SPDK bdev */
     471             : int
     472           0 : vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int),
     473             :                        void *cb_arg)
     474             : {
     475           0 :         vbdev->state.doing_clean_delete = true;
     476             : 
     477           0 :         return vbdev_ocf_delete(vbdev, cb, cb_arg);
     478             : }
     479             : 
     480             : 
     481             : /* If vbdev is online, return its object */
     482             : struct vbdev_ocf *
     483           0 : vbdev_ocf_get_by_name(const char *name)
     484             : {
     485             :         struct vbdev_ocf *vbdev;
     486             : 
     487           0 :         if (name == NULL) {
     488           0 :                 assert(false);
     489             :                 return NULL;
     490             :         }
     491             : 
     492           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
     493           0 :                 if (vbdev->name == NULL || vbdev->state.doing_finish) {
     494           0 :                         continue;
     495             :                 }
     496           0 :                 if (strcmp(vbdev->name, name) == 0) {
     497           0 :                         return vbdev;
     498             :                 }
     499             :         }
     500           0 :         return NULL;
     501             : }
     502             : 
     503             : /* Return matching base if parent vbdev is online */
     504             : struct vbdev_ocf_base *
     505           0 : vbdev_ocf_get_base_by_name(const char *name)
     506             : {
     507             :         struct vbdev_ocf *vbdev;
     508             : 
     509           0 :         if (name == NULL) {
     510           0 :                 assert(false);
     511             :                 return NULL;
     512             :         }
     513             : 
     514           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
     515           0 :                 if (vbdev->state.doing_finish) {
     516           0 :                         continue;
     517             :                 }
     518             : 
     519           0 :                 if (vbdev->cache.name && strcmp(vbdev->cache.name, name) == 0) {
     520           0 :                         return &vbdev->cache;
     521             :                 }
     522           0 :                 if (vbdev->core.name && strcmp(vbdev->core.name, name) == 0) {
     523           0 :                         return &vbdev->core;
     524             :                 }
     525             :         }
     526           0 :         return NULL;
     527             : }
     528             : 
     529             : /* Execute fn for each OCF device that is online or waits for base devices */
     530             : void
     531           0 : vbdev_ocf_foreach(vbdev_ocf_foreach_fn fn, void *ctx)
     532             : {
     533             :         struct vbdev_ocf *vbdev;
     534             : 
     535           0 :         assert(fn != NULL);
     536             : 
     537           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
     538           0 :                 if (!vbdev->state.doing_finish) {
     539           0 :                         fn(vbdev, ctx);
     540             :                 }
     541             :         }
     542           0 : }
     543             : 
     544             : /* Called from OCF when SPDK_IO is completed */
     545             : static void
     546           0 : vbdev_ocf_io_submit_cb(struct ocf_io *io, int error)
     547             : {
     548           0 :         struct spdk_bdev_io *bdev_io = io->priv1;
     549             : 
     550           0 :         if (error == 0) {
     551           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
     552           0 :         } else if (error == -OCF_ERR_NO_MEM) {
     553           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
     554             :         } else {
     555           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
     556             :         }
     557             : 
     558           0 :         ocf_io_put(io);
     559           0 : }
     560             : 
     561             : /* Configure io parameters and send it to OCF */
     562             : static int
     563           0 : io_submit_to_ocf(struct spdk_bdev_io *bdev_io, struct ocf_io *io)
     564             : {
     565           0 :         switch (bdev_io->type) {
     566           0 :         case SPDK_BDEV_IO_TYPE_WRITE:
     567             :         case SPDK_BDEV_IO_TYPE_READ:
     568           0 :                 ocf_core_submit_io(io);
     569           0 :                 return 0;
     570           0 :         case SPDK_BDEV_IO_TYPE_FLUSH:
     571           0 :                 ocf_core_submit_flush(io);
     572           0 :                 return 0;
     573           0 :         case SPDK_BDEV_IO_TYPE_UNMAP:
     574           0 :                 ocf_core_submit_discard(io);
     575           0 :                 return 0;
     576           0 :         case SPDK_BDEV_IO_TYPE_RESET:
     577             :         case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
     578             :         default:
     579           0 :                 SPDK_ERRLOG("Unsupported IO type: %d\n", bdev_io->type);
     580           0 :                 return -EINVAL;
     581             :         }
     582             : }
     583             : 
     584             : /* Submit SPDK-IO to OCF */
     585             : static void
     586           0 : io_handle(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
     587             : {
     588           0 :         struct vbdev_ocf *vbdev = bdev_io->bdev->ctxt;
     589           0 :         struct ocf_io *io = NULL;
     590           0 :         struct bdev_ocf_data *data = NULL;
     591           0 :         struct vbdev_ocf_qctx *qctx = spdk_io_channel_get_ctx(ch);
     592           0 :         uint64_t len = bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen;
     593           0 :         uint64_t offset = bdev_io->u.bdev.offset_blocks * bdev_io->bdev->blocklen;
     594           0 :         int dir, flags = 0;
     595             :         int err;
     596             : 
     597           0 :         switch (bdev_io->type) {
     598           0 :         case SPDK_BDEV_IO_TYPE_READ:
     599           0 :                 dir = OCF_READ;
     600           0 :                 break;
     601           0 :         case SPDK_BDEV_IO_TYPE_WRITE:
     602           0 :                 dir = OCF_WRITE;
     603           0 :                 break;
     604           0 :         case SPDK_BDEV_IO_TYPE_FLUSH:
     605           0 :                 dir = OCF_WRITE;
     606           0 :                 break;
     607           0 :         case SPDK_BDEV_IO_TYPE_UNMAP:
     608           0 :                 dir = OCF_WRITE;
     609           0 :                 break;
     610           0 :         default:
     611           0 :                 err = -EINVAL;
     612           0 :                 goto fail;
     613             :         }
     614             : 
     615           0 :         if (bdev_io->type == SPDK_BDEV_IO_TYPE_FLUSH) {
     616           0 :                 flags = OCF_WRITE_FLUSH;
     617             :         }
     618             : 
     619           0 :         io = ocf_volume_new_io(ocf_core_get_front_volume(vbdev->ocf_core), qctx->queue, offset, len, dir, 0,
     620             :                                flags);
     621           0 :         if (!io) {
     622           0 :                 err = -ENOMEM;
     623           0 :                 goto fail;
     624             :         }
     625             : 
     626           0 :         data = vbdev_ocf_data_from_spdk_io(bdev_io);
     627           0 :         if (!data) {
     628           0 :                 err = -ENOMEM;
     629           0 :                 goto fail;
     630             :         }
     631             : 
     632           0 :         err = ocf_io_set_data(io, data, 0);
     633           0 :         if (err) {
     634           0 :                 goto fail;
     635             :         }
     636             : 
     637           0 :         ocf_io_set_cmpl(io, bdev_io, NULL, vbdev_ocf_io_submit_cb);
     638             : 
     639           0 :         err = io_submit_to_ocf(bdev_io, io);
     640           0 :         if (err) {
     641           0 :                 goto fail;
     642             :         }
     643             : 
     644           0 :         return;
     645             : 
     646           0 : fail:
     647           0 :         if (io) {
     648           0 :                 ocf_io_put(io);
     649             :         }
     650             : 
     651           0 :         if (err == -ENOMEM) {
     652           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
     653             :         } else {
     654           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
     655             :         }
     656             : }
     657             : 
     658             : static void
     659           0 : vbdev_ocf_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
     660             :                      bool success)
     661             : {
     662           0 :         if (!success) {
     663           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
     664           0 :                 return;
     665             :         }
     666             : 
     667           0 :         io_handle(ch, bdev_io);
     668             : }
     669             : 
     670             : /* Called from bdev layer when an io to Cache vbdev is submitted */
     671             : static void
     672           0 : vbdev_ocf_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
     673             : {
     674           0 :         switch (bdev_io->type) {
     675           0 :         case SPDK_BDEV_IO_TYPE_READ:
     676             :                 /* User does not have to allocate io vectors for the request,
     677             :                  * so in case they are not allocated, we allocate them here */
     678           0 :                 spdk_bdev_io_get_buf(bdev_io, vbdev_ocf_get_buf_cb,
     679           0 :                                      bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
     680           0 :                 break;
     681           0 :         case SPDK_BDEV_IO_TYPE_WRITE:
     682             :         case SPDK_BDEV_IO_TYPE_FLUSH:
     683             :         case SPDK_BDEV_IO_TYPE_UNMAP:
     684           0 :                 io_handle(ch, bdev_io);
     685           0 :                 break;
     686           0 :         case SPDK_BDEV_IO_TYPE_RESET:
     687             :         case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
     688             :         default:
     689           0 :                 SPDK_ERRLOG("Unknown I/O type %d\n", bdev_io->type);
     690           0 :                 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
     691           0 :                 break;
     692             :         }
     693           0 : }
     694             : 
     695             : /* Called from bdev layer */
     696             : static bool
     697           0 : vbdev_ocf_io_type_supported(void *opaque, enum spdk_bdev_io_type io_type)
     698             : {
     699           0 :         struct vbdev_ocf *vbdev = opaque;
     700             : 
     701           0 :         switch (io_type) {
     702           0 :         case SPDK_BDEV_IO_TYPE_READ:
     703             :         case SPDK_BDEV_IO_TYPE_WRITE:
     704             :         case SPDK_BDEV_IO_TYPE_FLUSH:
     705             :         case SPDK_BDEV_IO_TYPE_UNMAP:
     706           0 :                 return spdk_bdev_io_type_supported(vbdev->core.bdev, io_type);
     707           0 :         case SPDK_BDEV_IO_TYPE_RESET:
     708             :         case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
     709             :         default:
     710           0 :                 return false;
     711             :         }
     712             : }
     713             : 
     714             : /* Called from bdev layer */
     715             : static struct spdk_io_channel *
     716           0 : vbdev_ocf_get_io_channel(void *opaque)
     717             : {
     718           0 :         struct vbdev_ocf *bdev = opaque;
     719             : 
     720           0 :         return spdk_get_io_channel(bdev);
     721             : }
     722             : 
     723             : static int
     724           0 : vbdev_ocf_dump_info_json(void *opaque, struct spdk_json_write_ctx *w)
     725             : {
     726           0 :         struct vbdev_ocf *vbdev = opaque;
     727             : 
     728           0 :         spdk_json_write_named_string(w, "cache_device", vbdev->cache.name);
     729           0 :         spdk_json_write_named_string(w, "core_device", vbdev->core.name);
     730             : 
     731           0 :         spdk_json_write_named_string(w, "mode",
     732             :                                      ocf_get_cache_modename(ocf_cache_get_mode(vbdev->ocf_cache)));
     733           0 :         spdk_json_write_named_uint32(w, "cache_line_size",
     734           0 :                                      ocf_get_cache_line_size(vbdev->ocf_cache));
     735           0 :         spdk_json_write_named_bool(w, "metadata_volatile",
     736           0 :                                    vbdev->cfg.cache.metadata_volatile);
     737             : 
     738           0 :         return 0;
     739             : }
     740             : 
     741             : static void
     742           0 : vbdev_ocf_write_json_config(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w)
     743             : {
     744           0 :         struct vbdev_ocf *vbdev = bdev->ctxt;
     745             : 
     746           0 :         spdk_json_write_object_begin(w);
     747             : 
     748           0 :         spdk_json_write_named_string(w, "method", "bdev_ocf_create");
     749             : 
     750           0 :         spdk_json_write_named_object_begin(w, "params");
     751           0 :         spdk_json_write_named_string(w, "name", vbdev->name);
     752           0 :         spdk_json_write_named_string(w, "mode",
     753             :                                      ocf_get_cache_modename(ocf_cache_get_mode(vbdev->ocf_cache)));
     754           0 :         spdk_json_write_named_uint32(w, "cache_line_size",
     755           0 :                                      ocf_get_cache_line_size(vbdev->ocf_cache));
     756           0 :         spdk_json_write_named_string(w, "cache_bdev_name", vbdev->cache.name);
     757           0 :         spdk_json_write_named_string(w, "core_bdev_name", vbdev->core.name);
     758           0 :         spdk_json_write_object_end(w);
     759             : 
     760           0 :         spdk_json_write_object_end(w);
     761           0 : }
     762             : 
     763             : /* Cache vbdev function table
     764             :  * Used by bdev layer */
     765             : static struct spdk_bdev_fn_table cache_dev_fn_table = {
     766             :         .destruct = vbdev_ocf_destruct,
     767             :         .io_type_supported = vbdev_ocf_io_type_supported,
     768             :         .submit_request = vbdev_ocf_submit_request,
     769             :         .get_io_channel = vbdev_ocf_get_io_channel,
     770             :         .write_config_json = vbdev_ocf_write_json_config,
     771             :         .dump_info_json = vbdev_ocf_dump_info_json,
     772             : };
     773             : 
     774             : /* Poller function for the OCF queue
     775             :  * We execute OCF requests here synchronously */
     776             : static int
     777           0 : queue_poll(void *opaque)
     778             : {
     779           0 :         struct vbdev_ocf_qctx *qctx = opaque;
     780           0 :         uint32_t iono = ocf_queue_pending_io(qctx->queue);
     781           0 :         int i, max = spdk_min(32, iono);
     782             : 
     783           0 :         for (i = 0; i < max; i++) {
     784           0 :                 ocf_queue_run_single(qctx->queue);
     785             :         }
     786             : 
     787           0 :         if (iono > 0) {
     788           0 :                 return SPDK_POLLER_BUSY;
     789             :         } else {
     790           0 :                 return SPDK_POLLER_IDLE;
     791             :         }
     792             : }
     793             : 
     794             : /* Called during ocf_submit_io, ocf_purge*
     795             :  * and any other requests that need to submit io */
     796             : static void
     797           0 : vbdev_ocf_ctx_queue_kick(ocf_queue_t q)
     798             : {
     799           0 : }
     800             : 
     801             : /* OCF queue deinitialization
     802             :  * Called at ocf_cache_stop */
     803             : static void
     804           0 : vbdev_ocf_ctx_queue_stop(ocf_queue_t q)
     805             : {
     806           0 :         struct vbdev_ocf_qctx *qctx = ocf_queue_get_priv(q);
     807             : 
     808           0 :         if (qctx) {
     809           0 :                 spdk_put_io_channel(qctx->cache_ch);
     810           0 :                 spdk_put_io_channel(qctx->core_ch);
     811           0 :                 spdk_poller_unregister(&qctx->poller);
     812           0 :                 if (qctx->allocated) {
     813           0 :                         free(qctx);
     814             :                 }
     815             :         }
     816           0 : }
     817             : 
     818             : /* Queue ops is an interface for running queue thread
     819             :  * stop() operation in called just before queue gets destroyed */
     820             : const struct ocf_queue_ops queue_ops = {
     821             :         .kick_sync = vbdev_ocf_ctx_queue_kick,
     822             :         .kick = vbdev_ocf_ctx_queue_kick,
     823             :         .stop = vbdev_ocf_ctx_queue_stop,
     824             : };
     825             : 
     826             : /* Called on cache vbdev creation at every thread
     827             :  * We allocate OCF queues here and SPDK poller for it */
     828             : static int
     829           0 : io_device_create_cb(void *io_device, void *ctx_buf)
     830             : {
     831           0 :         struct vbdev_ocf *vbdev = io_device;
     832           0 :         struct vbdev_ocf_qctx *qctx = ctx_buf;
     833             :         int rc;
     834             : 
     835           0 :         rc = vbdev_ocf_queue_create(vbdev->ocf_cache, &qctx->queue, &queue_ops);
     836           0 :         if (rc) {
     837           0 :                 return rc;
     838             :         }
     839             : 
     840           0 :         ocf_queue_set_priv(qctx->queue, qctx);
     841             : 
     842           0 :         qctx->vbdev      = vbdev;
     843           0 :         qctx->cache_ch   = spdk_bdev_get_io_channel(vbdev->cache.desc);
     844           0 :         qctx->core_ch    = spdk_bdev_get_io_channel(vbdev->core.desc);
     845           0 :         qctx->poller     = SPDK_POLLER_REGISTER(queue_poll, qctx, 0);
     846             : 
     847           0 :         return rc;
     848             : }
     849             : 
     850             : /* Called per thread
     851             :  * Put OCF queue and relaunch poller with new context to finish pending requests */
     852             : static void
     853           0 : io_device_destroy_cb(void *io_device, void *ctx_buf)
     854             : {
     855             :         /* Making a copy of context to use it after io channel will be destroyed */
     856           0 :         struct vbdev_ocf_qctx *copy = malloc(sizeof(*copy));
     857           0 :         struct vbdev_ocf_qctx *qctx = ctx_buf;
     858             : 
     859           0 :         if (copy) {
     860           0 :                 ocf_queue_set_priv(qctx->queue, copy);
     861           0 :                 memcpy(copy, qctx, sizeof(*copy));
     862           0 :                 spdk_poller_unregister(&qctx->poller);
     863           0 :                 copy->poller = SPDK_POLLER_REGISTER(queue_poll, copy, 0);
     864           0 :                 copy->allocated = true;
     865             :         } else {
     866           0 :                 SPDK_ERRLOG("Unable to stop OCF queue properly: %s\n",
     867             :                             spdk_strerror(ENOMEM));
     868             :         }
     869             : 
     870           0 :         vbdev_ocf_queue_put(qctx->queue);
     871           0 : }
     872             : 
     873             : /* OCF management queue deinitialization */
     874             : static void
     875           0 : vbdev_ocf_ctx_mngt_queue_stop(ocf_queue_t q)
     876             : {
     877           0 :         struct spdk_poller *poller = ocf_queue_get_priv(q);
     878             : 
     879           0 :         if (poller) {
     880           0 :                 spdk_poller_unregister(&poller);
     881             :         }
     882           0 : }
     883             : 
     884             : static int
     885           0 : mngt_queue_poll(void *opaque)
     886             : {
     887           0 :         ocf_queue_t q = opaque;
     888           0 :         uint32_t iono = ocf_queue_pending_io(q);
     889           0 :         int i, max = spdk_min(32, iono);
     890             : 
     891           0 :         for (i = 0; i < max; i++) {
     892           0 :                 ocf_queue_run_single(q);
     893             :         }
     894             : 
     895           0 :         if (iono > 0) {
     896           0 :                 return SPDK_POLLER_BUSY;
     897             :         } else {
     898           0 :                 return SPDK_POLLER_IDLE;
     899             :         }
     900             : }
     901             : 
     902             : static void
     903           0 : vbdev_ocf_ctx_mngt_queue_kick(ocf_queue_t q)
     904             : {
     905           0 : }
     906             : 
     907             : /* Queue ops is an interface for running queue thread
     908             :  * stop() operation in called just before queue gets destroyed */
     909             : const struct ocf_queue_ops mngt_queue_ops = {
     910             :         .kick_sync = NULL,
     911             :         .kick = vbdev_ocf_ctx_mngt_queue_kick,
     912             :         .stop = vbdev_ocf_ctx_mngt_queue_stop,
     913             : };
     914             : 
     915             : static void
     916           0 : vbdev_ocf_mngt_exit(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn *rollback_path, int rc)
     917             : {
     918           0 :         vbdev->state.starting = false;
     919           0 :         vbdev_ocf_mngt_stop(vbdev, rollback_path, rc);
     920           0 : }
     921             : 
     922             : /* Create exported spdk object */
     923             : static void
     924           0 : finish_register(struct vbdev_ocf *vbdev)
     925             : {
     926           0 :         struct spdk_uuid ns_uuid;
     927             :         int result;
     928             : 
     929             :         /* Copy properties of the base bdev */
     930           0 :         vbdev->exp_bdev.blocklen = vbdev->core.bdev->blocklen;
     931           0 :         vbdev->exp_bdev.write_cache = vbdev->core.bdev->write_cache;
     932           0 :         vbdev->exp_bdev.required_alignment = vbdev->core.bdev->required_alignment;
     933             : 
     934           0 :         vbdev->exp_bdev.name = vbdev->name;
     935           0 :         vbdev->exp_bdev.product_name = "SPDK OCF";
     936             : 
     937           0 :         vbdev->exp_bdev.blockcnt = vbdev->core.bdev->blockcnt;
     938           0 :         vbdev->exp_bdev.ctxt = vbdev;
     939           0 :         vbdev->exp_bdev.fn_table = &cache_dev_fn_table;
     940           0 :         vbdev->exp_bdev.module = &ocf_if;
     941             : 
     942             :         /* Generate UUID based on namespace UUID + base bdev UUID. */
     943           0 :         spdk_uuid_parse(&ns_uuid, BDEV_OCF_NAMESPACE_UUID);
     944           0 :         result = spdk_uuid_generate_sha1(&vbdev->exp_bdev.uuid, &ns_uuid,
     945           0 :                                          (const char *)&vbdev->core.bdev->uuid, sizeof(struct spdk_uuid));
     946           0 :         if (result) {
     947           0 :                 SPDK_ERRLOG("Unable to generate new UUID for ocf bdev\n");
     948           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, result);
     949           0 :                 return;
     950             :         }
     951             : 
     952             :         /* Finally register vbdev in SPDK */
     953           0 :         spdk_io_device_register(vbdev, io_device_create_cb, io_device_destroy_cb,
     954           0 :                                 sizeof(struct vbdev_ocf_qctx), vbdev->name);
     955           0 :         result = spdk_bdev_register(&vbdev->exp_bdev);
     956           0 :         if (result) {
     957           0 :                 SPDK_ERRLOG("Could not register exposed bdev %s\n",
     958             :                             vbdev->name);
     959           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, result);
     960           0 :                 return;
     961             :         } else {
     962           0 :                 vbdev->state.started = true;
     963             :         }
     964             : 
     965           0 :         vbdev_ocf_mngt_continue(vbdev, result);
     966             : }
     967             : 
     968             : static void
     969           0 : add_core_cmpl(ocf_cache_t cache, ocf_core_t core, void *priv, int error)
     970             : {
     971           0 :         struct vbdev_ocf *vbdev = priv;
     972             : 
     973           0 :         ocf_mngt_cache_unlock(cache);
     974             : 
     975           0 :         if (error) {
     976           0 :                 SPDK_ERRLOG("Error %d, failed to add core device to cache instance %s,"
     977             :                             "starting rollback\n", error, vbdev->name);
     978           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, error);
     979           0 :                 return;
     980             :         } else {
     981           0 :                 vbdev->ocf_core = core;
     982             :         }
     983             : 
     984           0 :         vbdev_ocf_mngt_continue(vbdev, error);
     985             : }
     986             : 
     987             : /* Try to lock cache, then add core */
     988             : static void
     989           0 : add_core_cache_lock_cmpl(ocf_cache_t cache, void *priv, int error)
     990             : {
     991           0 :         struct vbdev_ocf *vbdev = (struct vbdev_ocf *)priv;
     992             : 
     993           0 :         if (error) {
     994           0 :                 SPDK_ERRLOG("Error %d, can not lock cache instance %s,"
     995             :                             "starting rollback\n", error, vbdev->name);
     996           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, error);
     997             :         }
     998           0 :         ocf_mngt_cache_add_core(vbdev->ocf_cache, &vbdev->cfg.core, add_core_cmpl, vbdev);
     999           0 : }
    1000             : 
    1001             : /* Add core for existing OCF cache instance */
    1002             : static void
    1003           0 : add_core(struct vbdev_ocf *vbdev)
    1004             : {
    1005           0 :         ocf_mngt_cache_lock(vbdev->ocf_cache, add_core_cache_lock_cmpl, vbdev);
    1006           0 : }
    1007             : 
    1008             : static void
    1009           0 : start_cache_cmpl(ocf_cache_t cache, void *priv, int error)
    1010             : {
    1011           0 :         struct vbdev_ocf *vbdev = priv;
    1012           0 :         uint64_t mem_needed;
    1013             : 
    1014           0 :         ocf_mngt_cache_unlock(cache);
    1015             : 
    1016           0 :         if (error) {
    1017           0 :                 SPDK_ERRLOG("Error %d during start cache %s, starting rollback\n",
    1018             :                             error, vbdev->name);
    1019             : 
    1020           0 :                 if (error == -OCF_ERR_NO_MEM) {
    1021           0 :                         ocf_mngt_get_ram_needed(cache, &vbdev->cfg.attach.device, &mem_needed);
    1022             : 
    1023           0 :                         SPDK_NOTICELOG("Try to increase hugepage memory size or cache line size. "
    1024             :                                        "For your configuration:\nDevice size: %"PRIu64" bytes\n"
    1025             :                                        "Cache line size: %"PRIu64" bytes\nFree memory needed to start "
    1026             :                                        "cache: %"PRIu64" bytes\n", vbdev->cache.bdev->blockcnt *
    1027             :                                        vbdev->cache.bdev->blocklen, vbdev->cfg.cache.cache_line_size,
    1028             :                                        mem_needed);
    1029             :                 }
    1030             : 
    1031           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, error);
    1032           0 :                 return;
    1033             :         }
    1034             : 
    1035           0 :         vbdev_ocf_mngt_continue(vbdev, error);
    1036             : }
    1037             : 
    1038             : static int
    1039           0 : create_management_queue(struct vbdev_ocf *vbdev)
    1040             : {
    1041             :         struct spdk_poller *mngt_poller;
    1042             :         int rc;
    1043             : 
    1044           0 :         rc = vbdev_ocf_queue_create(vbdev->ocf_cache, &vbdev->cache_ctx->mngt_queue, &mngt_queue_ops);
    1045           0 :         if (rc) {
    1046           0 :                 SPDK_ERRLOG("Unable to create mngt_queue: %d\n", rc);
    1047           0 :                 return rc;
    1048             :         }
    1049             : 
    1050           0 :         mngt_poller = SPDK_POLLER_REGISTER(mngt_queue_poll, vbdev->cache_ctx->mngt_queue, 100);
    1051           0 :         if (mngt_poller == NULL) {
    1052           0 :                 SPDK_ERRLOG("Unable to initiate mngt request: %s", spdk_strerror(ENOMEM));
    1053           0 :                 return -ENOMEM;
    1054             :         }
    1055             : 
    1056           0 :         ocf_queue_set_priv(vbdev->cache_ctx->mngt_queue, mngt_poller);
    1057           0 :         ocf_mngt_cache_set_mngt_queue(vbdev->ocf_cache, vbdev->cache_ctx->mngt_queue);
    1058             : 
    1059           0 :         return 0;
    1060             : }
    1061             : 
    1062             : /* Start OCF cache, attach caching device */
    1063             : static void
    1064           0 : start_cache(struct vbdev_ocf *vbdev)
    1065             : {
    1066             :         ocf_cache_t existing;
    1067           0 :         uint32_t cache_block_size = vbdev->cache.bdev->blocklen;
    1068           0 :         uint32_t core_block_size = vbdev->core.bdev->blocklen;
    1069             :         int rc;
    1070             : 
    1071           0 :         if (is_ocf_cache_running(vbdev)) {
    1072           0 :                 vbdev_ocf_mngt_stop(vbdev, NULL, -EALREADY);
    1073           0 :                 return;
    1074             :         }
    1075             : 
    1076           0 :         if (cache_block_size > core_block_size) {
    1077           0 :                 SPDK_ERRLOG("Cache bdev block size (%d) is bigger then core bdev block size (%d)\n",
    1078             :                             cache_block_size, core_block_size);
    1079           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, -EINVAL);
    1080           0 :                 return;
    1081             :         }
    1082             : 
    1083           0 :         existing = get_other_cache_instance(vbdev);
    1084           0 :         if (existing) {
    1085           0 :                 SPDK_NOTICELOG("OCF bdev %s connects to existing cache device %s\n",
    1086             :                                vbdev->name, vbdev->cache.name);
    1087           0 :                 vbdev->ocf_cache = existing;
    1088           0 :                 ocf_mngt_cache_get(vbdev->ocf_cache);
    1089           0 :                 vbdev->cache_ctx = ocf_cache_get_priv(existing);
    1090           0 :                 vbdev_ocf_cache_ctx_get(vbdev->cache_ctx);
    1091           0 :                 vbdev_ocf_mngt_continue(vbdev, 0);
    1092           0 :                 return;
    1093             :         }
    1094             : 
    1095           0 :         vbdev->cache_ctx = calloc(1, sizeof(struct vbdev_ocf_cache_ctx));
    1096           0 :         if (vbdev->cache_ctx == NULL) {
    1097           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, -ENOMEM);
    1098           0 :                 return;
    1099             :         }
    1100             : 
    1101           0 :         vbdev_ocf_cache_ctx_get(vbdev->cache_ctx);
    1102           0 :         pthread_mutex_init(&vbdev->cache_ctx->lock, NULL);
    1103             : 
    1104           0 :         rc = ocf_mngt_cache_start(vbdev_ocf_ctx, &vbdev->ocf_cache, &vbdev->cfg.cache, NULL);
    1105           0 :         if (rc) {
    1106           0 :                 SPDK_ERRLOG("Could not start cache %s: %d\n", vbdev->name, rc);
    1107           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, rc);
    1108           0 :                 return;
    1109             :         }
    1110           0 :         ocf_mngt_cache_get(vbdev->ocf_cache);
    1111             : 
    1112           0 :         ocf_cache_set_priv(vbdev->ocf_cache, vbdev->cache_ctx);
    1113             : 
    1114           0 :         rc = create_management_queue(vbdev);
    1115           0 :         if (rc) {
    1116           0 :                 SPDK_ERRLOG("Unable to create mngt_queue: %d\n", rc);
    1117           0 :                 vbdev_ocf_mngt_exit(vbdev, unregister_path_dirty, rc);
    1118           0 :                 return;
    1119             :         }
    1120             : 
    1121           0 :         if (vbdev->cfg.loadq) {
    1122           0 :                 ocf_mngt_cache_load(vbdev->ocf_cache, &vbdev->cfg.attach, start_cache_cmpl, vbdev);
    1123             :         } else {
    1124           0 :                 ocf_mngt_cache_attach(vbdev->ocf_cache, &vbdev->cfg.attach, start_cache_cmpl, vbdev);
    1125             :         }
    1126             : }
    1127             : 
    1128             : /* Procedures called during register operation */
    1129             : vbdev_ocf_mngt_fn register_path[] = {
    1130             :         start_cache,
    1131             :         add_core,
    1132             :         finish_register,
    1133             :         NULL
    1134             : };
    1135             : 
    1136             : /* Start cache instance and register OCF bdev */
    1137             : static void
    1138           0 : register_vbdev(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_callback cb, void *cb_arg)
    1139             : {
    1140             :         int rc;
    1141             : 
    1142           0 :         if (!(vbdev->core.attached && vbdev->cache.attached) || vbdev->state.started) {
    1143           0 :                 cb(-EPERM, vbdev, cb_arg);
    1144           0 :                 return;
    1145             :         }
    1146             : 
    1147           0 :         vbdev->state.starting = true;
    1148           0 :         rc = vbdev_ocf_mngt_start(vbdev, register_path, cb, cb_arg);
    1149           0 :         if (rc) {
    1150           0 :                 cb(rc, vbdev, cb_arg);
    1151             :         }
    1152             : }
    1153             : 
    1154             : /* Init OCF configuration options
    1155             :  * for core and cache devices */
    1156             : static int
    1157           0 : init_vbdev_config(struct vbdev_ocf *vbdev)
    1158             : {
    1159           0 :         struct vbdev_ocf_config *cfg = &vbdev->cfg;
    1160           0 :         struct ocf_volume_uuid uuid;
    1161             :         ocf_volume_type_t type;
    1162             :         int ret;
    1163             : 
    1164             : 
    1165             :         /* Initialize OCF defaults first */
    1166           0 :         ocf_mngt_cache_attach_config_set_default(&cfg->attach);
    1167           0 :         ocf_mngt_cache_config_set_default(&cfg->cache);
    1168           0 :         ocf_mngt_core_config_set_default(&cfg->core);
    1169             : 
    1170           0 :         ret = snprintf(cfg->cache.name, sizeof(cfg->cache.name), "%s", vbdev->name);
    1171           0 :         if (ret < 0 || (size_t) ret >= sizeof(cfg->cache.name)) {
    1172           0 :                 return -EINVAL;
    1173             :         }
    1174           0 :         ret = snprintf(cfg->core.name, sizeof(cfg->core.name), "%s", vbdev->core.name);
    1175           0 :         if (ret < 0 || (size_t) ret >= sizeof(cfg->core.name)) {
    1176           0 :                 return -EINVAL;
    1177             :         }
    1178             : 
    1179           0 :         cfg->attach.open_cores = false;
    1180           0 :         cfg->attach.device.perform_test = false;
    1181           0 :         cfg->attach.discard_on_start = false;
    1182             : 
    1183           0 :         vbdev->cfg.cache.locked = true;
    1184             : 
    1185           0 :         cfg->core.volume_type = SPDK_OBJECT;
    1186             : 
    1187           0 :         if (vbdev->cfg.loadq) {
    1188             :                 /* When doing cache_load(), we need to set try_add to true,
    1189             :                  * otherwise OCF will interpret this core as new
    1190             :                  * instead of the inactive one */
    1191           0 :                 vbdev->cfg.core.try_add = true;
    1192             :         } else {
    1193             :                 /* When cache is initialized as new, set force flag to true,
    1194             :                  * to ignore warnings about existing metadata */
    1195           0 :                 cfg->attach.force = true;
    1196             :         }
    1197             : 
    1198             :         /* Serialize bdev names in OCF UUID to interpret on future loads
    1199             :          * Core UUID is a triple of (core name, vbdev name, cache name)
    1200             :          * Cache UUID is cache bdev name */
    1201           0 :         type = ocf_ctx_get_volume_type(vbdev_ocf_ctx, SPDK_OBJECT);
    1202           0 :         if (!type) {
    1203           0 :                 SPDK_ERRLOG("Fail to get volume type\n");
    1204           0 :                 return -EINVAL;
    1205             :         }
    1206           0 :         uuid.size = strlen(vbdev->cache.name) + 1;
    1207           0 :         uuid.data = vbdev->cache.name;
    1208           0 :         ret = ocf_volume_create(&cfg->attach.device.volume, type, &uuid);
    1209           0 :         if (ret) {
    1210           0 :                 SPDK_ERRLOG("Fail to create volume\n");
    1211           0 :                 return -EINVAL;
    1212             :         }
    1213             : 
    1214           0 :         snprintf(vbdev->uuid, VBDEV_OCF_MD_MAX_LEN, "%s %s %s",
    1215             :                  vbdev->core.name, vbdev->name, vbdev->cache.name);
    1216           0 :         cfg->core.uuid.size = strlen(vbdev->uuid) + 1;
    1217           0 :         cfg->core.uuid.data = vbdev->uuid;
    1218           0 :         vbdev->uuid[strlen(vbdev->core.name)] = 0;
    1219           0 :         vbdev->uuid[strlen(vbdev->core.name) + 1 + strlen(vbdev->name)] = 0;
    1220             : 
    1221           0 :         return 0;
    1222             : }
    1223             : 
    1224             : /* Allocate vbdev structure object and add it to the global list */
    1225             : static int
    1226           0 : init_vbdev(const char *vbdev_name,
    1227             :            const char *cache_mode_name,
    1228             :            const uint64_t cache_line_size,
    1229             :            const char *cache_name,
    1230             :            const char *core_name,
    1231             :            bool loadq)
    1232             : {
    1233             :         struct vbdev_ocf *vbdev;
    1234           0 :         int rc = 0;
    1235             : 
    1236           0 :         if (spdk_bdev_get_by_name(vbdev_name) || vbdev_ocf_get_by_name(vbdev_name)) {
    1237           0 :                 SPDK_ERRLOG("Device with name '%s' already exists\n", vbdev_name);
    1238           0 :                 return -EPERM;
    1239             :         }
    1240             : 
    1241           0 :         vbdev = calloc(1, sizeof(*vbdev));
    1242           0 :         if (!vbdev) {
    1243           0 :                 goto error_mem;
    1244             :         }
    1245             : 
    1246           0 :         vbdev->name = strdup(vbdev_name);
    1247           0 :         if (!vbdev->name) {
    1248           0 :                 goto error_mem;
    1249             :         }
    1250             : 
    1251           0 :         vbdev->cache.name = strdup(cache_name);
    1252           0 :         if (!vbdev->cache.name) {
    1253           0 :                 goto error_mem;
    1254             :         }
    1255             : 
    1256           0 :         vbdev->core.name = strdup(core_name);
    1257           0 :         if (!vbdev->core.name) {
    1258           0 :                 goto error_mem;
    1259             :         }
    1260             : 
    1261           0 :         vbdev->cache.parent = vbdev;
    1262           0 :         vbdev->core.parent = vbdev;
    1263           0 :         vbdev->cache.is_cache = true;
    1264           0 :         vbdev->core.is_cache = false;
    1265           0 :         vbdev->cfg.loadq = loadq;
    1266             : 
    1267           0 :         rc = init_vbdev_config(vbdev);
    1268           0 :         if (rc) {
    1269           0 :                 SPDK_ERRLOG("Fail to init vbdev config\n");
    1270           0 :                 goto error_free;
    1271             :         }
    1272             : 
    1273             : 
    1274           0 :         if (cache_mode_name) {
    1275             :                 vbdev->cfg.cache.cache_mode
    1276           0 :                         = ocf_get_cache_mode(cache_mode_name);
    1277           0 :         } else if (!loadq) { /* In load path it is OK to pass NULL as cache mode */
    1278           0 :                 SPDK_ERRLOG("No cache mode specified\n");
    1279           0 :                 rc = -EINVAL;
    1280           0 :                 goto error_free;
    1281             :         }
    1282           0 :         if (vbdev->cfg.cache.cache_mode < 0) {
    1283           0 :                 SPDK_ERRLOG("Incorrect cache mode '%s'\n", cache_mode_name);
    1284           0 :                 rc = -EINVAL;
    1285           0 :                 goto error_free;
    1286             :         }
    1287             : 
    1288           0 :         ocf_cache_line_size_t set_cache_line_size = cache_line_size ?
    1289           0 :                         (ocf_cache_line_size_t)cache_line_size * KiB :
    1290             :                         ocf_cache_line_size_default;
    1291           0 :         if (set_cache_line_size == 0) {
    1292           0 :                 SPDK_ERRLOG("Cache line size should be non-zero.\n");
    1293           0 :                 rc = -EINVAL;
    1294           0 :                 goto error_free;
    1295             :         }
    1296           0 :         vbdev->cfg.attach.cache_line_size = set_cache_line_size;
    1297           0 :         vbdev->cfg.cache.cache_line_size = set_cache_line_size;
    1298             : 
    1299           0 :         TAILQ_INSERT_TAIL(&g_ocf_vbdev_head, vbdev, tailq);
    1300           0 :         return rc;
    1301             : 
    1302           0 : error_mem:
    1303           0 :         rc = -ENOMEM;
    1304           0 : error_free:
    1305           0 :         free_vbdev(vbdev);
    1306           0 :         return rc;
    1307             : }
    1308             : 
    1309             : /* Read configuration file at the start of SPDK application
    1310             :  * This adds vbdevs to global list if some mentioned in config */
    1311             : static int
    1312           0 : vbdev_ocf_init(void)
    1313             : {
    1314             :         int status;
    1315             : 
    1316           0 :         status = vbdev_ocf_ctx_init();
    1317           0 :         if (status) {
    1318           0 :                 SPDK_ERRLOG("OCF ctx initialization failed with=%d\n", status);
    1319           0 :                 return status;
    1320             :         }
    1321             : 
    1322           0 :         status = vbdev_ocf_volume_init();
    1323           0 :         if (status) {
    1324           0 :                 vbdev_ocf_ctx_cleanup();
    1325           0 :                 SPDK_ERRLOG("OCF volume initialization failed with=%d\n", status);
    1326           0 :                 return status;
    1327             :         }
    1328             : 
    1329           0 :         return status;
    1330             : }
    1331             : 
    1332             : /* Called after application shutdown started
    1333             :  * Release memory of allocated structures here */
    1334             : static void
    1335           0 : vbdev_ocf_module_fini(void)
    1336             : {
    1337             :         struct vbdev_ocf *vbdev;
    1338             : 
    1339           0 :         while ((vbdev = TAILQ_FIRST(&g_ocf_vbdev_head))) {
    1340           0 :                 TAILQ_REMOVE(&g_ocf_vbdev_head, vbdev, tailq);
    1341           0 :                 free_vbdev(vbdev);
    1342             :         }
    1343             : 
    1344           0 :         vbdev_ocf_volume_cleanup();
    1345           0 :         vbdev_ocf_ctx_cleanup();
    1346           0 : }
    1347             : 
    1348             : /* When base device gets unplugged this is called
    1349             :  * We will unregister cache vbdev here
    1350             :  * When cache device is removed, we delete every OCF bdev that used it */
    1351             : static void
    1352           0 : hotremove_cb(struct vbdev_ocf_base *base)
    1353             : {
    1354             :         struct vbdev_ocf *vbdev;
    1355             : 
    1356           0 :         if (!base->is_cache) {
    1357           0 :                 if (base->parent->state.doing_finish) {
    1358           0 :                         return;
    1359             :                 }
    1360             : 
    1361           0 :                 SPDK_NOTICELOG("Deinitializing '%s' because its core device '%s' was removed\n",
    1362             :                                base->parent->name, base->name);
    1363           0 :                 vbdev_ocf_delete(base->parent, NULL, NULL);
    1364           0 :                 return;
    1365             :         }
    1366             : 
    1367           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
    1368           0 :                 if (vbdev->state.doing_finish) {
    1369           0 :                         continue;
    1370             :                 }
    1371           0 :                 if (strcmp(base->name, vbdev->cache.name) == 0) {
    1372           0 :                         SPDK_NOTICELOG("Deinitializing '%s' because"
    1373             :                                        " its cache device '%s' was removed\n",
    1374             :                                        vbdev->name, base->name);
    1375           0 :                         vbdev_ocf_delete(vbdev, NULL, NULL);
    1376             :                 }
    1377             :         }
    1378             : }
    1379             : 
    1380             : static void
    1381           0 : base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
    1382             :                    void *event_ctx)
    1383             : {
    1384           0 :         switch (type) {
    1385           0 :         case SPDK_BDEV_EVENT_REMOVE:
    1386           0 :                 if (event_ctx) {
    1387           0 :                         hotremove_cb(event_ctx);
    1388             :                 }
    1389           0 :                 break;
    1390           0 :         default:
    1391           0 :                 SPDK_NOTICELOG("Unsupported bdev event: type %d\n", type);
    1392           0 :                 break;
    1393             :         }
    1394           0 : }
    1395             : 
    1396             : /* Open base SPDK bdev and claim it */
    1397             : static int
    1398           0 : attach_base(struct vbdev_ocf_base *base)
    1399             : {
    1400             :         int status;
    1401             : 
    1402           0 :         if (base->attached) {
    1403           0 :                 return -EALREADY;
    1404             :         }
    1405             : 
    1406             :         /* If base cache bdev was already opened by other vbdev,
    1407             :          * we just copy its descriptor here */
    1408           0 :         if (base->is_cache) {
    1409           0 :                 struct vbdev_ocf_base *existing = get_other_cache_base(base);
    1410           0 :                 if (existing) {
    1411           0 :                         base->desc = existing->desc;
    1412           0 :                         base->management_channel = existing->management_channel;
    1413           0 :                         base->attached = true;
    1414           0 :                         return 0;
    1415             :                 }
    1416             :         }
    1417             : 
    1418           0 :         status = spdk_bdev_open_ext(base->name, true, base_bdev_event_cb, base, &base->desc);
    1419           0 :         if (status) {
    1420           0 :                 SPDK_ERRLOG("Unable to open device '%s' for writing\n", base->name);
    1421           0 :                 return status;
    1422             :         }
    1423             : 
    1424           0 :         status = spdk_bdev_module_claim_bdev(base->bdev, base->desc,
    1425             :                                              &ocf_if);
    1426           0 :         if (status) {
    1427           0 :                 SPDK_ERRLOG("Unable to claim device '%s'\n", base->name);
    1428           0 :                 spdk_bdev_close(base->desc);
    1429           0 :                 return status;
    1430             :         }
    1431             : 
    1432           0 :         base->management_channel = spdk_bdev_get_io_channel(base->desc);
    1433           0 :         if (!base->management_channel) {
    1434           0 :                 SPDK_ERRLOG("Unable to get io channel '%s'\n", base->name);
    1435           0 :                 spdk_bdev_module_release_bdev(base->bdev);
    1436           0 :                 spdk_bdev_close(base->desc);
    1437           0 :                 return -ENOMEM;
    1438             :         }
    1439             : 
    1440             :         /* Save the thread where the base device is opened */
    1441           0 :         base->thread = spdk_get_thread();
    1442             : 
    1443           0 :         base->attached = true;
    1444           0 :         return status;
    1445             : }
    1446             : 
    1447             : /* Attach base bdevs */
    1448             : static int
    1449           0 : attach_base_bdevs(struct vbdev_ocf *vbdev,
    1450             :                   struct spdk_bdev *cache_bdev,
    1451             :                   struct spdk_bdev *core_bdev)
    1452             : {
    1453           0 :         int rc = 0;
    1454             : 
    1455           0 :         if (cache_bdev) {
    1456           0 :                 vbdev->cache.bdev = cache_bdev;
    1457           0 :                 rc |= attach_base(&vbdev->cache);
    1458             :         }
    1459             : 
    1460           0 :         if (core_bdev) {
    1461           0 :                 vbdev->core.bdev = core_bdev;
    1462           0 :                 rc |= attach_base(&vbdev->core);
    1463             :         }
    1464             : 
    1465           0 :         return rc;
    1466             : }
    1467             : 
    1468             : /* Init and then start vbdev if all base devices are present */
    1469             : void
    1470           0 : vbdev_ocf_construct(const char *vbdev_name,
    1471             :                     const char *cache_mode_name,
    1472             :                     const uint64_t cache_line_size,
    1473             :                     const char *cache_name,
    1474             :                     const char *core_name,
    1475             :                     bool loadq,
    1476             :                     void (*cb)(int, struct vbdev_ocf *, void *),
    1477             :                     void *cb_arg)
    1478             : {
    1479             :         int rc;
    1480           0 :         struct spdk_bdev *cache_bdev = spdk_bdev_get_by_name(cache_name);
    1481           0 :         struct spdk_bdev *core_bdev = spdk_bdev_get_by_name(core_name);
    1482             :         struct vbdev_ocf *vbdev;
    1483             : 
    1484           0 :         rc = init_vbdev(vbdev_name, cache_mode_name, cache_line_size, cache_name, core_name, loadq);
    1485           0 :         if (rc) {
    1486           0 :                 cb(rc, NULL, cb_arg);
    1487           0 :                 return;
    1488             :         }
    1489             : 
    1490           0 :         vbdev = vbdev_ocf_get_by_name(vbdev_name);
    1491           0 :         if (vbdev == NULL) {
    1492           0 :                 cb(-ENODEV, NULL, cb_arg);
    1493           0 :                 return;
    1494             :         }
    1495             : 
    1496           0 :         if (cache_bdev == NULL) {
    1497           0 :                 SPDK_NOTICELOG("OCF bdev '%s' is waiting for cache device '%s' to connect\n",
    1498             :                                vbdev->name, cache_name);
    1499             :         }
    1500           0 :         if (core_bdev == NULL) {
    1501           0 :                 SPDK_NOTICELOG("OCF bdev '%s' is waiting for core device '%s' to connect\n",
    1502             :                                vbdev->name, core_name);
    1503             :         }
    1504             : 
    1505           0 :         rc = attach_base_bdevs(vbdev, cache_bdev, core_bdev);
    1506           0 :         if (rc) {
    1507           0 :                 cb(rc, vbdev, cb_arg);
    1508           0 :                 return;
    1509             :         }
    1510             : 
    1511           0 :         if (core_bdev && cache_bdev) {
    1512           0 :                 register_vbdev(vbdev, cb, cb_arg);
    1513             :         } else {
    1514           0 :                 cb(0, vbdev, cb_arg);
    1515             :         }
    1516             : }
    1517             : 
    1518             : /* Set new cache mode on OCF cache */
    1519             : void
    1520           0 : vbdev_ocf_set_cache_mode(struct vbdev_ocf *vbdev,
    1521             :                          const char *cache_mode_name,
    1522             :                          void (*cb)(int, struct vbdev_ocf *, void *),
    1523             :                          void *cb_arg)
    1524             : {
    1525             :         ocf_cache_t cache;
    1526             :         ocf_cache_mode_t cache_mode;
    1527             :         int rc;
    1528             : 
    1529           0 :         cache = vbdev->ocf_cache;
    1530           0 :         cache_mode = ocf_get_cache_mode(cache_mode_name);
    1531             : 
    1532           0 :         rc = ocf_mngt_cache_trylock(cache);
    1533           0 :         if (rc) {
    1534           0 :                 cb(rc, vbdev, cb_arg);
    1535           0 :                 return;
    1536             :         }
    1537             : 
    1538           0 :         rc = ocf_mngt_cache_set_mode(cache, cache_mode);
    1539           0 :         ocf_mngt_cache_unlock(cache);
    1540           0 :         cb(rc, vbdev, cb_arg);
    1541             : }
    1542             : 
    1543             : /* Set sequential cutoff parameters on OCF cache */
    1544             : void
    1545           0 : vbdev_ocf_set_seqcutoff(struct vbdev_ocf *vbdev, const char *policy_name, uint32_t threshold,
    1546             :                         uint32_t promotion_count, void (*cb)(int, void *), void *cb_arg)
    1547             : {
    1548             :         ocf_cache_t cache;
    1549             :         ocf_seq_cutoff_policy policy;
    1550             :         int rc;
    1551             : 
    1552           0 :         cache = vbdev->ocf_cache;
    1553             : 
    1554           0 :         policy = ocf_get_seqcutoff_policy(policy_name);
    1555           0 :         if (policy == ocf_seq_cutoff_policy_max) {
    1556           0 :                 cb(OCF_ERR_INVAL, cb_arg);
    1557           0 :                 return;
    1558             :         }
    1559             : 
    1560           0 :         rc = ocf_mngt_cache_trylock(cache);
    1561           0 :         if (rc) {
    1562           0 :                 cb(rc, cb_arg);
    1563           0 :                 return;
    1564             :         }
    1565             : 
    1566           0 :         rc = ocf_mngt_core_set_seq_cutoff_policy_all(cache, policy);
    1567           0 :         if (rc) {
    1568           0 :                 goto end;
    1569             :         }
    1570             : 
    1571           0 :         if (threshold) {
    1572           0 :                 threshold = threshold * KiB;
    1573             : 
    1574           0 :                 rc = ocf_mngt_core_set_seq_cutoff_threshold_all(cache, threshold);
    1575           0 :                 if (rc) {
    1576           0 :                         goto end;
    1577             :                 }
    1578             :         }
    1579             : 
    1580           0 :         if (promotion_count) {
    1581           0 :                 rc = ocf_mngt_core_set_seq_cutoff_promotion_count_all(cache, promotion_count);
    1582             :         }
    1583             : 
    1584           0 : end:
    1585           0 :         ocf_mngt_cache_unlock(cache);
    1586           0 :         cb(rc, cb_arg);
    1587             : }
    1588             : 
    1589             : /* This called if new device is created in SPDK application
    1590             :  * If that device named as one of base bdevs of OCF vbdev,
    1591             :  * claim and open them */
    1592             : static void
    1593           0 : vbdev_ocf_examine(struct spdk_bdev *bdev)
    1594             : {
    1595           0 :         const char *bdev_name = spdk_bdev_get_name(bdev);
    1596             :         struct vbdev_ocf *vbdev;
    1597             : 
    1598           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
    1599           0 :                 if (vbdev->state.doing_finish) {
    1600           0 :                         continue;
    1601             :                 }
    1602             : 
    1603           0 :                 if (!strcmp(bdev_name, vbdev->cache.name)) {
    1604           0 :                         attach_base_bdevs(vbdev, bdev, NULL);
    1605           0 :                         continue;
    1606             :                 }
    1607           0 :                 if (!strcmp(bdev_name, vbdev->core.name)) {
    1608           0 :                         attach_base_bdevs(vbdev, NULL, bdev);
    1609           0 :                         break;
    1610             :                 }
    1611             :         }
    1612           0 :         spdk_bdev_module_examine_done(&ocf_if);
    1613           0 : }
    1614             : 
    1615             : struct metadata_probe_ctx {
    1616             :         struct vbdev_ocf_base base;
    1617             :         ocf_volume_t volume;
    1618             : 
    1619             :         struct ocf_volume_uuid *core_uuids;
    1620             :         unsigned int uuid_count;
    1621             : 
    1622             :         int result;
    1623             :         int refcnt;
    1624             : };
    1625             : 
    1626             : static void
    1627           0 : _examine_ctx_put(void *ctx)
    1628             : {
    1629           0 :         struct spdk_bdev_desc *desc = ctx;
    1630             : 
    1631           0 :         spdk_bdev_close(desc);
    1632           0 : }
    1633             : 
    1634             : static void
    1635           0 : examine_ctx_put(struct metadata_probe_ctx *ctx)
    1636             : {
    1637             :         unsigned int i;
    1638             : 
    1639           0 :         ctx->refcnt--;
    1640           0 :         if (ctx->refcnt > 0) {
    1641           0 :                 return;
    1642             :         }
    1643             : 
    1644           0 :         if (ctx->result) {
    1645           0 :                 SPDK_ERRLOG("OCF metadata probe for bdev '%s' failed with %d\n",
    1646             :                             spdk_bdev_get_name(ctx->base.bdev), ctx->result);
    1647             :         }
    1648             : 
    1649           0 :         if (ctx->base.desc) {
    1650             :                 /* Close the underlying bdev on its same opened thread. */
    1651           0 :                 if (ctx->base.thread && ctx->base.thread != spdk_get_thread()) {
    1652           0 :                         spdk_thread_send_msg(ctx->base.thread, _examine_ctx_put, ctx->base.desc);
    1653             :                 } else {
    1654           0 :                         spdk_bdev_close(ctx->base.desc);
    1655             :                 }
    1656             :         }
    1657             : 
    1658           0 :         if (ctx->volume) {
    1659           0 :                 ocf_volume_destroy(ctx->volume);
    1660             :         }
    1661             : 
    1662           0 :         if (ctx->core_uuids) {
    1663           0 :                 for (i = 0; i < ctx->uuid_count; i++) {
    1664           0 :                         free(ctx->core_uuids[i].data);
    1665             :                 }
    1666             :         }
    1667           0 :         free(ctx->core_uuids);
    1668             : 
    1669           0 :         examine_done(ctx->result, NULL, ctx->base.bdev);
    1670           0 :         free(ctx);
    1671             : }
    1672             : 
    1673             : static void
    1674           0 : metadata_probe_cb(void *priv, int rc,
    1675             :                   struct ocf_metadata_probe_status *status)
    1676             : {
    1677           0 :         struct metadata_probe_ctx *ctx = priv;
    1678             : 
    1679           0 :         if (rc) {
    1680             :                 /* -ENODATA means device does not have cache metadata on it */
    1681           0 :                 if (rc != -OCF_ERR_NO_METADATA) {
    1682           0 :                         ctx->result = rc;
    1683             :                 }
    1684             :         }
    1685             : 
    1686           0 :         examine_ctx_put(ctx);
    1687           0 : }
    1688             : 
    1689             : /* This is called after vbdev_ocf_examine
    1690             :  * It allows to delay application initialization
    1691             :  * until all OCF bdevs get registered
    1692             :  * If vbdev has all of its base devices it starts asynchronously here
    1693             :  * We first check if bdev appears in configuration,
    1694             :  * if not we do metadata_probe() to create its configuration from bdev metadata */
    1695             : static void
    1696           0 : vbdev_ocf_examine_disk(struct spdk_bdev *bdev)
    1697             : {
    1698           0 :         const char *bdev_name = spdk_bdev_get_name(bdev);
    1699             :         struct vbdev_ocf *vbdev;
    1700             :         struct metadata_probe_ctx *ctx;
    1701           0 :         bool created_from_config = false;
    1702             :         int rc;
    1703             : 
    1704           0 :         examine_start(bdev);
    1705             : 
    1706           0 :         TAILQ_FOREACH(vbdev, &g_ocf_vbdev_head, tailq) {
    1707           0 :                 if (vbdev->state.doing_finish || vbdev->state.started) {
    1708           0 :                         continue;
    1709             :                 }
    1710             : 
    1711           0 :                 if (!strcmp(bdev_name, vbdev->cache.name)) {
    1712           0 :                         examine_start(bdev);
    1713           0 :                         register_vbdev(vbdev, examine_done, bdev);
    1714           0 :                         created_from_config = true;
    1715           0 :                         continue;
    1716             :                 }
    1717           0 :                 if (!strcmp(bdev_name, vbdev->core.name)) {
    1718           0 :                         examine_start(bdev);
    1719           0 :                         register_vbdev(vbdev, examine_done, bdev);
    1720           0 :                         examine_done(0, NULL, bdev);
    1721           0 :                         return;
    1722             :                 }
    1723             :         }
    1724             : 
    1725             :         /* If devices is discovered during config we do not check for metadata */
    1726           0 :         if (created_from_config) {
    1727           0 :                 examine_done(0, NULL, bdev);
    1728           0 :                 return;
    1729             :         }
    1730             : 
    1731             :         /* Metadata probe path
    1732             :          * We create temporary OCF volume and a temporary base structure
    1733             :          * to use them for ocf_metadata_probe() and for bottom adapter IOs
    1734             :          * Then we get UUIDs of core devices an create configurations based on them */
    1735           0 :         ctx = calloc(1, sizeof(*ctx));
    1736           0 :         if (!ctx) {
    1737           0 :                 examine_done(-ENOMEM, NULL, bdev);
    1738           0 :                 return;
    1739             :         }
    1740             : 
    1741           0 :         ctx->base.bdev = bdev;
    1742           0 :         ctx->refcnt = 1;
    1743             : 
    1744           0 :         rc = spdk_bdev_open_ext(bdev_name, true, base_bdev_event_cb, NULL, &ctx->base.desc);
    1745           0 :         if (rc) {
    1746           0 :                 ctx->result = rc;
    1747           0 :                 examine_ctx_put(ctx);
    1748           0 :                 return;
    1749             :         }
    1750             : 
    1751           0 :         rc = ocf_ctx_volume_create(vbdev_ocf_ctx, &ctx->volume, NULL, SPDK_OBJECT);
    1752           0 :         if (rc) {
    1753           0 :                 ctx->result = rc;
    1754           0 :                 examine_ctx_put(ctx);
    1755           0 :                 return;
    1756             :         }
    1757             : 
    1758           0 :         rc = ocf_volume_open(ctx->volume, &ctx->base);
    1759           0 :         if (rc) {
    1760           0 :                 ctx->result = rc;
    1761           0 :                 examine_ctx_put(ctx);
    1762           0 :                 return;
    1763             :         }
    1764             : 
    1765             :         /* Save the thread where the base device is opened */
    1766           0 :         ctx->base.thread = spdk_get_thread();
    1767             : 
    1768           0 :         ocf_metadata_probe(vbdev_ocf_ctx, ctx->volume, metadata_probe_cb, ctx);
    1769             : }
    1770             : 
    1771             : static int
    1772           0 : vbdev_ocf_get_ctx_size(void)
    1773             : {
    1774           0 :         return sizeof(struct bdev_ocf_data);
    1775             : }
    1776             : 
    1777             : static void
    1778           0 : fini_start(void)
    1779             : {
    1780           0 :         g_fini_started = true;
    1781           0 : }
    1782             : 
    1783             : /* Module-global function table
    1784             :  * Does not relate to vbdev instances */
    1785             : static struct spdk_bdev_module ocf_if = {
    1786             :         .name = "ocf",
    1787             :         .module_init = vbdev_ocf_init,
    1788             :         .fini_start = fini_start,
    1789             :         .module_fini = vbdev_ocf_module_fini,
    1790             :         .get_ctx_size = vbdev_ocf_get_ctx_size,
    1791             :         .examine_config = vbdev_ocf_examine,
    1792             :         .examine_disk   = vbdev_ocf_examine_disk,
    1793             : };
    1794           0 : SPDK_BDEV_MODULE_REGISTER(ocf, &ocf_if);

Generated by: LCOV version 1.15