Changeset b81ae12 in mainline


Ignore:
Timestamp:
2025-06-29T16:27:35Z (3 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
7ef5ea2
Parents:
4a77540
Message:

hr: softraid metadata saving support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/hr/metadata/foreign/softraid/hr_softraid.c

    r4a77540 rb81ae12  
    5656/* not exposed */
    5757static void *meta_softraid_alloc_struct(void);
    58 /* static void meta_softraid_encode(void *, void *); */
     58static void meta_softraid_encode(void *, void *);
    5959static errno_t meta_softraid_decode(const void *, void *);
    6060static errno_t meta_softraid_get_block(service_id_t, void **);
    61 /* static errno_t meta_softraid_write_block(service_id_t, const void *); */
     61static errno_t meta_softraid_write_block(service_id_t, const void *);
    6262
    6363static errno_t meta_softraid_probe(service_id_t, void **);
     
    182182        memcpy(vol->in_mem_md, main_meta, SR_META_SIZE * DEV_BSIZE);
    183183
     184        bool rebuild = false;
    184185        list_foreach(*list, link, struct dev_list_member, iter) {
    185186                struct sr_metadata *iter_meta = iter->md;
     
    191192
    192193                struct sr_meta_chunk *mc =
    193                     (struct sr_meta_chunk *)(main_meta + 1);
    194                 mc += index;
    195 
    196                 /* for now no ssd_rebuild handling for saved REBUILD */
    197                 if (iter_meta->ssd_ondisk == max_counter_val &&
    198                     mc->scm_status != BIOC_SDREBUILD)
     194                    ((struct sr_meta_chunk *)(main_meta + 1)) + index;
     195
     196                bool invalidate = false;
     197
     198                if (iter_meta->ssd_meta_flags & SR_META_DIRTY)
     199                        invalidate = true;
     200                if (iter_meta->ssd_ondisk != max_counter_val)
     201                        invalidate = true;
     202
     203                if (mc->scm_status == BIOC_SDREBUILD && !invalidate) {
     204                        if (rebuild) {
     205                                HR_DEBUG("only 1 rebuilt extent allowed");
     206                                rc = EINVAL;
     207                                goto error;
     208                        }
     209                        rebuild = true;
     210                        vol->rebuild_blk = iter_meta->ssd_rebuild;
     211                }
     212
     213                if (!rebuild && !invalidate)
    199214                        vol->extents[index].state = HR_EXT_ONLINE;
     215                else if (rebuild && !invalidate)
     216                        vol->extents[index].state = HR_EXT_REBUILD;
    200217                else
    201218                        vol->extents[index].state = HR_EXT_INVALID;
     
    224241        const struct sr_metadata *m1 = m1_v;
    225242        const struct sr_metadata *m2 = m2_v;
    226         if (memcmp(&m1->ssdi.ssd_uuid, &m2->ssdi.ssd_uuid,
    227             SR_UUID_MAX) == 0)
     243        if (memcmp(&m1->ssdi.ssd_uuid, &m2->ssdi.ssd_uuid, SR_UUID_MAX) == 0)
    228244                return true;
    229245
     
    246262        HR_DEBUG("%s()", __func__);
    247263
    248         return ENOTSUP;
     264        fibril_rwlock_read_lock(&vol->extents_lock);
     265
     266        for (size_t i = 0; i < vol->extent_no; i++)
     267                meta_softraid_save_ext(vol, i, with_state_callback);
     268
     269        fibril_rwlock_read_unlock(&vol->extents_lock);
     270
     271        return EOK;
    249272}
    250273
     
    254277        HR_DEBUG("%s()", __func__);
    255278
    256         return ENOTSUP;
     279        assert(fibril_rwlock_is_locked(&vol->extents_lock));
     280
     281        void *md_block = hr_calloc_waitok(1, vol->bsize * SR_META_SIZE);
     282
     283        struct sr_metadata *md = vol->in_mem_md;
     284        struct sr_meta_chunk *mc =
     285            ((struct sr_meta_chunk *)(md + 1)) + ext_idx;
     286
     287        hr_extent_t *ext = &vol->extents[ext_idx];
     288
     289        fibril_rwlock_read_lock(&vol->states_lock);
     290        hr_ext_state_t s = ext->state;
     291        fibril_rwlock_read_unlock(&vol->states_lock);
     292
     293        if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) {
     294                return EINVAL;
     295        }
     296
     297        fibril_mutex_lock(&vol->md_lock);
     298
     299        if (s == HR_EXT_REBUILD) {
     300                md->ssd_rebuild = vol->rebuild_blk;
     301                mc->scm_status = BIOC_SDREBUILD;
     302        } else {
     303                md->ssd_rebuild = 0;
     304                mc->scm_status = BIOC_SDONLINE;
     305        }
     306
     307        meta_softraid_encode(md, md_block);
     308        errno_t rc = meta_softraid_write_block(ext->svc_id, md_block);
     309        if (rc != EOK && with_state_callback)
     310                vol->hr_ops.ext_state_cb(vol, ext_idx, rc);
     311
     312        fibril_mutex_unlock(&vol->md_lock);
     313
     314        if (with_state_callback)
     315                vol->hr_ops.vol_state_eval(vol);
     316
     317        free(md_block);
     318        return EOK;
    257319}
    258320
     
    316378}
    317379
    318 #if 0
    319380static void meta_softraid_encode(void *md_v, void *block)
    320381{
    321382        HR_DEBUG("%s()", __func__);
    322383
    323         (void)md_v;
    324         (void)block;
    325 }
    326 #endif
     384        errno_t rc = EOK;
     385        struct sr_metadata *md = md_v;
     386        uint8_t md5_hash[16];
     387
     388        struct sr_metadata *scratch_md =
     389            hr_calloc_waitok(1, SR_META_SIZE * DEV_BSIZE);
     390
     391        scratch_md->ssdi.ssd_magic = host2uint64_t_le(md->ssdi.ssd_magic);
     392        scratch_md->ssdi.ssd_version = host2uint32_t_le(md->ssdi.ssd_version);
     393        scratch_md->ssdi.ssd_vol_flags =
     394            host2uint32_t_le(md->ssdi.ssd_vol_flags);
     395        memcpy(&scratch_md->ssdi.ssd_uuid, &md->ssdi.ssd_uuid, SR_UUID_MAX);
     396        scratch_md->ssdi.ssd_chunk_no =
     397            host2uint32_t_le(md->ssdi.ssd_chunk_no);
     398        scratch_md->ssdi.ssd_chunk_id =
     399            host2uint32_t_le(md->ssdi.ssd_chunk_id);
     400        scratch_md->ssdi.ssd_opt_no = host2uint32_t_le(md->ssdi.ssd_opt_no);
     401        scratch_md->ssdi.ssd_secsize = host2uint32_t_le(md->ssdi.ssd_secsize);
     402        scratch_md->ssdi.ssd_volid = host2uint32_t_le(md->ssdi.ssd_volid);
     403        scratch_md->ssdi.ssd_level = host2uint32_t_le(md->ssdi.ssd_level);
     404        scratch_md->ssdi.ssd_size = host2int64_t_le(md->ssdi.ssd_size);
     405        memcpy(scratch_md->ssdi.ssd_vendor, md->ssdi.ssd_vendor, 8);
     406        memcpy(scratch_md->ssdi.ssd_product, md->ssdi.ssd_product, 16);
     407        memcpy(scratch_md->ssdi.ssd_revision, md->ssdi.ssd_revision, 4);
     408        scratch_md->ssdi.ssd_strip_size =
     409            host2uint32_t_le(md->ssdi.ssd_strip_size);
     410        rc = create_hash((const uint8_t *)&scratch_md->ssdi,
     411            sizeof(struct sr_meta_invariant), md5_hash, HASH_MD5);
     412        assert(rc == EOK);
     413        memcpy(scratch_md->ssd_checksum, md5_hash, MD5_DIGEST_LENGTH);
     414
     415        memcpy(scratch_md->ssd_devname, md->ssd_devname, 32);
     416
     417        scratch_md->ssd_meta_flags = host2uint32_t_le(md->ssd_meta_flags);
     418        scratch_md->ssd_data_blkno = host2uint32_t_le(md->ssd_data_blkno);
     419        scratch_md->ssd_ondisk = host2uint64_t_le(md->ssd_ondisk);
     420        scratch_md->ssd_rebuild = host2int64_t_le(md->ssd_rebuild);
     421
     422        struct sr_meta_chunk *scratch_mc =
     423            (struct sr_meta_chunk *)(scratch_md + 1);
     424        struct sr_meta_chunk *mc = (struct sr_meta_chunk *)(md + 1);
     425        for (size_t i = 0; i < md->ssdi.ssd_chunk_no; i++, mc++, scratch_mc++) {
     426                scratch_mc->scmi.scm_volid =
     427                    host2uint32_t_le(mc->scmi.scm_volid);
     428                scratch_mc->scmi.scm_chunk_id =
     429                    host2uint32_t_le(mc->scmi.scm_chunk_id);
     430                memcpy(scratch_mc->scmi.scm_devname, mc->scmi.scm_devname, 32);
     431                scratch_mc->scmi.scm_size = host2int64_t_le(mc->scmi.scm_size);
     432                scratch_mc->scmi.scm_coerced_size =
     433                    host2int64_t_le(mc->scmi.scm_coerced_size);
     434                memcpy(&scratch_mc->scmi.scm_uuid, &mc->scmi.scm_uuid,
     435                    SR_UUID_MAX);
     436
     437                rc = create_hash((const uint8_t *)&scratch_mc->scmi,
     438                    sizeof(struct sr_meta_chunk_invariant), md5_hash, HASH_MD5);
     439                assert(rc == EOK);
     440
     441                memcpy(scratch_mc->scm_checksum, md5_hash,
     442                    MD5_DIGEST_LENGTH);
     443                scratch_mc->scm_status = host2uint32_t_le(mc->scm_status);
     444        }
     445
     446        struct sr_meta_opt_hdr *scratch_om =
     447            (struct sr_meta_opt_hdr *)((u_int8_t *)(scratch_md + 1) +
     448            sizeof(struct sr_meta_chunk) * md->ssdi.ssd_chunk_no);
     449        struct sr_meta_opt_hdr *om =
     450            (struct sr_meta_opt_hdr *)((u_int8_t *)(md + 1) +
     451            sizeof(struct sr_meta_chunk) * md->ssdi.ssd_chunk_no);
     452        for (size_t i = 0; i < md->ssdi.ssd_opt_no; i++) {
     453                scratch_om->som_type = host2uint32_t_le(om->som_type);
     454                scratch_om->som_length = host2uint32_t_le(om->som_length);
     455                memcpy(scratch_om->som_checksum, om->som_checksum,
     456                    MD5_DIGEST_LENGTH);
     457
     458                /*
     459                 * No need to do checksum, we don't support optional headers.
     460                 * Despite this, still load it the headers.
     461                 */
     462
     463                om = (struct sr_meta_opt_hdr *)((void *)om +
     464                    om->som_length);
     465                scratch_om = (struct sr_meta_opt_hdr *)((void *)scratch_om +
     466                    om->som_length);
     467        }
     468
     469        memcpy(block, scratch_md, meta_softraid_get_size() * 512);
     470
     471        free(scratch_md);
     472}
    327473
    328474static errno_t meta_softraid_decode(const void *block, void *md_v)
     
    396542        memcpy(md->ssd_devname, scratch_md->ssd_devname, 32);
    397543        md->ssd_meta_flags = uint32_t_le2host(scratch_md->ssd_meta_flags);
    398         if (md->ssd_meta_flags & SR_META_DIRTY) {
    399                 HR_DEBUG("dirty metadata not supported\n");
    400                 rc = EINVAL;
    401                 goto error;
    402         }
    403544        md->ssd_data_blkno = uint32_t_le2host(scratch_md->ssd_data_blkno);
    404545        md->ssd_ondisk = uint64_t_le2host(scratch_md->ssd_ondisk);
     
    514655}
    515656
    516 #if 0
    517657static errno_t meta_softraid_write_block(service_id_t dev, const void *block)
    518658{
     
    541681        return rc;
    542682}
    543 #endif
    544683
    545684/** @}
Note: See TracChangeset for help on using the changeset viewer.