Changeset 5ee041e in mainline


Ignore:
Timestamp:
2025-01-12T17:02:39Z (5 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
3a68baa
Parents:
58d82fa
Message:

hr: RAID1: deferred extent invalidation

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

Legend:

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

    r58d82fa r5ee041e  
    260260        fibril_mutex_initialize(&new_volume->range_lock_list_lock);
    261261
     262        fibril_mutex_initialize(&new_volume->deferred_list_lock);
     263        list_initialize(&new_volume->deferred_invalidations_list);
     264
    262265        atomic_init(&new_volume->rebuild_blk, 0);
    263266
  • uspace/srv/bd/hr/raid1.c

    r58d82fa r5ee041e  
    5656extern loc_srv_t *hr_srv;
    5757
     58static void process_deferred_invalidations(hr_volume_t *);
    5859static void hr_raid1_update_vol_status(hr_volume_t *);
    5960static void hr_raid1_ext_state_callback(hr_volume_t *, size_t, errno_t);
     
    225226}
    226227
     228static void process_deferred_invalidations(hr_volume_t *vol)
     229{
     230        HR_DEBUG("hr_raid1_update_vol_status(): deferred invalidations\n");
     231
     232        fibril_mutex_lock(&vol->halt_lock);
     233        vol->halt_please = true;
     234        fibril_rwlock_write_lock(&vol->extents_lock);
     235        fibril_rwlock_write_lock(&vol->states_lock);
     236        fibril_mutex_lock(&vol->hotspare_lock);
     237
     238        list_foreach(vol->deferred_invalidations_list, link,
     239            hr_deferred_invalidation_t, di) {
     240                assert(vol->extents[di->index].status == HR_EXT_INVALID);
     241
     242                HR_DEBUG("moving invalidated extent no. %lu to hotspares\n",
     243                    di->index);
     244
     245                block_fini(di->svc_id);
     246
     247                size_t hs_idx = vol->hotspare_no;
     248
     249                vol->hotspare_no++;
     250
     251                vol->hotspares[hs_idx].svc_id = di->svc_id;
     252                hr_update_hotspare_status(vol, hs_idx, HR_EXT_HOTSPARE);
     253
     254                vol->extents[di->index].svc_id = 0;
     255                hr_update_ext_status(vol, di->index, HR_EXT_MISSING);
     256
     257                assert(vol->hotspare_no < HR_MAX_HOTSPARES + HR_MAX_EXTENTS);
     258        }
     259
     260        for (size_t i = 0; i < HR_MAX_EXTENTS; i++) {
     261                hr_deferred_invalidation_t *di = &vol->deferred_inval[i];
     262                if (di->svc_id != 0) {
     263                        list_remove(&di->link);
     264                        di->svc_id = 0;
     265                }
     266        }
     267
     268        fibril_mutex_unlock(&vol->hotspare_lock);
     269        fibril_rwlock_write_unlock(&vol->states_lock);
     270        fibril_rwlock_write_unlock(&vol->extents_lock);
     271        vol->halt_please = false;
     272        fibril_mutex_unlock(&vol->halt_lock);
     273}
     274
    227275static void hr_raid1_update_vol_status(hr_volume_t *vol)
    228276{
     277        fibril_mutex_lock(&vol->deferred_list_lock);
     278
     279        if (list_count(&vol->deferred_invalidations_list) > 0)
     280                process_deferred_invalidations(vol);
     281
     282        fibril_mutex_unlock(&vol->deferred_list_lock);
     283
    229284        fibril_rwlock_read_lock(&vol->extents_lock);
    230285        fibril_rwlock_read_lock(&vol->states_lock);
     
    279334
    280335        switch (rc) {
     336        case ENOMEM:
     337                fibril_mutex_lock(&vol->deferred_list_lock);
     338
     339                service_id_t invalid_svc_id = vol->extents[extent].svc_id;
     340
     341                list_foreach(vol->deferred_invalidations_list, link,
     342                    hr_deferred_invalidation_t, di) {
     343                        if (di->svc_id == invalid_svc_id) {
     344                                assert(vol->extents[extent].status ==
     345                                    HR_EXT_INVALID);
     346                                goto done;
     347                        }
     348                }
     349
     350                assert(vol->extents[extent].svc_id != HR_EXT_INVALID);
     351
     352                hr_update_ext_status(vol, extent, HR_EXT_INVALID);
     353
     354                size_t i = list_count(&vol->deferred_invalidations_list);
     355                vol->deferred_inval[i].svc_id = invalid_svc_id;
     356                vol->deferred_inval[i].index = extent;
     357
     358                list_append(&vol->deferred_inval[i].link,
     359                    &vol->deferred_invalidations_list);
     360        done:
     361                fibril_mutex_unlock(&vol->deferred_list_lock);
     362                break;
    281363        case ENOENT:
    282364                hr_update_ext_status(vol, extent, HR_EXT_MISSING);
  • uspace/srv/bd/hr/var.h

    r58d82fa r5ee041e  
    5959} hr_ops_t;
    6060
     61typedef struct hr_deferred_invalidation {
     62        link_t link;
     63        size_t index;
     64        service_id_t svc_id;
     65} hr_deferred_invalidation_t;
     66
    6167typedef struct hr_volume {
    6268        hr_ops_t hr_ops;
     
    8995
    9096        size_t hotspare_no;
    91         hr_extent_t hotspares[HR_MAX_HOTSPARES];
     97        hr_extent_t hotspares[HR_MAX_HOTSPARES + HR_MAX_EXTENTS];
    9298
    9399        /* protects hotspares (hotspares.{svc_id,status}, hotspare_no) */
     
    103109        bool halt_please;
    104110        fibril_mutex_t halt_lock;
     111
     112        /*
     113         * For deferring invalidations of extents. Used when
     114         * an extent has to be invalidated (got ENOMEM on a WRITE),
     115         * but workers - therefore state callbacks cannot lock
     116         * extents for writing (they are readers), so invalidations
     117         * are harvested later when we are able to.
     118         */
     119        fibril_mutex_t deferred_list_lock;
     120        list_t deferred_invalidations_list;
     121        hr_deferred_invalidation_t deferred_inval[HR_MAX_EXTENTS];
    105122
    106123        _Atomic uint64_t rebuild_blk;
Note: See TracChangeset for help on using the changeset viewer.