Changeset d84773a in mainline


Ignore:
Timestamp:
2024-10-28T21:46:47Z (7 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
cf28ffd3
Parents:
6124ee1
Message:

hr: RAID 1 state handling

Location:
uspace
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/device/include/hr.h

    r6124ee1 rd84773a  
    5656typedef enum hr_vol_status {
    5757        HR_VOL_ONLINE,  /* OK, OPTIMAL */
    58         HR_VOL_FAULTY
     58        HR_VOL_FAULTY,
     59        HR_VOL_WEAKENED /* used for partial, but usable mirror */
    5960} hr_vol_status_t;
    6061
  • uspace/lib/device/src/hr.c

    r6124ee1 rd84773a  
    275275        case HR_VOL_FAULTY:
    276276                return "FAULTY";
     277        case HR_VOL_WEAKENED:
     278                return "WEAKENED";
    277279        default:
    278280                return "UNKNOWN";
  • uspace/srv/bd/hr/raid1.c

    r6124ee1 rd84773a  
    7373};
    7474
     75static errno_t hr_raid1_check_vol_status(hr_volume_t *vol)
     76{
     77        if (vol->status == HR_VOL_ONLINE ||
     78            vol->status == HR_VOL_WEAKENED)
     79                return EOK;
     80        return EINVAL;
     81}
     82
     83/*
     84 * Update vol->status and return EOK if volume
     85 * is usable
     86 */
     87static errno_t hr_raid1_update_vol_status(hr_volume_t *vol)
     88{
     89        hr_vol_status_t old_state = vol->status;
     90        size_t healthy = 0;
     91        for (size_t i = 0; i < vol->dev_no; i++)
     92                if (vol->extents[i].status == HR_EXT_ONLINE)
     93                        healthy++;
     94
     95        if (healthy == 0) {
     96                if (old_state != HR_VOL_FAULTY) {
     97                        log_msg(LOG_DEFAULT, LVL_ERROR,
     98                            "RAID 1 needs at least 1 extent to be ONLINE, "
     99                            "marking \"%s\" (%lu) as FAULTY",
     100                            vol->devname, vol->svc_id);
     101                        vol->status = HR_VOL_FAULTY;
     102                }
     103                return EINVAL;
     104        } else if (healthy < vol->dev_no) {
     105                if (old_state != HR_VOL_WEAKENED) {
     106                        log_msg(LOG_DEFAULT, LVL_ERROR,
     107                            "RAID 1 array \"%s\" (%lu) has some inactive "
     108                            "extents, marking as WEAKENED",
     109                            vol->devname, vol->svc_id);
     110                        vol->status = HR_VOL_WEAKENED;
     111                }
     112                return EOK;
     113        } else {
     114                if (old_state != HR_VOL_ONLINE) {
     115                        log_msg(LOG_DEFAULT, LVL_ERROR,
     116                            "RAID 1 array \"%s\" (%lu) has all extents active, "
     117                            "marking as ONLINE",
     118                            vol->devname, vol->svc_id);
     119                        vol->status = HR_VOL_ONLINE;
     120                }
     121                return EOK;
     122        }
     123
     124}
     125
    75126static errno_t hr_raid1_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    76127{
     
    83134        log_msg(LOG_DEFAULT, LVL_NOTE, "hr_bd_close()");
    84135        return EOK;
     136}
     137
     138static void handle_extent_error(hr_volume_t *vol, size_t extent,
     139    errno_t rc)
     140{
     141        if (rc == ENOENT)
     142                hr_update_ext_status(vol, extent, HR_EXT_MISSING);
     143        else if (rc != EOK)
     144                hr_update_ext_status(vol, extent, HR_EXT_FAILED);
    85145}
    86146
     
    104164        fibril_mutex_lock(&vol->lock);
    105165
     166        rc = hr_raid1_check_vol_status(vol);
     167        if (rc != EOK) {
     168                fibril_mutex_unlock(&vol->lock);
     169                return EIO;
     170        }
     171
     172        size_t successful = 0;
    106173        switch (type) {
    107174        case HR_BD_SYNC:
    108175                for (i = 0; i < vol->dev_no; i++) {
     176                        if (vol->extents[i].status != HR_EXT_ONLINE)
     177                                continue;
    109178                        rc = block_sync_cache(vol->extents[i].svc_id, ba, cnt);
    110179                        if (rc != EOK)
    111                                 goto error;
     180                                handle_extent_error(vol, i, rc);
     181                        else
     182                                successful++;
    112183                }
    113184                break;
    114185        case HR_BD_READ:
    115186                for (i = 0; i < vol->dev_no; i++) {
     187                        if (vol->extents[i].status != HR_EXT_ONLINE)
     188                                continue;
    116189                        rc = block_read_direct(vol->extents[i].svc_id, ba, cnt,
    117190                            data_read);
    118191                        if (rc != EOK)
    119                                 goto error;
     192                                handle_extent_error(vol, i, rc);
     193                        else
     194                                successful++;
    120195                }
    121196                break;
    122197        case HR_BD_WRITE:
    123198                for (i = 0; i < vol->dev_no; i++) {
     199                        if (vol->extents[i].status != HR_EXT_ONLINE)
     200                                continue;
    124201                        rc = block_write_direct(vol->extents[i].svc_id, ba, cnt,
    125202                            data_write);
    126203                        if (rc != EOK)
    127                                 goto error;
     204                                handle_extent_error(vol, i, rc);
     205                        else
     206                                successful++;
    128207                }
    129208                break;
     
    132211        }
    133212
    134 error:
     213        if (successful > 0)
     214                rc = EOK;
     215        else
     216                rc = EIO;
     217
     218        (void) hr_raid1_update_vol_status(vol);
    135219        fibril_mutex_unlock(&vol->lock);
    136220        return rc;
     
    182266        }
    183267
     268        rc = hr_raid1_update_vol_status(new_volume);
     269        if (rc != EOK)
     270                return rc;
     271
    184272        bd_srvs_init(&new_volume->hr_bds);
    185273        new_volume->hr_bds.ops = &hr_raid1_bd_ops;
Note: See TracChangeset for help on using the changeset viewer.