Changeset 800d188 in mainline


Ignore:
Timestamp:
2025-04-15T07:00:31Z (2 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
29e7cc7
Parents:
ca7fa5b
git-author:
Miroslav Cimerman <mc@…> (2025-04-15 06:55:25)
git-committer:
Miroslav Cimerman <mc@…> (2025-04-15 07:00:31)
Message:

hr: metadata saving on stop

New bool argument for hr_metadata_save() to indicate if
we want callback too (on array stop we don't, so we won't
init a rebuild).

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

Legend:

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

    rca7fa5b r800d188  
    146146                goto error;
    147147
    148         rc = hr_metadata_save(new_volume);
    149         if (rc != EOK)
    150                 goto error;
    151 
    152148        rc = new_volume->hr_ops.create(new_volume);
     149        if (rc != EOK)
     150                goto error;
     151
     152        rc = hr_metadata_save(new_volume, WITH_STATE_CALLBACK);
    153153        if (rc != EOK)
    154154                goto error;
  • uspace/srv/bd/hr/io.c

    rca7fa5b r800d188  
    4545#include "var.h"
    4646
     47static errno_t exec_io_op(hr_io_t *);
     48
    4749errno_t hr_io_worker(void *arg)
    4850{
    4951        hr_io_t *io = arg;
     52
     53        errno_t rc = exec_io_op(io);
     54
     55        /*
     56         * We don't have to invalidate extents who got ENOMEM
     57         * on READ/SYNC. But when we get ENOMEM on a WRITE, we have
     58         * to invalidate it, because there could have been
     59         * other writes, there is no way to rollback.
     60         */
     61        if (rc != EOK && (rc != ENOMEM || io->type == HR_BD_WRITE))
     62                io->vol->state_callback(io->vol, io->extent, rc);
     63
     64        return rc;
     65}
     66
     67errno_t hr_io_worker_basic(void *arg)
     68{
     69        hr_io_t *io = arg;
     70
     71        errno_t rc = exec_io_op(io);
     72
     73        return rc;
     74}
     75
     76static errno_t exec_io_op(hr_io_t *io)
     77{
     78        size_t ext_idx = io->extent;
    5079        hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
    51         size_t ext_idx = io->extent;
    5280        errno_t rc;
    5381
     
    90118        HR_DEBUG("WORKER (%p) rc: %s\n", io, str_error(rc));
    91119
    92         /*
    93          * We don't have to invalidate extents who got ENOMEM
    94          * on READ/SYNC. But when we get ENOMEM on a WRITE, we have
    95          * to invalidate it, because there could have been
    96          * other writes, there is no way to rollback.
    97          */
    98         if (rc != EOK && (rc != ENOMEM || io->type == HR_BD_WRITE))
    99                 io->state_callback(io->vol, io->extent, rc);
    100 
    101120        return rc;
    102121}
  • uspace/srv/bd/hr/io.h

    rca7fa5b r800d188  
    4747        const void      *data_write;
    4848        hr_volume_t     *vol;
    49         void            (*state_callback)(hr_volume_t *, size_t, errno_t);
    5049} hr_io_t;
    5150
    5251errno_t hr_io_worker(void *);
     52errno_t hr_io_worker_basic(void *);
    5353
    5454#endif
  • uspace/srv/bd/hr/raid0.c

    rca7fa5b r800d188  
    5454
    5555static void     hr_raid0_update_vol_status(hr_volume_t *);
    56 static void     raid0_state_callback(hr_volume_t *, size_t, errno_t);
     56static void     hr_raid0_state_callback(hr_volume_t *, size_t, errno_t);
    5757static errno_t  hr_raid0_bd_op(hr_bd_op_type_t, bd_srv_t *, aoff64_t, size_t,
    5858    void *, const void *, size_t);
     
    100100        new_volume->hr_bds.sarg = new_volume;
    101101
     102        new_volume->state_callback = hr_raid0_state_callback;
     103
    102104        return EOK;
    103105}
     
    196198static void hr_raid0_update_vol_status(hr_volume_t *vol)
    197199{
     200        fibril_mutex_lock(&vol->md_lock);
     201
     202        /* XXX: will be wrapped in md specific fcn ptrs */
     203        vol->in_mem_md->counter++;
     204
     205        fibril_mutex_unlock(&vol->md_lock);
     206
    198207        fibril_rwlock_read_lock(&vol->states_lock);
    199208
     
    221230}
    222231
    223 static void raid0_state_callback(hr_volume_t *vol, size_t extent, errno_t rc)
     232static void hr_raid0_state_callback(hr_volume_t *vol, size_t extent, errno_t rc)
    224233{
    225234        if (rc == EOK)
     
    272281                        io->type = type;
    273282                        io->vol = vol;
    274                         io->state_callback = raid0_state_callback;
    275283
    276284                        hr_fgroup_submit(group, hr_io_worker, io);
     
    326334                io->type = type;
    327335                io->vol = vol;
    328                 io->state_callback = raid0_state_callback;
    329336
    330337                hr_fgroup_submit(group, hr_io_worker, io);
  • uspace/srv/bd/hr/raid1.c

    rca7fa5b r800d188  
    105105        new_volume->hr_bds.sarg = new_volume;
    106106
     107        new_volume->state_callback = hr_raid1_ext_state_callback;
     108
    107109        /* force volume state update */
    108110        hr_mark_vol_state_dirty(new_volume);
     
    222224        if (!atomic_compare_exchange_strong(&vol->state_dirty, &exp, false))
    223225                return;
     226
     227        fibril_mutex_lock(&vol->md_lock);
     228
     229        /* XXX: will be wrapped in md specific fcn ptrs */
     230        vol->in_mem_md->counter++;
     231
     232        fibril_mutex_unlock(&vol->md_lock);
    224233
    225234        fibril_rwlock_read_lock(&vol->extents_lock);
     
    247256
    248257                if (old_state != HR_VOL_REBUILD) {
     258                        /* XXX: allow REBUILD on INVALID extents */
    249259                        if (vol->hotspare_no > 0) {
    250260                                fid_t fib = fibril_create(hr_raid1_rebuild,
     
    427437                        io->type = type;
    428438                        io->vol = vol;
    429                         io->state_callback = hr_raid1_ext_state_callback;
    430439
    431440                        hr_fgroup_submit(group, hr_io_worker, io);
     
    541550        fibril_rwlock_write_unlock(&vol->states_lock);
    542551
    543         rc = hr_metadata_save(vol);
     552        rc = hr_metadata_save(vol, WITH_STATE_CALLBACK);
    544553
    545554end:
     
    576585        fibril_mutex_lock(&vol->hotspare_lock);
    577586
     587        /* XXX: allow REBUILD on INVALID extents */
    578588        if (vol->hotspare_no == 0) {
    579589                HR_WARN("hr_raid1_rebuild(): no free hotspares on \"%s\", "
  • uspace/srv/bd/hr/raid5.c

    rca7fa5b r800d188  
    845845        hr_update_ext_status(vol, bad, HR_EXT_ONLINE);
    846846
    847         rc = hr_metadata_save(vol);
     847        rc = hr_metadata_save(vol, WITH_STATE_CALLBACK);
    848848
    849849end:
  • uspace/srv/bd/hr/superblock.c

    rca7fa5b r800d188  
    8888
    8989/*
    90  * TODO: think about thread safety, if hr_metadata_save() can
    91  * be called from multiple threads, and if, maybe will need
    92  * md_lock... or whatever, but dont want to stall I/Os...
    93  */
    94 errno_t hr_metadata_save(hr_volume_t *vol)
     90 * XXX: finish this fcn documentation
     91 *
     92 * Returns ENOMEM else EOK
     93 */
     94errno_t hr_metadata_save(hr_volume_t *vol, bool with_state_callback)
    9595{
    9696        HR_DEBUG("%s()", __func__);
     
    102102                return ENOMEM;
    103103
     104        fibril_rwlock_read_lock(&vol->extents_lock);
     105
     106        fibril_mutex_lock(&vol->md_lock);
     107
    104108        for (size_t i = 0; i < vol->extent_no; i++) {
    105109                hr_extent_t *ext = &vol->extents[i];
     110
     111                fibril_rwlock_read_lock(&vol->states_lock);
    106112
    107113                /* TODO: special case for REBUILD */
     
    109115                        continue;
    110116
     117                fibril_rwlock_read_unlock(&vol->states_lock);
     118
    111119                vol->in_mem_md->index = i;
    112120                hr_encode_metadata_to_block(vol->in_mem_md, md_block);
    113121                rc = hr_write_metadata_block(ext->svc_id, md_block);
    114                 /*
    115                  * XXX: here maybe call vol status event or the state
    116                  * callback inside, same with read_block...
    117                  *
    118                  * also think about using FGE here... maybe a bit more
    119                  * code, but faster and gratis state callback :-)
    120                  */
    121                 if (rc != EOK)
    122                         goto error;
     122                if (with_state_callback && rc != EOK)
     123                        vol->state_callback(vol, i, rc);
    123124        }
    124125
    125 error:
     126        fibril_mutex_unlock(&vol->md_lock);
     127
     128        fibril_rwlock_read_unlock(&vol->extents_lock);
     129
     130        if (with_state_callback)
     131                vol->hr_ops.status_event(vol);
     132
    126133        free(md_block);
    127         return rc;
     134        return EOK;
    128135}
    129136
     
    161168
    162169        rc = block_write_direct(dev, blkno - 1, HR_META_SIZE, block);
    163         /*
    164          * XXX: here maybe call vol status event or the state callback...
    165          *
    166          * but need to pass vol pointer
    167          */
    168170
    169171        return rc;
  • uspace/srv/bd/hr/superblock.h

    rca7fa5b r800d188  
    8080
    8181extern errno_t  hr_metadata_init(hr_volume_t *, hr_metadata_t *);
    82 extern errno_t  hr_metadata_save(hr_volume_t *);
     82extern errno_t  hr_metadata_save(hr_volume_t *, bool);
    8383extern errno_t  hr_write_metadata_block(service_id_t, const void *);
    8484extern errno_t  hr_get_metadata_block(service_id_t, void **);
  • uspace/srv/bd/hr/util.c

    rca7fa5b r800d188  
    145145        fibril_mutex_initialize(&vol->lock); /* XXX: will remove this */
    146146
     147        fibril_mutex_initialize(&vol->md_lock);
     148
    147149        fibril_rwlock_initialize(&vol->extents_lock);
    148150        fibril_rwlock_initialize(&vol->states_lock);
     
    219221                        fibril_rwlock_write_unlock(&hr_volumes_lock);
    220222
     223                        hr_metadata_save(vol, NO_STATE_CALLBACK);
     224
    221225                        hr_destroy_vol_struct(vol);
    222226
     
    843847        vol->in_mem_md->counter++;
    844848
    845         hr_metadata_save(vol);
    846 
    847849        rc = vol->hr_ops.create(vol);
    848850        if (rc != EOK)
    849851                goto error;
     852
     853        hr_metadata_save(vol, WITH_STATE_CALLBACK);
    850854
    851855        fibril_rwlock_write_lock(&hr_volumes_lock);
  • uspace/srv/bd/hr/var.h

    rca7fa5b r800d188  
    8383
    8484        hr_metadata_t   *in_mem_md;
     85        fibril_mutex_t   md_lock;               /* lock protecting in_mem_md */
    8586
    8687        /* invariants */
     
    111112        _Atomic int      open_cnt;              /* open/close() counter */
    112113        hr_vol_status_t  status;                /* volume status */
     114        void             (*state_callback)(hr_volume_t *, size_t, errno_t);
    113115} hr_volume_t;
    114116
     
    118120        HR_BD_WRITE
    119121} hr_bd_op_type_t;
     122
     123/* macros for hr_metadata_save() */
     124#define WITH_STATE_CALLBACK true
     125#define NO_STATE_CALLBACK false
    120126
    121127typedef struct hr_range_lock {
Note: See TracChangeset for help on using the changeset viewer.