Changeset e0695ce in mainline


Ignore:
Timestamp:
2025-06-23T16:50:43Z (4 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
6a8c1569
Parents:
f18e36e
git-author:
Miroslav Cimerman <mc@…> (2025-06-23 16:47:52)
git-committer:
Miroslav Cimerman <mc@…> (2025-06-23 16:50:43)
Message:

hr: save REBUILD position

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

Legend:

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

    rf18e36e re0695ce  
    155155                goto error;
    156156
    157         rc = vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
    158         if (rc != EOK)
    159                 goto error;
     157        vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
    160158
    161159        rc = hr_register_volume(vol);
  • uspace/srv/bd/hr/metadata/native.c

    rf18e36e re0695ce  
    171171                iter->fini = false;
    172172
    173                 if (iter_meta->counter == max_counter_val)
    174                         vol->extents[iter_meta->index].state = HR_EXT_ONLINE;
    175                 else
    176                         vol->extents[iter_meta->index].state = HR_EXT_INVALID;
     173                hr_ext_state_t final_ext_state = HR_EXT_INVALID;
     174                if (iter_meta->counter == max_counter_val) {
     175                        if (iter_meta->rebuild_pos > 0) {
     176                                final_ext_state = HR_EXT_REBUILD;
     177                                vol->rebuild_blk = iter_meta->rebuild_pos;
     178                                printf("REBUILD SHOULD RESUME at %lu\n",
     179                                    vol->rebuild_blk);
     180                        } else {
     181                                final_ext_state = HR_EXT_ONLINE;
     182                        }
     183                }
     184
     185                vol->extents[iter_meta->index].state = final_ext_state;
    177186        }
    178187
     
    206215        scratch_md.data_offset = host2uint64_t_le(metadata->data_offset);
    207216        scratch_md.counter = host2uint64_t_le(metadata->counter);
     217        scratch_md.rebuild_pos = host2uint64_t_le(metadata->rebuild_pos);
    208218        scratch_md.version = host2uint32_t_le(metadata->version);
    209219        scratch_md.extent_no = host2uint32_t_le(metadata->extent_no);
     
    240250        metadata->data_offset = uint64_t_le2host(scratch_md.data_offset);
    241251        metadata->counter = uint64_t_le2host(scratch_md.counter);
     252        metadata->rebuild_pos = uint64_t_le2host(scratch_md.rebuild_pos);
    242253        metadata->version = uint32_t_le2host(scratch_md.version);
    243254        metadata->extent_no = uint32_t_le2host(scratch_md.extent_no);
     
    249260        memcpy(metadata->devname, scratch_md.devname, HR_DEVNAME_LEN);
    250261
     262        if (metadata->version != 1)
     263                return EINVAL;
     264
    251265        return EOK;
    252266}
     
    394408
    395409                fibril_rwlock_read_lock(&vol->states_lock);
    396 
    397                 /* TODO: special case for REBUILD */
    398                 if (ext->state != HR_EXT_ONLINE) {
     410                hr_ext_state_t s = ext->state;
     411
     412                if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) {
    399413                        fibril_rwlock_read_unlock(&vol->states_lock);
    400414                        continue;
     
    404418
    405419                md->index = i;
     420                if (s == HR_EXT_REBUILD)
     421                        md->rebuild_pos = vol->rebuild_blk;
     422                else
     423                        md->rebuild_pos = 0;
    406424                meta_native_encode(md, md_block);
    407425                rc = meta_native_write_block(ext->svc_id, md_block);
  • uspace/srv/bd/hr/metadata/native.h

    rf18e36e re0695ce  
    6161        uint64_t counter;
    6262
     63        uint64_t rebuild_pos;
     64
    6365        uint32_t version; /* XXX: yet unused */
    6466        uint32_t extent_no;
  • uspace/srv/bd/hr/raid1.c

    rf18e36e re0695ce  
    153153
    154154        vol->meta_ops->inc_counter(vol);
    155         (void)vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
     155        vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
    156156
    157157        hr_raid1_vol_state_eval_forced(vol);
     
    194194        size_t invalid_no = hr_count_extents(vol, HR_EXT_INVALID);
    195195
     196        size_t rebuild_no = hr_count_extents(vol, HR_EXT_REBUILD);
     197
    196198        fibril_mutex_lock(&vol->hotspare_lock);
    197199        size_t hs_no = vol->hotspare_no;
     
    216218
    217219                if (old_state != HR_VOL_REBUILD) {
    218                         if (hs_no > 0 || invalid_no > 0) {
     220                        if (hs_no > 0 || invalid_no > 0 || rebuild_no > 0) {
    219221                                fid_t fib = fibril_create(hr_raid1_rebuild,
    220222                                    vol);
     
    443445}
    444446
    445 /*
    446  * Put the last HOTSPARE extent in place
    447  * of first that != ONLINE, and start the rebuild.
    448  */
    449447static errno_t hr_raid1_rebuild(void *arg)
    450448{
     
    463461        rebuild_ext = &vol->extents[rebuild_idx];
    464462
    465         size_t left = vol->data_blkno;
     463        size_t left = vol->data_blkno - vol->rebuild_blk;
    466464        size_t max_blks = DATA_XFER_LIMIT / vol->bsize;
    467465        buf = hr_malloc_waitok(max_blks * vol->bsize);
    468466
    469467        size_t cnt;
    470         uint64_t ba = 0;
     468        uint64_t ba = vol->rebuild_blk;
    471469        hr_add_data_offset(vol, &ba);
    472470
     
    487485        hr_range_lock_t *rl = NULL;
    488486
     487        HR_NOTE("\"%s\": REBUILD started on extent no. %zu at block %lu.\n",
     488            vol->devname, rebuild_idx, ba);
     489
     490        uint64_t written = 0;
    489491        unsigned int percent, old_percent = 100;
    490492        while (left != 0) {
     
    517519                }
    518520
     521                if (written * vol->bsize > HR_REBUILD_SAVE_BYTES) {
     522                        vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
     523                        written = 0;
     524                }
     525
    519526                hr_range_lock_release(rl);
    520527
     528                written += cnt;
    521529                ba += cnt;
    522530                left -= cnt;
     
    531539        hr_update_ext_state(vol, rebuild_idx, HR_EXT_ONLINE);
    532540
     541        atomic_store_explicit(&vol->rebuild_blk, 0, memory_order_relaxed);
     542
    533543        hr_mark_vol_state_dirty(vol);
    534544
    535545        fibril_rwlock_write_unlock(&vol->states_lock);
    536 
    537         /* (void)vol->meta_ops->save(vol, WITH_STATE_CALLBACK); */
    538 
    539546end:
    540547        fibril_rwlock_read_unlock(&vol->extents_lock);
     
    542549        hr_raid1_vol_state_eval(vol);
    543550
    544         if (buf != NULL)
    545                 free(buf);
     551        free(buf);
    546552
    547553        return rc;
  • uspace/srv/bd/hr/raid5.c

    rf18e36e re0695ce  
    150150
    151151        vol->meta_ops->inc_counter(vol);
    152         (void)vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
     152        vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
    153153
    154154        hr_raid5_vol_state_eval_forced(vol);
     
    610610
    611611        size_t invalid_no = hr_count_extents(vol, HR_EXT_INVALID);
     612
     613        size_t rebuild_no = hr_count_extents(vol, HR_EXT_REBUILD);
    612614
    613615        fibril_mutex_lock(&vol->hotspare_lock);
     
    625627
    626628                if (state != HR_VOL_REBUILD) {
    627                         if (hs_no > 0 || invalid_no > 0) {
     629                        if (hs_no > 0 || invalid_no > 0 || rebuild_no > 0) {
    628630                                fid_t fib = fibril_create(hr_raid5_rebuild,
    629631                                    vol);
     
    720722
    721723        uint64_t max_blks = DATA_XFER_LIMIT / vol->bsize;
    722         uint64_t left = vol->data_blkno / (vol->extent_no - 1);
     724        uint64_t left =
     725            vol->data_blkno / (vol->extent_no - 1) - vol->rebuild_blk;
    723726        buf = hr_malloc_waitok(max_blks * vol->bsize);
    724727        xorbuf = hr_malloc_waitok(max_blks * vol->bsize);
     
    726729        uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
    727730
    728         uint64_t ba = 0, cnt;
     731        size_t cnt;
     732        uint64_t ba = vol->rebuild_blk;
    729733        hr_add_data_offset(vol, &ba);
    730734
     
    747751            false);
    748752
     753        HR_NOTE("\"%s\": REBUILD started on extent no. %zu at block %lu.\n",
     754            vol->devname, rebuild_idx, ba);
     755
     756        uint64_t written = 0;
    749757        unsigned int percent, old_percent = 100;
    750758        while (left != 0) {
     
    810818                }
    811819
     820                if (written * vol->bsize > HR_REBUILD_SAVE_BYTES) {
     821                        vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
     822                        written = 0;
     823                }
     824
    812825                hr_range_lock_release(rl);
    813826                hr_reset_stripe(stripe);
    814827
     828                written += cnt;
    815829                ba += cnt;
    816830                left -= cnt;
     831                old_percent = percent;
    817832
    818833                /*
     
    829844        hr_update_ext_state(vol, rebuild_idx, HR_EXT_ONLINE);
    830845
     846        atomic_store_explicit(&vol->rebuild_blk, 0, memory_order_relaxed);
     847
    831848        hr_mark_vol_state_dirty(vol);
    832849
    833850        fibril_rwlock_write_unlock(&vol->states_lock);
    834 
    835         /* (void)vol->meta_ops->save(vol, WITH_STATE_CALLBACK); */
    836 
    837851end:
    838852        fibril_rwlock_read_unlock(&vol->extents_lock);
  • uspace/srv/bd/hr/util.c

    rf18e36e re0695ce  
    281281
    282282        /* save metadata, but we don't care about states anymore */
    283         (void)vol->meta_ops->save(vol, NO_STATE_CALLBACK);
     283        vol->meta_ops->save(vol, NO_STATE_CALLBACK);
    284284
    285285        HR_NOTE("deactivating volume \"%s\"\n", vol->devname);
     
    11171117{
    11181118        errno_t rc = EOK;
     1119        size_t bad = vol->extent_no;
    11191120
    11201121        if (vol->level == HR_LVL_0)
     
    11251126        fibril_mutex_lock(&vol->hotspare_lock);
    11261127
    1127         size_t bad = vol->extent_no;
     1128        if (vol->state != HR_VOL_DEGRADED) {
     1129                rc = EINVAL;
     1130                goto error;
     1131        }
     1132
     1133        size_t rebuild = vol->extent_no;
    11281134        for (size_t i = 0; i < vol->extent_no; i++) {
    1129                 if (vol->extents[i].state != HR_EXT_ONLINE) {
    1130                         bad = i;
     1135                if (vol->extents[i].state == HR_EXT_REBUILD) {
     1136                        rebuild = i;
    11311137                        break;
    11321138                }
    11331139        }
    11341140
    1135         if (bad == vol->extent_no)
    1136                 rc = EINVAL;
    1137         else if (vol->state != HR_VOL_DEGRADED)
    1138                 rc = EINVAL;
     1141        if (rebuild < vol->extent_no) {
     1142                bad = rebuild;
     1143                goto init_rebuild;
     1144        }
    11391145
    11401146        size_t invalid = vol->extent_no;
     
    11461152        }
    11471153
    1148         if (invalid < vol->extent_no)
     1154        if (invalid < vol->extent_no) {
    11491155                bad = invalid;
    1150 
    1151         if (bad != invalid && vol->hotspare_no == 0)
     1156                goto init_rebuild;
     1157        }
     1158
     1159        for (size_t i = 0; i < vol->extent_no; i++) {
     1160                if (vol->extents[i].state != HR_EXT_ONLINE) {
     1161                        bad = i;
     1162                        break;
     1163                }
     1164        }
     1165
     1166        if (bad == vol->extent_no || vol->hotspare_no == 0) {
    11521167                rc = EINVAL;
    1153 
    1154         if (rc != EOK)
    1155                 goto error;
    1156 
    1157         if (bad != invalid) {
    1158                 size_t hotspare_idx = vol->hotspare_no - 1;
    1159 
    1160                 hr_ext_state_t hs_state = vol->hotspares[hotspare_idx].state;
    1161                 if (hs_state != HR_EXT_HOTSPARE) {
    1162                         HR_ERROR("hr_raid1_rebuild(): invalid hotspare"
    1163                             "state \"%s\", aborting rebuild\n",
    1164                             hr_get_ext_state_str(hs_state));
    1165                         rc = EINVAL;
    1166                         goto error;
    1167                 }
    1168 
    1169                 rc = hr_swap_hs(vol, bad, hotspare_idx);
    1170                 if (rc != EOK) {
    1171                         HR_ERROR("hr_raid1_rebuild(): swapping "
    1172                             "hotspare failed, aborting rebuild\n");
    1173                         goto error;
    1174                 }
     1168                goto error;
     1169        }
     1170
     1171        size_t hotspare_idx = vol->hotspare_no - 1;
     1172
     1173        hr_ext_state_t hs_state = vol->hotspares[hotspare_idx].state;
     1174        if (hs_state != HR_EXT_HOTSPARE) {
     1175                HR_ERROR("hr_raid1_rebuild(): invalid hotspare"
     1176                    "state \"%s\", aborting rebuild\n",
     1177                    hr_get_ext_state_str(hs_state));
     1178                rc = EINVAL;
     1179                goto error;
     1180        }
     1181
     1182        rc = hr_swap_hs(vol, bad, hotspare_idx);
     1183        if (rc != EOK) {
     1184                HR_ERROR("hr_raid1_rebuild(): swapping "
     1185                    "hotspare failed, aborting rebuild\n");
     1186                goto error;
    11751187        }
    11761188
     
    11801192            "(%"  PRIun  ")\n", bad, rebuild_ext->svc_id);
    11811193
    1182         atomic_store_explicit(&vol->rebuild_blk, 0, memory_order_relaxed);
    1183 
     1194init_rebuild:
    11841195        hr_update_ext_state(vol, bad, HR_EXT_REBUILD);
    11851196        hr_update_vol_state(vol, HR_VOL_REBUILD);
  • uspace/srv/bd/hr/var.h

    rf18e36e re0695ce  
    4949#define NAME "hr"
    5050#define HR_STRIP_SIZE DATA_XFER_LIMIT
     51
     52/*
     53 * During a rebuild operation, we save the rebuild
     54 * position this each many bytes. Currently each
     55 * 10 MiB.
     56 */
     57#define HR_REBUILD_SAVE_BYTES (10U * 1024 * 1024)
    5158
    5259struct hr_volume;
Note: See TracChangeset for help on using the changeset viewer.