Changeset 09c195e8 in mainline for uspace/srv/bd/hr/util.c


Ignore:
Timestamp:
2025-06-23T13:32:13Z (9 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
cdfcaea
Parents:
f6590c4
Message:

hr: move rebuild init to util.c

File:
1 edited

Legend:

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

    rf6590c4 r09c195e8  
    6969    hr_metadata_type_t);
    7070static errno_t hr_fill_svcs_list_from_cfg(hr_config_t *, list_t *);
     71static errno_t hr_swap_hs(hr_volume_t *, size_t, size_t);
    7172
    7273#define HR_RL_LIST_LOCK(vol) (fibril_mutex_lock(&(vol)->range_lock_list_lock))
     
    11281129}
    11291130
     1131errno_t hr_init_rebuild(hr_volume_t *vol, size_t *rebuild_idx)
     1132{
     1133        errno_t rc = EOK;
     1134
     1135        if (vol->level == HR_LVL_0)
     1136                return EINVAL;
     1137
     1138        fibril_rwlock_write_lock(&vol->extents_lock);
     1139        fibril_rwlock_write_lock(&vol->states_lock);
     1140        fibril_mutex_lock(&vol->hotspare_lock);
     1141
     1142        size_t bad = vol->extent_no;
     1143        for (size_t i = 0; i < vol->extent_no; i++) {
     1144                if (vol->extents[i].state != HR_EXT_ONLINE) {
     1145                        bad = i;
     1146                        break;
     1147                }
     1148        }
     1149
     1150        if (bad == vol->extent_no)
     1151                rc = EINVAL;
     1152        else if (vol->state != HR_VOL_DEGRADED)
     1153                rc = EINVAL;
     1154
     1155        size_t invalid = vol->extent_no;
     1156        for (size_t i = 0; i < vol->extent_no; i++) {
     1157                if (vol->extents[i].state == HR_EXT_INVALID) {
     1158                        invalid = i;
     1159                        break;
     1160                }
     1161        }
     1162
     1163        if (invalid < vol->extent_no)
     1164                bad = invalid;
     1165
     1166        if (bad != invalid && vol->hotspare_no == 0)
     1167                rc = EINVAL;
     1168
     1169        if (rc != EOK)
     1170                goto error;
     1171
     1172        if (bad != invalid) {
     1173                size_t hotspare_idx = vol->hotspare_no - 1;
     1174
     1175                hr_ext_state_t hs_state = vol->hotspares[hotspare_idx].state;
     1176                if (hs_state != HR_EXT_HOTSPARE) {
     1177                        HR_ERROR("hr_raid1_rebuild(): invalid hotspare"
     1178                            "state \"%s\", aborting rebuild\n",
     1179                            hr_get_ext_state_str(hs_state));
     1180                        rc = EINVAL;
     1181                        goto error;
     1182                }
     1183
     1184                rc = hr_swap_hs(vol, bad, hotspare_idx);
     1185                if (rc != EOK) {
     1186                        HR_ERROR("hr_raid1_rebuild(): swapping "
     1187                            "hotspare failed, aborting rebuild\n");
     1188                        goto error;
     1189                }
     1190        }
     1191
     1192        hr_extent_t *rebuild_ext = &vol->extents[bad];
     1193
     1194        HR_DEBUG("hr_raid1_rebuild(): starting REBUILD on extent no. %zu "
     1195            "(%"  PRIun  ")\n", bad, rebuild_ext->svc_id);
     1196
     1197        atomic_store_explicit(&vol->rebuild_blk, 0, memory_order_relaxed);
     1198
     1199        hr_update_ext_state(vol, bad, HR_EXT_REBUILD);
     1200        hr_update_vol_state(vol, HR_VOL_REBUILD);
     1201
     1202        *rebuild_idx = bad;
     1203error:
     1204        fibril_mutex_unlock(&vol->hotspare_lock);
     1205        fibril_rwlock_write_unlock(&vol->states_lock);
     1206        fibril_rwlock_write_unlock(&vol->extents_lock);
     1207
     1208        return rc;
     1209}
     1210
     1211static errno_t hr_swap_hs(hr_volume_t *vol, size_t bad, size_t hs)
     1212{
     1213        HR_DEBUG("%s()", __func__);
     1214
     1215        service_id_t faulty_svc_id = vol->extents[bad].svc_id;
     1216        service_id_t hs_svc_id = vol->hotspares[hs].svc_id;
     1217
     1218        hr_update_ext_svc_id(vol, bad, hs_svc_id);
     1219        hr_update_ext_state(vol, bad, HR_EXT_HOTSPARE);
     1220
     1221        hr_update_hotspare_svc_id(vol, hs, 0);
     1222        hr_update_hotspare_state(vol, hs, HR_EXT_MISSING);
     1223
     1224        vol->hotspare_no--;
     1225
     1226        if (faulty_svc_id != 0)
     1227                block_fini(faulty_svc_id);
     1228
     1229        return EOK;
     1230}
     1231
    11301232/** @}
    11311233 */
Note: See TracChangeset for help on using the changeset viewer.