Changeset 4a77540 in mainline


Ignore:
Timestamp:
2025-06-29T16:27:07Z (4 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
b81ae12
Parents:
c095ad93
Message:

hr: GEOM Mirror metadata saving support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/hr/metadata/foreign/geom/hr_g_mirror.c

    rc095ad93 r4a77540  
    5656/* not exposed */
    5757static void *meta_gmirror_alloc_struct(void);
    58 /* static void meta_gmirror_encode(void *, void *); */
     58static void meta_gmirror_encode(void *, void *);
    5959static errno_t meta_gmirror_decode(const void *, void *);
    6060static errno_t meta_gmirror_get_block(service_id_t, void **);
    61 /* static errno_t meta_gmirror_write_block(service_id_t, const void *); */
     61static errno_t meta_gmirror_write_block(service_id_t, const void *);
    6262
    6363static errno_t meta_gmirror_probe(service_id_t, void **);
     
    172172        vol->bsize = main_meta->md_sectorsize;
    173173
    174         vol->in_mem_md = calloc(1, sizeof(struct g_mirror_metadata));
     174        vol->in_mem_md =
     175            calloc(vol->extent_no, sizeof(struct g_mirror_metadata));
    175176        if (vol->in_mem_md == NULL)
    176177                return ENOMEM;
    177178        memcpy(vol->in_mem_md, main_meta, sizeof(struct g_mirror_metadata));
    178179
     180        bool rebuild = false;
     181
    179182        uint8_t index = 0;
    180183        list_foreach(*list, link, struct dev_list_member, iter) {
    181184                struct g_mirror_metadata *iter_meta = iter->md;
    182185
     186                struct g_mirror_metadata *p =
     187                    ((struct g_mirror_metadata *)vol->in_mem_md) + index;
     188                memcpy(p, iter_meta, sizeof(*p));
     189
    183190                vol->extents[index].svc_id = iter->svc_id;
    184191                iter->fini = false;
    185192
    186                 /* for now no md_sync_offset handling for saved REBUILD */
    187                 if (iter_meta->md_syncid == max_counter_val)
     193                bool invalidate = false;
     194
     195                if (iter_meta->md_dflags & G_MIRROR_DISK_FLAG_DIRTY)
     196                        invalidate = true;
     197                if (iter_meta->md_syncid != max_counter_val)
     198                        invalidate = true;
     199
     200                if (iter_meta->md_dflags & G_MIRROR_DISK_FLAG_SYNCHRONIZING &&
     201                    !invalidate) {
     202                        if (rebuild) {
     203                                HR_DEBUG("only 1 rebuilt extent allowed");
     204                                rc = EINVAL;
     205                                goto error;
     206                        }
     207                        rebuild = true;
     208                        vol->rebuild_blk = iter_meta->md_sync_offset;
     209                }
     210
     211                if (!rebuild && !invalidate)
    188212                        vol->extents[index].state = HR_EXT_ONLINE;
     213                else if (rebuild && !invalidate)
     214                        vol->extents[index].state = HR_EXT_REBUILD;
    189215                else
    190216                        vol->extents[index].state = HR_EXT_INVALID;
     
    225251        fibril_mutex_lock(&vol->md_lock);
    226252
    227         struct g_mirror_metadata *md = vol->in_mem_md;
    228 
    229         md->md_syncid++;
     253        for (size_t d = 0; d < vol->extent_no; d++) {
     254                struct g_mirror_metadata *md =
     255                    ((struct g_mirror_metadata *)vol->in_mem_md) + d;
     256                md->md_syncid++;
     257        }
    230258
    231259        fibril_mutex_unlock(&vol->md_lock);
     
    236264        HR_DEBUG("%s()", __func__);
    237265
    238         (void)vol;
    239         (void)with_state_callback;
    240 
    241         /*
    242          * cannot support right now, because would need to store the
    243          * metadata for all disks, because of hardcoded provider names and
    244          * more importantly, disk unique ids
    245          */
    246 
    247         return ENOTSUP;
     266        fibril_rwlock_read_lock(&vol->extents_lock);
     267
     268        for (size_t i = 0; i < vol->extent_no; i++)
     269                meta_gmirror_save_ext(vol, i, with_state_callback);
     270
     271        fibril_rwlock_read_unlock(&vol->extents_lock);
     272
     273        return EOK;
    248274}
    249275
     
    253279        HR_DEBUG("%s()", __func__);
    254280
    255         return ENOTSUP;
     281        assert(fibril_rwlock_is_locked(&vol->extents_lock));
     282
     283        void *md_block = hr_calloc_waitok(1, vol->bsize);
     284
     285        struct g_mirror_metadata *md =
     286            ((struct g_mirror_metadata *)vol->in_mem_md) + ext_idx;
     287
     288        hr_extent_t *ext = &vol->extents[ext_idx];
     289
     290        fibril_rwlock_read_lock(&vol->states_lock);
     291        hr_ext_state_t s = ext->state;
     292        fibril_rwlock_read_unlock(&vol->states_lock);
     293
     294        if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) {
     295                return EINVAL;
     296        }
     297
     298        fibril_mutex_lock(&vol->md_lock);
     299
     300        if (s == HR_EXT_REBUILD) {
     301                md->md_sync_offset = vol->rebuild_blk;
     302                md->md_dflags |= G_MIRROR_DISK_FLAG_SYNCHRONIZING;
     303        } else {
     304                md->md_sync_offset = 0;
     305                md->md_dflags &= ~(G_MIRROR_DISK_FLAG_SYNCHRONIZING);
     306        }
     307
     308        meta_gmirror_encode(md, md_block);
     309        errno_t rc = meta_gmirror_write_block(ext->svc_id, md_block);
     310        if (rc != EOK && with_state_callback)
     311                vol->hr_ops.ext_state_cb(vol, ext_idx, rc);
     312
     313        fibril_mutex_unlock(&vol->md_lock);
     314
     315        if (with_state_callback)
     316                vol->hr_ops.vol_state_eval(vol);
     317
     318        free(md_block);
     319        return EOK;
    256320}
    257321
     
    303367        return calloc(1, sizeof(struct g_mirror_metadata));
    304368}
    305 
    306 #if 0
    307369static void meta_gmirror_encode(void *md_v, void *block)
    308370{
     
    311373        mirror_metadata_encode(md_v, block);
    312374}
    313 #endif
    314375
    315376static errno_t meta_gmirror_decode(const void *block, void *md_v)
     
    366427}
    367428
    368 #if 0
    369429static errno_t meta_gmirror_write_block(service_id_t dev, const void *block)
    370430{
     
    393453        return rc;
    394454}
    395 #endif
    396455
    397456/** @}
Note: See TracChangeset for help on using the changeset viewer.