Changeset 7ef5ea2 in mainline


Ignore:
Timestamp:
2025-06-29T23:21:19Z (3 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
640250b
Parents:
b81ae12
Message:

hr: encoding and saving MD metadata support

Location:
uspace/srv/bd/hr/metadata/foreign/md
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/hr/metadata/foreign/md/hr_md.c

    rb81ae12 r7ef5ea2  
    5555/* not exposed */
    5656static void *meta_md_alloc_struct(void);
    57 /* static void meta_md_encode(void *, void *); */
     57static void meta_md_encode(void *, void *);
    5858static errno_t meta_md_decode(const void *, void *);
    5959static errno_t meta_md_get_block(service_id_t, void **);
    60 /* static errno_t meta_md_write_block(service_id_t, const void *); */
     60static errno_t meta_md_write_block(service_id_t, const void *);
    6161
    6262static errno_t meta_md_probe(service_id_t, void **);
     
    190190        vol->strip_size = main_meta->chunksize * 512;
    191191
    192         vol->in_mem_md = calloc(1, MD_SIZE * 512);
     192        vol->in_mem_md = calloc(vol->extent_no, MD_SIZE * 512);
    193193        if (vol->in_mem_md == NULL)
    194194                return ENOMEM;
    195         memcpy(vol->in_mem_md, main_meta, MD_SIZE * 512);
    196 
     195
     196        size_t i = 0;
    197197        list_foreach(*list, link, struct dev_list_member, iter) {
    198198                struct mdp_superblock_1 *iter_meta = iter->md;
     
    200200                uint8_t index = iter_meta->dev_roles[iter_meta->dev_number];
    201201
     202                struct mdp_superblock_1 *p = (struct mdp_superblock_1 *)
     203                    (((char *)vol->in_mem_md) + MD_SIZE * 512 * index);
     204                memcpy(p, iter_meta, MD_SIZE * 512);
     205
    202206                vol->extents[index].svc_id = iter->svc_id;
    203207                iter->fini = false;
    204208
    205                 if (iter_meta->events == max_events && index < vol->extent_no)
     209                bool invalidate = false;
     210
     211                if (iter_meta->events != max_events)
     212                        invalidate = true;
     213
     214                if (iter_meta->feature_map & MD_DISK_SYNC)
     215                        invalidate = true;
     216
     217                if (!invalidate)
    206218                        vol->extents[index].state = HR_EXT_ONLINE;
    207219                else
    208220                        vol->extents[index].state = HR_EXT_INVALID;
     221
     222                i++;
     223                if (i == vol->extent_no)
     224                        break;
    209225        }
    210226
     
    240256        fibril_mutex_lock(&vol->md_lock);
    241257
    242         struct mdp_superblock_1 *md = vol->in_mem_md;
    243 
    244         md->events++;
     258        for (size_t d = 0; d < vol->extent_no; d++) {
     259                struct mdp_superblock_1 *md = (struct mdp_superblock_1 *)
     260                    (((uint8_t *)vol->in_mem_md) + MD_SIZE * 512 * d);
     261                md->events++;
     262        }
    245263
    246264        fibril_mutex_unlock(&vol->md_lock);
     
    251269        HR_DEBUG("%s()", __func__);
    252270
    253         return ENOTSUP;
     271        fibril_rwlock_read_lock(&vol->extents_lock);
     272
     273        for (size_t i = 0; i < vol->extent_no; i++)
     274                meta_md_save_ext(vol, i, with_state_callback);
     275
     276        fibril_rwlock_read_unlock(&vol->extents_lock);
     277
     278        return EOK;
    254279}
    255280
     
    259284        HR_DEBUG("%s()", __func__);
    260285
    261         return ENOTSUP;
     286        assert(fibril_rwlock_is_locked(&vol->extents_lock));
     287
     288        void *md_block = hr_calloc_waitok(1, MD_SIZE * 512);
     289
     290        struct mdp_superblock_1 *md = (struct mdp_superblock_1 *)
     291            (((uint8_t *)vol->in_mem_md) + MD_SIZE * 512 * ext_idx);
     292
     293        hr_extent_t *ext = &vol->extents[ext_idx];
     294
     295        fibril_rwlock_read_lock(&vol->states_lock);
     296        hr_ext_state_t s = ext->state;
     297        fibril_rwlock_read_unlock(&vol->states_lock);
     298
     299        if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) {
     300                return EINVAL;
     301        }
     302
     303        fibril_mutex_lock(&vol->md_lock);
     304
     305        if (s == HR_EXT_REBUILD) {
     306                md->resync_offset = vol->rebuild_blk;
     307                md->feature_map = MD_DISK_SYNC;
     308        } else {
     309                md->resync_offset = 0;
     310                md->feature_map = 0;
     311        }
     312
     313        meta_md_encode(md, md_block);
     314        errno_t rc = meta_md_write_block(ext->svc_id, md_block);
     315        if (rc != EOK && with_state_callback)
     316                vol->hr_ops.ext_state_cb(vol, ext_idx, rc);
     317
     318        fibril_mutex_unlock(&vol->md_lock);
     319
     320        if (with_state_callback)
     321                vol->hr_ops.vol_state_eval(vol);
     322
     323        free(md_block);
     324
     325        return EOK;
    262326}
    263327
     
    353417        printf("dev_number: %" PRIu32 "\n", md->dev_number);
    354418
    355         printf("cnt_corrected_read: %" PRIu32 "\n", md->cnt_corrected_read);
    356 
    357419        printf("device_uuid: ");
    358420        bytefield_print(md->device_uuid, 16);
    359421        printf("\n");
    360 
    361         printf("devflags: 0x%" PRIx8 "\n", md->devflags);
    362422
    363423        printf("events: %" PRIu64 "\n", md->events);
     
    367427        else
    368428                printf("resync_offset: %" PRIu64 "\n", md->resync_offset);
    369 
    370         printf("sb_csum: 0x%" PRIx32 "\n", md->sb_csum);
    371429
    372430        printf("max_dev: %" PRIu32 "\n", md->max_dev);
     
    387445}
    388446
    389 #if 0
    390447static void meta_md_encode(void *md_v, void *block)
    391448{
    392449        HR_DEBUG("%s()", __func__);
    393450
    394         (void)md_v;
    395         (void)block;
    396 }
    397 #endif
     451        memcpy(block, md_v, meta_md_get_size() * 512);
     452
     453        struct mdp_superblock_1 *md = block;
     454
     455        md->magic = host2uint32_t_le(md->magic);
     456        md->major_version = host2uint32_t_le(md->major_version);
     457        md->feature_map = host2uint32_t_le(md->feature_map);
     458        md->level = host2uint32_t_le(md->level);
     459        md->layout = host2uint32_t_le(md->layout);
     460        md->size = host2uint64_t_le(md->size);
     461        md->chunksize = host2uint32_t_le(md->chunksize);
     462        md->raid_disks = host2uint32_t_le(md->raid_disks);
     463        md->data_offset = host2uint64_t_le(md->data_offset);
     464        md->data_size = host2uint64_t_le(md->data_size);
     465        md->super_offset = host2uint64_t_le(md->super_offset);
     466        md->dev_number = host2uint32_t_le(md->dev_number);
     467        md->events = host2uint64_t_le(md->events);
     468        md->resync_offset = host2uint64_t_le(md->resync_offset);
     469        md->max_dev = host2uint32_t_le(md->max_dev);
     470        for (uint32_t d = 0; d < md->max_dev; d++)
     471                md->dev_roles[d] = host2uint16_t_le(md->dev_roles[d]);
     472
     473        md->sb_csum = calc_sb_1_csum(md);
     474}
    398475
    399476static errno_t meta_md_decode(const void *block, void *md_v)
     
    404481        struct mdp_superblock_1 *md = md_v;
    405482
    406         struct mdp_superblock_1 *scratch_md = meta_md_alloc_struct();
    407         if (scratch_md == NULL)
    408                 return ENOMEM;
    409 
    410         memcpy(scratch_md, block, meta_md_get_size() * 512);
    411 
    412         md->magic = uint32_t_le2host(scratch_md->magic);
     483        /*
     484         * Do in-place decoding to cpu byte order.
     485         * We do it like this because:
     486         * 1) we do not know what is after the 256 bytes
     487         * of the struct, so we write back what was there
     488         * previously,
     489         * 2) we do not want to deal unused fields such
     490         * as unions and so on.
     491         */
     492        memcpy(md, block, meta_md_get_size() * 512);
     493
     494        md->magic = uint32_t_le2host(md->magic);
    413495        if (md->magic != MD_MAGIC) {
    414496                rc = EINVAL;
     
    416498        }
    417499
    418         md->major_version = uint32_t_le2host(scratch_md->major_version);
     500        md->major_version = uint32_t_le2host(md->major_version);
    419501        if (md->major_version != 1) {
    420502                HR_DEBUG("unsupported metadata version\n");
     
    423505        }
    424506
    425         md->feature_map = uint32_t_le2host(scratch_md->feature_map);
     507        md->feature_map = uint32_t_le2host(md->feature_map);
     508        /* XXX: do not even support MD_DISK_SYNC here */
    426509        if (md->feature_map != 0x0) {
    427510                HR_DEBUG("unsupported feature map bits\n");
     
    430513        }
    431514
    432         memcpy(md->set_uuid, scratch_md->set_uuid, 16);
    433 
    434         memcpy(md->set_name, scratch_md->set_name, 32);
    435 
    436         md->ctime = uint64_t_le2host(scratch_md->ctime);
    437 
    438         md->level = uint32_t_le2host(scratch_md->level);
     515        md->level = uint32_t_le2host(md->level);
    439516        switch (md->level) {
    440517        case 0:
     
    449526        }
    450527
    451         md->layout = uint32_t_le2host(scratch_md->layout);
     528        md->layout = uint32_t_le2host(md->layout);
    452529        if (md->level == 5) {
    453530                switch (md->layout) {
     
    469546        }
    470547
    471         md->size = uint64_t_le2host(scratch_md->size);
    472 
    473         md->chunksize = uint32_t_le2host(scratch_md->chunksize);
    474 
    475         md->raid_disks = uint32_t_le2host(scratch_md->raid_disks);
     548        md->size = uint64_t_le2host(md->size);
     549
     550        md->chunksize = uint32_t_le2host(md->chunksize);
     551
     552        md->raid_disks = uint32_t_le2host(md->raid_disks);
    476553        if (md->raid_disks > HR_MAX_EXTENTS) {
    477554                rc = EINVAL;
     
    479556        }
    480557
    481         md->data_offset = uint64_t_le2host(scratch_md->data_offset);
    482 
    483         md->data_size = uint64_t_le2host(scratch_md->data_size);
     558        md->data_offset = uint64_t_le2host(md->data_offset);
     559
     560        md->data_size = uint64_t_le2host(md->data_size);
    484561        if (md->data_size != md->size) {
    485562                rc = EINVAL;
     
    487564        }
    488565
    489         md->super_offset = uint64_t_le2host(scratch_md->super_offset);
     566        md->super_offset = uint64_t_le2host(md->super_offset);
    490567        if (md->super_offset != MD_OFFSET) {
    491568                rc = EINVAL;
     
    493570        }
    494571
    495         md->dev_number = uint32_t_le2host(scratch_md->dev_number);
    496 
    497         md->cnt_corrected_read =
    498             uint32_t_le2host(scratch_md->cnt_corrected_read);
    499 
    500         memcpy(md->device_uuid, scratch_md->device_uuid, 16);
    501 
    502         md->devflags = scratch_md->devflags;
    503 
    504         md->bblog_shift = scratch_md->bblog_shift;
    505 
    506         md->bblog_size = uint16_t_le2host(scratch_md->bblog_size);
    507 
    508         md->bblog_offset = uint32_t_le2host(scratch_md->bblog_offset);
    509 
    510         md->utime = uint64_t_le2host(scratch_md->utime);
    511 
    512         md->events = uint64_t_le2host(scratch_md->events);
    513 
    514         md->resync_offset = uint64_t_le2host(scratch_md->resync_offset);
    515         if (md->resync_offset != ~(0ULL)) {
    516                 rc = EINVAL;
    517                 goto error;
    518         }
    519 
    520         md->sb_csum = uint32_t_le2host(scratch_md->sb_csum);
    521 
    522         md->max_dev = uint32_t_le2host(scratch_md->max_dev);
     572        md->dev_number = uint32_t_le2host(md->dev_number);
     573
     574        md->events = uint64_t_le2host(md->events);
     575
     576        md->resync_offset = uint64_t_le2host(md->resync_offset);
     577        if (md->feature_map == 0 && md->resync_offset != ~(0ULL)) {
     578                rc = EINVAL;
     579                goto error;
     580        }
     581
     582        md->max_dev = uint32_t_le2host(md->max_dev);
    523583        if (md->max_dev > 256 + 128) {
    524584                rc = EINVAL;
     
    527587
    528588        for (uint32_t d = 0; d < md->max_dev; d++)
    529                 md->dev_roles[d] = uint16_t_le2host(scratch_md->dev_roles[d]);
     589                md->dev_roles[d] = uint16_t_le2host(md->dev_roles[d]);
    530590
    531591error:
    532         free(scratch_md);
    533 
    534592        return rc;
    535593}
     
    575633}
    576634
    577 #if 0
    578635static errno_t meta_md_write_block(service_id_t dev, const void *block)
    579636{
     
    602659        return rc;
    603660}
    604 #endif
    605661
    606662/** @}
  • uspace/srv/bd/hr/metadata/foreign/md/md_p.h

    rb81ae12 r7ef5ea2  
    3333
    3434#define MD_MAGIC 0xa92b4efc
     35
     36#define MD_DISK_SYNC 2
    3537
    3638/*
     
    130132};
    131133
    132 /* from mdadm.h */
     134/*
     135 * mdadm - manage Linux "md" devices aka RAID arrays.
     136 *
     137 * Copyright (C) 2001-2016 Neil Brown <neilb@suse.com>
     138 *
     139 *
     140 *    This program is free software; you can redistribute it and/or modify
     141 *    it under the terms of the GNU General Public License as published by
     142 *    the Free Software Foundation; either version 2 of the License, or
     143 *    (at your option) any later version.
     144 *
     145 *    This program is distributed in the hope that it will be useful,
     146 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
     147 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     148 *    GNU General Public License for more details.
     149 *
     150 *    You should have received a copy of the GNU General Public License
     151 *    along with this program; if not, write to the Free Software
     152 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     153 *
     154 *    Author: Neil Brown
     155 *    Email: <neilb@suse.de>
     156 */
     157
     158/* from mdadm - mdadm.h*/
    133159#define ALGORITHM_LEFT_ASYMMETRIC       0
    134160#define ALGORITHM_RIGHT_ASYMMETRIC      1
    135161#define ALGORITHM_LEFT_SYMMETRIC        2
     162
     163/* from mdadm - super1.c */
     164static inline unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
     165{
     166        unsigned int disk_csum, csum;
     167        unsigned long long newcsum;
     168        int size = sizeof(*sb) + uint32_t_le2host(sb->max_dev)*2;
     169        unsigned int *isuper = (unsigned int *)sb;
     170
     171/* make sure I can count... */
     172        if (offsetof(struct mdp_superblock_1,data_offset) != 128 ||
     173            offsetof(struct mdp_superblock_1, utime) != 192 ||
     174            sizeof(struct mdp_superblock_1) != 256) {
     175                fprintf(stderr, "WARNING - superblock isn't sized correctly\n");
     176        }
     177
     178        disk_csum = sb->sb_csum;
     179        sb->sb_csum = 0;
     180        newcsum = 0;
     181        for (; size >= 4; size -= 4) {
     182                newcsum += uint32_t_le2host(*isuper);
     183                isuper++;
     184        }
     185
     186        if (size == 2)
     187                newcsum += uint32_t_le2host(*(unsigned short*) isuper);
     188
     189        csum = (newcsum & 0xffffffff) + (newcsum >> 32);
     190        sb->sb_csum = disk_csum;
     191        return host2uint32_t_le(csum);
     192}
    136193
    137194#endif
Note: See TracChangeset for help on using the changeset viewer.