LCOV - code coverage report
Current view: top level - spdk/module/bdev/raid - bdev_raid_sb.c (source / functions) Hit Total Coverage
Test: Combined Lines: 207 249 83.1 %
Date: 2024-11-18 12:18:03 Functions: 16 16 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 155 832 18.6 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2022 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/bdev_module.h"
       7                 :            : #include "spdk/crc32.h"
       8                 :            : #include "spdk/env.h"
       9                 :            : #include "spdk/log.h"
      10                 :            : #include "spdk/string.h"
      11                 :            : #include "spdk/util.h"
      12                 :            : 
      13                 :            : #include "bdev_raid.h"
      14                 :            : 
      15                 :            : struct raid_bdev_write_sb_ctx {
      16                 :            :         struct raid_bdev *raid_bdev;
      17                 :            :         int status;
      18                 :            :         uint8_t submitted;
      19                 :            :         uint8_t remaining;
      20                 :            :         raid_bdev_write_sb_cb cb;
      21                 :            :         void *cb_ctx;
      22                 :            :         struct spdk_bdev_io_wait_entry wait_entry;
      23                 :            : };
      24                 :            : 
      25                 :            : struct raid_bdev_read_sb_ctx {
      26                 :            :         struct spdk_bdev_desc *desc;
      27                 :            :         struct spdk_io_channel *ch;
      28                 :            :         raid_bdev_load_sb_cb cb;
      29                 :            :         void *cb_ctx;
      30                 :            :         void *buf;
      31                 :            :         uint32_t buf_size;
      32                 :            : };
      33                 :            : 
      34                 :            : int
      35                 :        127 : raid_bdev_alloc_superblock(struct raid_bdev *raid_bdev, uint32_t block_size)
      36                 :            : {
      37                 :            :         struct raid_bdev_superblock *sb;
      38                 :            : 
      39   [ +  +  #  #  :        127 :         assert(raid_bdev->sb == NULL);
             #  #  #  # ]
      40                 :            : 
      41                 :        127 :         sb = spdk_dma_zmalloc(SPDK_ALIGN_CEIL(RAID_BDEV_SB_MAX_LENGTH, block_size), 0x1000, NULL);
      42         [ +  + ]:        127 :         if (!sb) {
      43                 :          0 :                 SPDK_ERRLOG("Failed to allocate raid bdev sb buffer\n");
      44                 :          0 :                 return -ENOMEM;
      45                 :            :         }
      46                 :            : 
      47   [ #  #  #  # ]:        127 :         raid_bdev->sb = sb;
      48                 :            : 
      49                 :        127 :         return 0;
      50                 :          3 : }
      51                 :            : 
      52                 :            : void
      53                 :        398 : raid_bdev_free_superblock(struct raid_bdev *raid_bdev)
      54                 :            : {
      55   [ +  +  +  +  :        398 :         if (raid_bdev->sb_io_buf != NULL && raid_bdev->sb_io_buf != raid_bdev->sb) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      56   [ +  +  #  #  :         11 :                 assert(spdk_bdev_is_md_interleaved(&raid_bdev->bdev));
                   #  # ]
      57   [ #  #  #  # ]:         11 :                 spdk_dma_free(raid_bdev->sb_io_buf);
      58   [ #  #  #  # ]:         11 :                 raid_bdev->sb_io_buf = NULL;
      59                 :          1 :         }
      60   [ #  #  #  # ]:        398 :         spdk_dma_free(raid_bdev->sb);
      61   [ #  #  #  # ]:        398 :         raid_bdev->sb = NULL;
      62                 :        398 : }
      63                 :            : 
      64                 :            : void
      65                 :         78 : raid_bdev_init_superblock(struct raid_bdev *raid_bdev)
      66                 :            : {
      67   [ #  #  #  # ]:         78 :         struct raid_bdev_superblock *sb = raid_bdev->sb;
      68                 :            :         struct raid_base_bdev_info *base_info;
      69                 :            :         struct raid_bdev_sb_base_bdev *sb_base_bdev;
      70                 :            : 
      71   [ -  +  -  +  :         78 :         memcpy(&sb->signature, RAID_BDEV_SB_SIG, sizeof(sb->signature));
                   #  # ]
      72   [ #  #  #  #  :         78 :         sb->version.major = RAID_BDEV_SB_VERSION_MAJOR;
                   #  # ]
      73   [ #  #  #  #  :         78 :         sb->version.minor = RAID_BDEV_SB_VERSION_MINOR;
                   #  # ]
      74   [ #  #  #  #  :         78 :         spdk_uuid_copy(&sb->uuid, &raid_bdev->bdev.uuid);
                   #  # ]
      75   [ -  +  #  #  :         78 :         snprintf(sb->name, RAID_BDEV_SB_NAME_SIZE, "%s", raid_bdev->bdev.name);
             #  #  #  # ]
      76   [ #  #  #  #  :         78 :         sb->raid_size = raid_bdev->bdev.blockcnt;
          #  #  #  #  #  
                      # ]
      77   [ #  #  #  #  :         78 :         sb->block_size = spdk_bdev_get_data_block_size(&raid_bdev->bdev);
                   #  # ]
      78   [ #  #  #  #  :         78 :         sb->level = raid_bdev->level;
             #  #  #  # ]
      79   [ #  #  #  #  :         78 :         sb->strip_size = raid_bdev->strip_size;
             #  #  #  # ]
      80                 :            :         /* TODO: sb->state */
      81   [ #  #  #  #  :         78 :         sb->num_base_bdevs = sb->base_bdevs_size = raid_bdev->num_base_bdevs;
          #  #  #  #  #  
                #  #  # ]
      82   [ #  #  #  #  :         78 :         sb->length = sizeof(*sb) + sizeof(*sb_base_bdev) * sb->base_bdevs_size;
             #  #  #  # ]
      83                 :            : 
      84   [ #  #  #  # ]:         78 :         sb_base_bdev = &sb->base_bdevs[0];
      85   [ +  +  #  #  :        308 :         RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      86   [ #  #  #  # ]:        230 :                 spdk_uuid_copy(&sb_base_bdev->uuid, &base_info->uuid);
      87   [ #  #  #  #  :        230 :                 sb_base_bdev->data_offset = base_info->data_offset;
             #  #  #  # ]
      88   [ #  #  #  #  :        230 :                 sb_base_bdev->data_size = base_info->data_size;
             #  #  #  # ]
      89   [ #  #  #  # ]:        230 :                 sb_base_bdev->state = RAID_SB_BASE_BDEV_CONFIGURED;
      90   [ #  #  #  # ]:        230 :                 sb_base_bdev->slot = raid_bdev_base_bdev_slot(base_info);
      91         [ #  # ]:        230 :                 sb_base_bdev++;
      92                 :          9 :         }
      93                 :         78 : }
      94                 :            : 
      95                 :            : static int
      96                 :        131 : raid_bdev_alloc_sb_io_buf(struct raid_bdev *raid_bdev)
      97                 :            : {
      98   [ #  #  #  # ]:        131 :         struct raid_bdev_superblock *sb = raid_bdev->sb;
      99                 :            : 
     100   [ +  +  #  # ]:        131 :         if (spdk_bdev_is_md_interleaved(&raid_bdev->bdev)) {
     101   [ #  #  #  #  :         32 :                 raid_bdev->sb_io_buf_size = spdk_divide_round_up(sb->length,
             #  #  #  # ]
     102   [ #  #  #  #  :         30 :                                             sb->block_size) * raid_bdev->bdev.blocklen;
          #  #  #  #  #  
                #  #  # ]
     103   [ #  #  #  #  :         15 :                 raid_bdev->sb_io_buf = spdk_dma_zmalloc(raid_bdev->sb_io_buf_size, 0x1000, NULL);
             #  #  #  # ]
     104   [ -  +  #  #  :         15 :                 if (!raid_bdev->sb_io_buf) {
                   #  # ]
     105                 :          0 :                         SPDK_ERRLOG("Failed to allocate raid bdev sb io buffer\n");
     106                 :          0 :                         return -ENOMEM;
     107                 :            :                 }
     108                 :          2 :         } else {
     109   [ #  #  #  #  :        116 :                 raid_bdev->sb_io_buf_size = SPDK_ALIGN_CEIL(sb->length, raid_bdev->bdev.blocklen);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     110   [ #  #  #  #  :        116 :                 raid_bdev->sb_io_buf = raid_bdev->sb;
             #  #  #  # ]
     111                 :            :         }
     112                 :            : 
     113                 :        131 :         return 0;
     114                 :          6 : }
     115                 :            : 
     116                 :            : static void
     117                 :        588 : raid_bdev_sb_update_crc(struct raid_bdev_superblock *sb)
     118                 :            : {
     119   [ #  #  #  # ]:        588 :         sb->crc = 0;
     120   [ #  #  #  #  :        588 :         sb->crc = spdk_crc32c_update(sb, sb->length, 0);
             #  #  #  # ]
     121                 :        588 : }
     122                 :            : 
     123                 :            : static bool
     124                 :        297 : raid_bdev_sb_check_crc(struct raid_bdev_superblock *sb)
     125                 :            : {
     126   [ #  #  #  # ]:        297 :         uint32_t crc, prev = sb->crc;
     127                 :            : 
     128                 :        297 :         raid_bdev_sb_update_crc(sb);
     129   [ #  #  #  # ]:        297 :         crc = sb->crc;
     130   [ #  #  #  # ]:        297 :         sb->crc = prev;
     131                 :            : 
     132                 :        297 :         return crc == prev;
     133                 :            : }
     134                 :            : 
     135                 :            : static int
     136                 :       6972 : raid_bdev_parse_superblock(struct raid_bdev_read_sb_ctx *ctx)
     137                 :            : {
     138   [ +  -  +  - ]:       6972 :         struct raid_bdev_superblock *sb = ctx->buf;
     139   [ +  -  +  - ]:       6972 :         struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(ctx->desc);
     140                 :            :         struct raid_bdev_sb_base_bdev *sb_base_bdev;
     141                 :            :         uint8_t i;
     142                 :            : 
     143   [ +  +  +  +  :       6972 :         if (memcmp(sb->signature, RAID_BDEV_SB_SIG, sizeof(sb->signature))) {
             +  -  +  - ]
     144   [ +  +  +  +  :       6639 :                 SPDK_DEBUGLOG(bdev_raid_sb, "invalid signature\n");
                   +  - ]
     145                 :       6639 :                 return -EINVAL;
     146                 :            :         }
     147                 :            : 
     148   [ +  +  +  +  :        666 :         if (spdk_divide_round_up(sb->length, spdk_bdev_get_data_block_size(bdev)) >
                   #  # ]
     149   [ #  #  #  #  :        333 :             spdk_divide_round_up(ctx->buf_size, bdev->blocklen)) {
             #  #  #  # ]
     150   [ -  +  #  #  :         36 :                 if (sb->length > RAID_BDEV_SB_MAX_LENGTH) {
                   #  # ]
     151                 :          0 :                         SPDK_WARNLOG("Incorrect superblock length on bdev %s\n",
     152                 :            :                                      spdk_bdev_get_name(bdev));
     153                 :          0 :                         return -EINVAL;
     154                 :            :                 }
     155                 :            : 
     156                 :         36 :                 return -EAGAIN;
     157                 :            :         }
     158                 :            : 
     159         [ +  + ]:        297 :         if (!raid_bdev_sb_check_crc(sb)) {
     160                 :         36 :                 SPDK_WARNLOG("Incorrect superblock crc on bdev %s\n", spdk_bdev_get_name(bdev));
     161                 :         36 :                 return -EINVAL;
     162                 :            :         }
     163                 :            : 
     164   [ +  +  #  #  :        261 :         if (sb->version.major != RAID_BDEV_SB_VERSION_MAJOR) {
             #  #  #  # ]
     165   [ #  #  #  #  :         12 :                 SPDK_ERRLOG("Not supported superblock major version %d on bdev %s\n",
                   #  # ]
     166                 :            :                             sb->version.major, spdk_bdev_get_name(bdev));
     167                 :         12 :                 return -EINVAL;
     168                 :            :         }
     169                 :            : 
     170   [ +  +  #  #  :        249 :         if (sb->version.minor > RAID_BDEV_SB_VERSION_MINOR) {
             #  #  #  # ]
     171   [ #  #  #  #  :          0 :                 SPDK_WARNLOG("Superblock minor version %d on bdev %s is higher than the currently supported: %d\n",
                   #  # ]
     172                 :            :                              sb->version.minor, spdk_bdev_get_name(bdev), RAID_BDEV_SB_VERSION_MINOR);
     173                 :          0 :         }
     174                 :            : 
     175   [ +  +  #  #  :        816 :         for (i = 0; i < sb->base_bdevs_size; i++) {
                   #  # ]
     176   [ #  #  #  # ]:        579 :                 sb_base_bdev = &sb->base_bdevs[i];
     177   [ +  +  #  #  :        579 :                 if (sb_base_bdev->slot >= sb->num_base_bdevs) {
          #  #  #  #  #  
                      # ]
     178   [ #  #  #  # ]:         12 :                         SPDK_WARNLOG("Invalid superblock base bdev slot number %u on bdev %s\n",
     179                 :            :                                      sb_base_bdev->slot, spdk_bdev_get_name(bdev));
     180                 :         12 :                         return -EINVAL;
     181                 :            :                 }
     182                 :          0 :         }
     183                 :            : 
     184                 :        237 :         return 0;
     185                 :        380 : }
     186                 :            : 
     187                 :            : static void
     188                 :       6852 : raid_bdev_read_sb_ctx_free(struct raid_bdev_read_sb_ctx *ctx)
     189                 :            : {
     190   [ +  -  +  - ]:       6852 :         spdk_dma_free(ctx->buf);
     191                 :            : 
     192                 :       6852 :         free(ctx);
     193                 :       6852 : }
     194                 :            : 
     195                 :            : static void raid_bdev_read_sb_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
     196                 :            : 
     197                 :            : static int
     198                 :         24 : raid_bdev_read_sb_remainder(struct raid_bdev_read_sb_ctx *ctx)
     199                 :            : {
     200   [ #  #  #  # ]:         24 :         struct raid_bdev_superblock *sb = ctx->buf;
     201   [ #  #  #  # ]:         24 :         struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(ctx->desc);
     202                 :            :         uint32_t buf_size_prev;
     203                 :            :         void *buf;
     204                 :            :         int rc;
     205                 :            : 
     206   [ #  #  #  # ]:         24 :         buf_size_prev = ctx->buf_size;
     207   [ +  -  #  #  :         42 :         ctx->buf_size = spdk_divide_round_up(spdk_min(sb->length, RAID_BDEV_SB_MAX_LENGTH),
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     208   [ #  #  #  #  :         48 :                                              spdk_bdev_get_data_block_size(bdev)) * bdev->blocklen;
                   #  # ]
     209   [ #  #  #  #  :         24 :         buf = spdk_dma_realloc(ctx->buf, ctx->buf_size, spdk_bdev_get_buf_align(bdev), NULL);
             #  #  #  # ]
     210         [ +  + ]:         24 :         if (buf == NULL) {
     211                 :          0 :                 SPDK_ERRLOG("Failed to reallocate buffer\n");
     212                 :          0 :                 return -ENOMEM;
     213                 :            :         }
     214   [ #  #  #  # ]:         24 :         ctx->buf = buf;
     215                 :            : 
     216   [ #  #  #  #  :         30 :         rc = spdk_bdev_read(ctx->desc, ctx->ch, ctx->buf + buf_size_prev, buf_size_prev,
          #  #  #  #  #  
                #  #  # ]
     217   [ #  #  #  # ]:         24 :                             ctx->buf_size - buf_size_prev, raid_bdev_read_sb_cb, ctx);
     218         [ -  + ]:         24 :         if (rc != 0) {
     219         [ #  # ]:          0 :                 SPDK_ERRLOG("Failed to read bdev %s superblock remainder: %s\n",
     220                 :            :                             spdk_bdev_get_name(bdev), spdk_strerror(-rc));
     221                 :          0 :                 return rc;
     222                 :            :         }
     223                 :            : 
     224                 :         24 :         return 0;
     225                 :          6 : }
     226                 :            : 
     227                 :            : static void
     228                 :       6876 : raid_bdev_read_sb_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
     229                 :            : {
     230   [ +  -  +  - ]:       6876 :         struct spdk_bdev *bdev = bdev_io->bdev;
     231                 :       6876 :         struct raid_bdev_read_sb_ctx *ctx = cb_arg;
     232                 :       6876 :         struct raid_bdev_superblock *sb = NULL;
     233                 :            :         int status;
     234                 :            : 
     235   [ +  +  +  +  :       6876 :         if (spdk_bdev_is_md_interleaved(bdev_io->bdev) && ctx->buf_size > bdev->blocklen) {
          -  +  #  #  #  
          #  #  #  #  #  
                   #  # ]
     236                 :          8 :                 const uint32_t data_block_size = spdk_bdev_get_data_block_size(bdev);
     237                 :            :                 uint32_t i;
     238                 :            : 
     239   [ +  +  +  +  :         24 :                 for (i = 1; i < ctx->buf_size / bdev->blocklen; i++) {
          #  #  #  #  #  
                #  #  # ]
     240   [ -  +  -  +  :         20 :                         memmove(ctx->buf + (i * data_block_size),
             #  #  #  # ]
     241   [ #  #  #  #  :         16 :                                 ctx->buf + (i * bdev->blocklen),
             #  #  #  # ]
     242                 :          4 :                                 data_block_size);
     243                 :          4 :                 }
     244                 :          2 :         }
     245                 :            : 
     246                 :       6876 :         spdk_bdev_free_io(bdev_io);
     247                 :            : 
     248   [ +  +  +  - ]:       6876 :         if (!success) {
     249                 :          0 :                 status = -EIO;
     250                 :          0 :                 goto out;
     251                 :            :         }
     252                 :            : 
     253                 :       6876 :         status = raid_bdev_parse_superblock(ctx);
     254         [ +  + ]:       7226 :         if (status == -EAGAIN) {
     255                 :         24 :                 status = raid_bdev_read_sb_remainder(ctx);
     256         [ +  + ]:         24 :                 if (status == 0) {
     257                 :         24 :                         return;
     258                 :            :                 }
     259         [ +  + ]:       6852 :         } else if (status != 0) {
     260   [ +  +  +  +  :       6639 :                 SPDK_DEBUGLOG(bdev_raid_sb, "failed to parse bdev %s superblock\n",
          +  -  #  #  #  
                      # ]
     261                 :            :                               spdk_bdev_get_name(spdk_bdev_desc_get_bdev(ctx->desc)));
     262                 :        344 :         } else {
     263   [ #  #  #  # ]:        213 :                 sb = ctx->buf;
     264                 :            :         }
     265                 :       6502 : out:
     266   [ +  -  +  -  :       6852 :         ctx->cb(sb, status, ctx->cb_ctx);
          -  +  +  -  +  
                -  +  - ]
     267                 :            : 
     268                 :       6852 :         raid_bdev_read_sb_ctx_free(ctx);
     269                 :        356 : }
     270                 :            : 
     271                 :            : int
     272                 :       6852 : raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
     273                 :            :                                     raid_bdev_load_sb_cb cb, void *cb_ctx)
     274                 :            : {
     275                 :       6852 :         struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
     276                 :            :         struct raid_bdev_read_sb_ctx *ctx;
     277                 :            :         int rc;
     278                 :            : 
     279   [ +  +  #  # ]:       6852 :         assert(cb != NULL);
     280                 :            : 
     281                 :       6852 :         ctx = calloc(1, sizeof(*ctx));
     282         [ +  + ]:       6852 :         if (!ctx) {
     283                 :          0 :                 return -ENOMEM;
     284                 :            :         }
     285                 :            : 
     286   [ +  -  +  - ]:       6852 :         ctx->desc = desc;
     287   [ +  -  +  - ]:       6852 :         ctx->ch = ch;
     288   [ +  -  +  - ]:       6852 :         ctx->cb = cb;
     289   [ +  -  +  - ]:       6852 :         ctx->cb_ctx = cb_ctx;
     290   [ +  -  +  - ]:      13704 :         ctx->buf_size = spdk_divide_round_up(sizeof(struct raid_bdev_superblock),
     291   [ +  -  +  -  :      13704 :                                              spdk_bdev_get_data_block_size(bdev)) * bdev->blocklen;
                   +  - ]
     292   [ +  -  +  -  :       6852 :         ctx->buf = spdk_dma_malloc(ctx->buf_size, spdk_bdev_get_buf_align(bdev), NULL);
             +  -  +  - ]
     293   [ +  +  +  -  :       6852 :         if (!ctx->buf) {
                   +  - ]
     294                 :          0 :                 rc = -ENOMEM;
     295                 :          0 :                 goto err;
     296                 :            :         }
     297                 :            : 
     298   [ +  -  +  -  :       6852 :         rc = spdk_bdev_read(desc, ch, ctx->buf, 0, ctx->buf_size, raid_bdev_read_sb_cb, ctx);
             +  -  +  - ]
     299         [ +  + ]:       6852 :         if (rc) {
     300                 :          0 :                 goto err;
     301                 :            :         }
     302                 :            : 
     303                 :       6852 :         return 0;
     304                 :          0 : err:
     305                 :          0 :         raid_bdev_read_sb_ctx_free(ctx);
     306                 :            : 
     307                 :          0 :         return rc;
     308                 :        350 : }
     309                 :            : 
     310                 :            : static void
     311                 :        754 : raid_bdev_write_sb_base_bdev_done(int status, struct raid_bdev_write_sb_ctx *ctx)
     312                 :            : {
     313         [ +  + ]:        754 :         if (status != 0) {
     314   [ #  #  #  # ]:          0 :                 ctx->status = status;
     315                 :          0 :         }
     316                 :            : 
     317   [ +  +  #  # ]:        754 :         if (--ctx->remaining == 0) {
     318   [ #  #  #  #  :        195 :                 ctx->cb(ctx->status, ctx->raid_bdev, ctx->cb_ctx);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     319                 :        195 :                 free(ctx);
     320                 :          6 :         }
     321                 :        754 : }
     322                 :            : 
     323                 :            : static void
     324                 :        443 : raid_bdev_write_superblock_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
     325                 :            : {
     326                 :        443 :         struct raid_bdev_write_sb_ctx *ctx = cb_arg;
     327                 :        443 :         int status = 0;
     328                 :            : 
     329   [ +  +  #  # ]:        443 :         if (!success) {
     330   [ #  #  #  #  :          0 :                 SPDK_ERRLOG("Failed to save superblock on bdev %s\n", bdev_io->bdev->name);
             #  #  #  # ]
     331                 :          0 :                 status = -EIO;
     332                 :          0 :         }
     333                 :            : 
     334                 :        443 :         spdk_bdev_free_io(bdev_io);
     335                 :            : 
     336                 :        443 :         raid_bdev_write_sb_base_bdev_done(status, ctx);
     337                 :        443 : }
     338                 :            : 
     339                 :            : static void
     340                 :        195 : _raid_bdev_write_superblock(void *_ctx)
     341                 :            : {
     342                 :        195 :         struct raid_bdev_write_sb_ctx *ctx = _ctx;
     343   [ #  #  #  # ]:        195 :         struct raid_bdev *raid_bdev = ctx->raid_bdev;
     344                 :            :         struct raid_base_bdev_info *base_info;
     345                 :            :         uint8_t i;
     346                 :            :         int rc;
     347                 :            : 
     348   [ +  +  #  #  :        754 :         for (i = ctx->submitted; i < raid_bdev->num_base_bdevs; i++) {
          #  #  #  #  #  
                      # ]
     349   [ #  #  #  #  :        559 :                 base_info = &raid_bdev->base_bdev_info[i];
                   #  # ]
     350                 :            : 
     351   [ +  +  +  +  :        559 :                 if (!base_info->is_configured || base_info->remove_scheduled) {
          -  +  +  +  #  
          #  #  #  #  #  
                   #  # ]
     352   [ +  +  #  #  :        116 :                         assert(ctx->remaining > 1);
             #  #  #  # ]
     353                 :        116 :                         raid_bdev_write_sb_base_bdev_done(0, ctx);
     354         [ #  # ]:        116 :                         ctx->submitted++;
     355                 :        116 :                         continue;
     356                 :            :                 }
     357                 :            : 
     358   [ #  #  #  #  :        455 :                 rc = spdk_bdev_write(base_info->desc, base_info->app_thread_ch,
             #  #  #  # ]
     359   [ #  #  #  #  :        443 :                                      raid_bdev->sb_io_buf, 0, raid_bdev->sb_io_buf_size,
             #  #  #  # ]
     360                 :         12 :                                      raid_bdev_write_superblock_cb, ctx);
     361         [ +  + ]:        443 :                 if (rc != 0) {
     362   [ #  #  #  # ]:          0 :                         struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(base_info->desc);
     363                 :            : 
     364         [ #  # ]:          0 :                         if (rc == -ENOMEM) {
     365   [ #  #  #  #  :          0 :                                 ctx->wait_entry.bdev = bdev;
                   #  # ]
     366   [ #  #  #  #  :          0 :                                 ctx->wait_entry.cb_fn = _raid_bdev_write_superblock;
                   #  # ]
     367   [ #  #  #  #  :          0 :                                 ctx->wait_entry.cb_arg = ctx;
                   #  # ]
     368   [ #  #  #  #  :          0 :                                 spdk_bdev_queue_io_wait(bdev, base_info->app_thread_ch, &ctx->wait_entry);
                   #  # ]
     369                 :          0 :                                 return;
     370                 :            :                         }
     371                 :            : 
     372   [ #  #  #  #  :          0 :                         assert(ctx->remaining > 1);
             #  #  #  # ]
     373                 :          0 :                         raid_bdev_write_sb_base_bdev_done(rc, ctx);
     374                 :          0 :                 }
     375                 :            : 
     376         [ #  # ]:        443 :                 ctx->submitted++;
     377                 :         12 :         }
     378                 :            : 
     379                 :        195 :         raid_bdev_write_sb_base_bdev_done(0, ctx);
     380                 :          6 : }
     381                 :            : 
     382                 :            : void
     383                 :        195 : raid_bdev_write_superblock(struct raid_bdev *raid_bdev, raid_bdev_write_sb_cb cb, void *cb_ctx)
     384                 :            : {
     385                 :            :         struct raid_bdev_write_sb_ctx *ctx;
     386   [ #  #  #  # ]:        195 :         struct raid_bdev_superblock *sb = raid_bdev->sb;
     387                 :            :         int rc;
     388                 :            : 
     389   [ +  +  #  # ]:        195 :         assert(spdk_get_thread() == spdk_thread_get_app_thread());
     390   [ +  +  #  # ]:        195 :         assert(sb != NULL);
     391   [ -  +  #  # ]:        195 :         assert(cb != NULL);
     392                 :            : 
     393   [ +  +  #  #  :        195 :         if (raid_bdev->sb_io_buf == NULL) {
                   #  # ]
     394                 :        131 :                 rc = raid_bdev_alloc_sb_io_buf(raid_bdev);
     395         [ -  + ]:        131 :                 if (rc != 0) {
     396                 :          0 :                         goto err;
     397                 :            :                 }
     398                 :          6 :         }
     399                 :            : 
     400                 :        195 :         ctx = calloc(1, sizeof(*ctx));
     401         [ +  + ]:        195 :         if (!ctx) {
     402                 :          0 :                 rc = -ENOMEM;
     403                 :          0 :                 goto err;
     404                 :            :         }
     405                 :            : 
     406   [ #  #  #  # ]:        195 :         ctx->raid_bdev = raid_bdev;
     407   [ #  #  #  #  :        195 :         ctx->remaining = raid_bdev->num_base_bdevs + 1;
          #  #  #  #  #  
                      # ]
     408   [ #  #  #  # ]:        195 :         ctx->cb = cb;
     409   [ #  #  #  # ]:        195 :         ctx->cb_ctx = cb_ctx;
     410                 :            : 
     411         [ #  # ]:        195 :         sb->seq_number++;
     412                 :        195 :         raid_bdev_sb_update_crc(sb);
     413                 :            : 
     414   [ +  +  #  # ]:        195 :         if (spdk_bdev_is_md_interleaved(&raid_bdev->bdev)) {
     415                 :         21 :                 void *sb_buf = sb;
     416                 :            :                 uint32_t i;
     417                 :            : 
     418   [ +  +  +  +  :        170 :                 for (i = 0; i < raid_bdev->sb_io_buf_size / raid_bdev->bdev.blocklen; i++) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     419   [ -  +  -  +  :        183 :                         memcpy(raid_bdev->sb_io_buf + (i * raid_bdev->bdev.blocklen),
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     420   [ #  #  #  #  :        149 :                                sb_buf + (i * sb->block_size), sb->block_size);
             #  #  #  # ]
     421                 :         34 :                 }
     422                 :          2 :         }
     423                 :            : 
     424                 :        195 :         _raid_bdev_write_superblock(ctx);
     425                 :        195 :         return;
     426                 :          0 : err:
     427   [ #  #  #  # ]:          0 :         cb(rc, raid_bdev, cb_ctx);
     428                 :          6 : }
     429                 :            : 
     430                 :       2288 : SPDK_LOG_REGISTER_COMPONENT(bdev_raid_sb)

Generated by: LCOV version 1.15