Changeset baa4929 in mainline


Ignore:
Timestamp:
2025-03-31T17:07:34Z (6 weeks ago)
Author:
Miroslav Cimerman <mc@…>
Children:
a5ec426
Parents:
6d0fc11
Message:

hr: extent init refactor, blkno truncation

Location:
uspace/srv/bd/hr
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/hr/hr.c

    r6d0fc11 rbaa4929  
    127127        }
    128128
    129         rc = hr_create_vol_struct(&new_volume, cfg->level);
     129        rc = hr_create_vol_struct(&new_volume, cfg->level, cfg->devname);
    130130        if (rc != EOK) {
    131131                free(cfg);
     
    134134        }
    135135
    136         str_cpy(new_volume->devname, HR_DEVNAME_LEN, cfg->devname);
    137         for (i = 0; i < cfg->dev_no; i++)
    138                 new_volume->extents[i].svc_id = cfg->devs[i];
    139         new_volume->level = cfg->level;
    140         new_volume->extent_no = cfg->dev_no;
    141 
    142         /* XXX: do proper initing ... */
    143         rc = hr_init_devs(new_volume);
    144         if (rc != EOK) {
    145                 free(cfg);
    146                 free(new_volume);
    147                 async_answer_0(icall, rc);
    148                 return;
    149         }
     136        rc = hr_init_extents_from_cfg(new_volume, cfg);
     137        if (rc != EOK)
     138                goto error;
    150139
    151140        new_volume->hr_ops.init(new_volume);
  • uspace/srv/bd/hr/raid0.c

    r6d0fc11 rbaa4929  
    8383errno_t hr_raid0_create(hr_volume_t *new_volume)
    8484{
     85        HR_DEBUG("%s()", __func__);
     86
    8587        assert(new_volume->level == HR_LVL_0);
    8688
     
    106108errno_t hr_raid0_init(hr_volume_t *vol)
    107109{
    108         errno_t rc;
    109         size_t bsize;
    110         uint64_t total_blkno;
     110        HR_DEBUG("%s()", __func__);
    111111
    112112        assert(vol->level == HR_LVL_0);
    113113
    114         rc = hr_check_devs(vol, &total_blkno, &bsize);
    115         if (rc != EOK)
    116                 return rc;
    117 
     114        uint64_t truncated_blkno = vol->extents[0].blkno;
     115        for (size_t i = 1; i < vol->extent_no; i++) {
     116                if (vol->extents[i].blkno < truncated_blkno)
     117                        truncated_blkno = vol->extents[i].blkno;
     118        }
     119
     120        uint64_t total_blkno = truncated_blkno * vol->extent_no;
     121
     122        vol->truncated_blkno = truncated_blkno;
    118123        vol->nblocks = total_blkno;
    119         vol->bsize = bsize;
    120         /*
    121          * XXX: according to bsize set the data_offset...
    122          *
    123          * also can change this depending on level, like
    124          * RAID5 might try to put data at 64K boundary
    125          */
    126124        vol->data_offset = HR_DATA_OFF;
    127         vol->data_blkno = vol->nblocks - (vol->data_offset * vol->extent_no);
     125
     126        vol->data_blkno = total_blkno;
     127        vol->data_blkno -= HR_META_SIZE * vol->extent_no; /* count md blocks */
     128
    128129        vol->strip_size = HR_STRIP_SIZE;
    129130
     
    133134void hr_raid0_status_event(hr_volume_t *vol)
    134135{
     136        HR_DEBUG("%s()", __func__);
     137
    135138        hr_raid0_update_vol_status(vol);
    136139}
  • uspace/srv/bd/hr/raid1.c

    r6d0fc11 rbaa4929  
    9191errno_t hr_raid1_create(hr_volume_t *new_volume)
    9292{
     93        HR_DEBUG("%s()", __func__);
     94
    9395        assert(new_volume->level == HR_LVL_1);
    9496
     
    120122errno_t hr_raid1_init(hr_volume_t *vol)
    121123{
    122         errno_t rc;
    123         size_t bsize;
    124         uint64_t total_blkno;
     124        HR_DEBUG("%s()", __func__);
    125125
    126126        assert(vol->level == HR_LVL_1);
    127127
    128         rc = hr_check_devs(vol, &total_blkno, &bsize);
    129         if (rc != EOK)
    130                 return rc;
    131 
    132         vol->nblocks = total_blkno / vol->extent_no;
    133         vol->bsize = bsize;
    134         /*
    135          * XXX: according to bsize set the data_offset...
    136          *
    137          * also can change this depending on level, like
    138          * RAID5 might try to put data at 64K boundary
    139          */
     128        uint64_t truncated_blkno = vol->extents[0].blkno;
     129        for (size_t i = 1; i < vol->extent_no; i++) {
     130                if (vol->extents[i].blkno < truncated_blkno)
     131                        truncated_blkno = vol->extents[i].blkno;
     132        }
     133
     134        vol->truncated_blkno = truncated_blkno;
     135        vol->nblocks = truncated_blkno;
    140136        vol->data_offset = HR_DATA_OFF;
    141         vol->data_blkno = vol->nblocks - vol->data_offset;
     137        vol->data_blkno = truncated_blkno - HR_META_SIZE;
    142138        vol->strip_size = 0;
    143139
     
    147143void hr_raid1_status_event(hr_volume_t *vol)
    148144{
     145        HR_DEBUG("%s()", __func__);
     146
    149147        hr_raid1_update_vol_status(vol);
    150148}
  • uspace/srv/bd/hr/raid5.c

    r6d0fc11 rbaa4929  
    9393errno_t hr_raid5_create(hr_volume_t *new_volume)
    9494{
     95        HR_DEBUG("%s()", __func__);
     96
    9597        assert(new_volume->level == HR_LVL_5 || new_volume->level == HR_LVL_4);
    9698
     
    122124errno_t hr_raid5_init(hr_volume_t *vol)
    123125{
    124         errno_t rc;
    125         size_t bsize;
    126         uint64_t total_blkno;
     126        HR_DEBUG("%s()", __func__);
    127127
    128128        assert(vol->level == HR_LVL_5 || vol->level == HR_LVL_4);
    129129
    130         rc = hr_check_devs(vol, &total_blkno, &bsize);
    131         if (rc != EOK)
    132                 return rc;
    133 
     130        uint64_t truncated_blkno = vol->extents[0].blkno;
     131        for (size_t i = 1; i < vol->extent_no; i++) {
     132                if (vol->extents[i].blkno < truncated_blkno)
     133                        truncated_blkno = vol->extents[i].blkno;
     134        }
     135
     136        uint64_t total_blkno = truncated_blkno * vol->extent_no;
     137
     138        vol->truncated_blkno = truncated_blkno;
    134139        vol->nblocks = total_blkno;
    135         vol->bsize = bsize;
    136         /*
    137          * XXX: according to bsize set the data_offset...
    138          *
    139          * also can change this depending on level, like
    140          * RAID5 might try to put data at 64K boundary
    141          */
    142140        vol->data_offset = HR_DATA_OFF;
    143         vol->data_blkno = vol->nblocks - (vol->data_offset * vol->extent_no) -
    144             (vol->nblocks / vol->extent_no);
     141
     142        vol->data_blkno = total_blkno;
     143        vol->data_blkno -= HR_META_SIZE * vol->extent_no; /* count md blocks */
     144        vol->data_blkno -= truncated_blkno; /* count parity */
     145
    145146        vol->strip_size = HR_STRIP_SIZE;
    146147
  • uspace/srv/bd/hr/util.c

    r6d0fc11 rbaa4929  
    4545#include <stdlib.h>
    4646#include <stdio.h>
     47#include <str.h>
    4748#include <str_error.h>
    4849#include <vbd.h>
     
    8485extern fibril_rwlock_t hr_volumes_lock;
    8586
    86 errno_t hr_create_vol_struct(hr_volume_t **rvol, hr_level_t level)
     87errno_t hr_create_vol_struct(hr_volume_t **rvol, hr_level_t level,
     88    const char *devname)
    8789{
    8890        errno_t rc;
     
    9294                return ENOMEM;
    9395
     96        str_cpy(vol->devname, HR_DEVNAME_LEN, devname);
    9497        vol->level = level;
    9598
     
    139142        vol->status = HR_VOL_NONE;
    140143
    141         for (size_t i = 0; i < HR_MAX_EXTENTS; ++i)
    142                 vol->extents[i].status = HR_EXT_MISSING;
    143 
    144         for (size_t i = 0; i < HR_MAX_HOTSPARES; ++i)
    145                 vol->extents[i].status = HR_EXT_MISSING;
    146 
    147144        fibril_mutex_initialize(&vol->lock); /* XXX: will remove this */
    148145
     
    232229}
    233230
    234 errno_t hr_init_devs(hr_volume_t *vol)
     231errno_t hr_init_extents_from_cfg(hr_volume_t *vol, hr_config_t *cfg)
    235232{
    236233        HR_DEBUG("%s()", __func__);
    237234
    238235        errno_t rc;
    239         size_t i;
    240         hr_extent_t *extent;
    241 
    242         for (i = 0; i < vol->extent_no; i++) {
    243                 extent = &vol->extents[i];
    244                 if (extent->svc_id == 0) {
    245                         extent->status = HR_EXT_MISSING;
    246                         continue;
    247                 }
    248 
    249                 HR_DEBUG("hr_init_devs(): block_init() on (%lu)\n",
    250                     extent->svc_id);
    251                 rc = block_init(extent->svc_id);
    252                 extent->status = HR_EXT_ONLINE;
    253 
     236        size_t i, blkno, bsize;
     237        size_t last_bsize = 0;
     238
     239        for (i = 0; i < cfg->dev_no; i++) {
     240                service_id_t svc_id = cfg->devs[i];
     241                if (svc_id == 0) {
     242                        rc = EINVAL;
     243                        goto error;
     244                }
     245
     246                HR_DEBUG("%s(): block_init() on (%lu)\n", __func__, svc_id);
     247                rc = block_init(svc_id);
    254248                if (rc != EOK) {
    255                         HR_ERROR("hr_init_devs(): initing (%lu) failed, "
    256                             "aborting\n", extent->svc_id);
    257                         break;
    258                 }
    259         }
     249                        HR_DEBUG("%s(): initing (%lu) failed, aborting\n",
     250                            __func__, svc_id);
     251                        goto error;
     252                }
     253
     254                rc = block_get_nblocks(svc_id, &blkno);
     255                if (rc != EOK)
     256                        goto error;
     257
     258                rc = block_get_bsize(svc_id, &bsize);
     259                if (rc != EOK)
     260                        goto error;
     261
     262                if (last_bsize != 0 && bsize != last_bsize) {
     263                        HR_DEBUG("block sizes differ\n");
     264                        rc = EINVAL;
     265                        goto error;
     266                }
     267
     268                vol->extents[i].svc_id = svc_id;
     269                vol->extents[i].blkno = blkno;
     270                vol->extents[i].status = HR_EXT_ONLINE;
     271
     272                last_bsize = bsize;
     273        }
     274
     275        vol->bsize = last_bsize;
     276        vol->extent_no = cfg->dev_no;
    260277
    261278        for (i = 0; i < HR_MAX_HOTSPARES; i++)
    262279                vol->hotspares[i].status = HR_EXT_MISSING;
     280
     281        return EOK;
     282
     283error:
     284        for (i = 0; i < HR_MAX_EXTENTS; i++) {
     285                if (vol->extents[i].svc_id != 0)
     286                        block_fini(vol->extents[i].svc_id);
     287        }
    263288
    264289        return rc;
     
    330355        rc = loc_service_unregister(hr_srv, new_id);
    331356        free(fullname);
    332         return rc;
    333 }
    334 
    335 errno_t hr_check_devs(hr_volume_t *vol, uint64_t *rblkno, size_t *rbsize)
    336 {
    337         HR_DEBUG("%s()", __func__);
    338 
    339         errno_t rc;
    340         size_t i, bsize;
    341         uint64_t nblocks;
    342         size_t last_bsize = 0;
    343         uint64_t last_nblocks = 0;
    344         uint64_t total_blocks = 0;
    345         hr_extent_t *extent;
    346 
    347         for (i = 0; i < vol->extent_no; i++) {
    348                 extent = &vol->extents[i];
    349                 if (extent->status == HR_EXT_MISSING)
    350                         continue;
    351                 rc = block_get_nblocks(extent->svc_id, &nblocks);
    352                 if (rc != EOK)
    353                         goto error;
    354                 if (last_nblocks != 0 && nblocks != last_nblocks) {
    355                         HR_ERROR("number of blocks differs\n");
    356                         rc = EINVAL;
    357                         goto error;
    358                 }
    359 
    360                 total_blocks += nblocks;
    361                 last_nblocks = nblocks;
    362         }
    363 
    364         for (i = 0; i < vol->extent_no; i++) {
    365                 extent = &vol->extents[i];
    366                 if (extent->status == HR_EXT_MISSING)
    367                         continue;
    368                 rc = block_get_bsize(extent->svc_id, &bsize);
    369                 if (rc != EOK)
    370                         goto error;
    371                 if (last_bsize != 0 && bsize != last_bsize) {
    372                         HR_ERROR("block sizes differ\n");
    373                         rc = EINVAL;
    374                         goto error;
    375                 }
    376 
    377                 last_bsize = bsize;
    378         }
    379 
    380         if ((bsize % 512) != 0) {
    381                 HR_ERROR("block size not multiple of 512\n");
    382                 return EINVAL;
    383         }
    384 
    385         if (rblkno != NULL)
    386                 *rblkno = total_blocks;
    387         if (rbsize != NULL)
    388                 *rbsize = bsize;
    389 error:
    390357        return rc;
    391358}
     
    816783
    817784        hr_volume_t *vol;
    818         rc = hr_create_vol_struct(&vol, (hr_level_t)main_md->level);
     785        rc = hr_create_vol_struct(&vol, (hr_level_t)main_md->level,
     786            main_md->devname);
    819787        if (rc != EOK)
    820788                goto error;
     
    827795        vol->metadata_version = main_md->version;
    828796        vol->extent_no = main_md->extent_no;
    829         vol->level = main_md->level;
     797        /* vol->level = main_md->level; */
    830798        vol->layout = main_md->layout;
    831799        vol->strip_size = main_md->strip_size;
    832800        vol->bsize = main_md->bsize;
    833         memcpy(vol->devname, main_md->devname, HR_DEVNAME_LEN);
     801        /* memcpy(vol->devname, main_md->devname, HR_DEVNAME_LEN); */
    834802
    835803        memcpy(vol->in_mem_md, main_md, sizeof(hr_metadata_t));
     
    837805        list_foreach(*list, link, struct svc_id_linked, iter) {
    838806                vol->extents[iter->md->index].svc_id = iter->svc_id;
     807
     808                size_t blkno;
     809                rc = block_get_nblocks(iter->svc_id, &blkno);
     810                if (rc != EOK)
     811                        goto error;
     812                vol->extents[iter->md->index].blkno = blkno;
     813
    839814                if (iter->md->counter == max_counter_val)
    840815                        vol->extents[iter->md->index].status = HR_EXT_ONLINE;
     
    10451020                    "to \"%s\"\n", __func__, vol->devname);
    10461021                rc = ELIMIT;
    1047                 goto end;
     1022                goto error;
    10481023        }
    10491024
    10501025        rc = block_init(hotspare);
    10511026        if (rc != EOK)
    1052                 goto end;
     1027                goto error;
     1028
     1029        size_t hs_blkno;
     1030        rc = block_get_nblocks(hotspare, &hs_blkno);
     1031        if (rc != EOK) {
     1032                block_fini(hotspare);
     1033                goto error;
     1034        }
     1035
     1036        /*
     1037         * TODO: make more flexible, when will have foreign md, the calculation
     1038         * will differ, maybe something new like vol->md_hs_blkno will be enough
     1039         */
     1040        if (hs_blkno < vol->truncated_blkno - HR_META_SIZE) {
     1041                rc = EINVAL;
     1042                block_fini(hotspare);
     1043                goto error;
     1044        }
    10531045
    10541046        size_t hs_idx = vol->hotspare_no;
     
    10601052
    10611053        hr_mark_vol_state_dirty(vol);
    1062 end:
     1054error:
    10631055        fibril_mutex_unlock(&vol->hotspare_lock);
    10641056        return rc;
  • uspace/srv/bd/hr/util.h

    r6d0fc11 rbaa4929  
    5353
    5454
    55 extern errno_t           hr_create_vol_struct(hr_volume_t **, hr_level_t);
     55extern errno_t           hr_create_vol_struct(hr_volume_t **, hr_level_t,
     56    const char *);
    5657extern void              hr_destroy_vol_struct(hr_volume_t *);
    5758extern hr_volume_t      *hr_get_volume(service_id_t);
    5859extern errno_t           hr_remove_volume(service_id_t);
    59 extern errno_t           hr_init_devs(hr_volume_t *);
     60extern errno_t           hr_init_extents_from_cfg(hr_volume_t *, hr_config_t *);
    6061extern void              hr_fini_devs(hr_volume_t *);
    6162extern errno_t           hr_register_volume(hr_volume_t *);
    62 extern errno_t           hr_check_devs(hr_volume_t *, uint64_t *, size_t *);
    6363extern errno_t           hr_check_ba_range(hr_volume_t *, size_t, uint64_t);
    6464extern void              hr_add_ba_offset(hr_volume_t *, uint64_t *);
  • uspace/srv/bd/hr/var.h

    r6d0fc11 rbaa4929  
    123123} hr_range_lock_t;
    124124
    125 extern errno_t          hr_init_devs(hr_volume_t *);
    126 extern void             hr_fini_devs(hr_volume_t *);
    127 
    128125extern errno_t          hr_raid0_create(hr_volume_t *);
    129126extern errno_t          hr_raid1_create(hr_volume_t *);
Note: See TracChangeset for help on using the changeset viewer.