Changeset 978130a in mainline for uspace/srv/bd/hr/raid4.c


Ignore:
Timestamp:
2024-10-28T16:03:24Z (15 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
4dd650a
Parents:
76cd345
Message:

hr: optimize RAID 0, 4, 5 to write whole strip

File:
1 edited

Legend:

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

    r76cd345 r978130a  
    4343#include <ipc/services.h>
    4444#include <loc.h>
     45#include <mem.h>
    4546#include <task.h>
    4647#include <stdio.h>
     
    8586
    8687static errno_t write_parity(hr_volume_t *vol, uint64_t extent, uint64_t block,
    87     const void *data)
    88 {
    89         errno_t rc;
    90         size_t i;
     88    const void *data, size_t cnt)
     89{
     90        errno_t rc;
     91        size_t i, j;
    9192        void *xorbuf;
    9293        void *buf;
    9394
    94         xorbuf = calloc(1, vol->bsize);
     95        xorbuf = malloc(vol->bsize);
    9596        if (xorbuf == NULL)
    9697                return ENOMEM;
     
    102103        }
    103104
    104         for (i = 1; i < vol->dev_no; i++) {
    105                 if (i == extent) {
    106                         xor(xorbuf, data, vol->bsize);
    107                 } else {
    108                         rc = block_read_direct(vol->extents[i].svc_id, block, 1,
    109                             buf);
    110                         if (rc != EOK)
    111                                 goto end;
    112                         xor(xorbuf, buf, vol->bsize);
     105        for (j = 0; j < cnt; j++) {
     106                memset(xorbuf, 0, vol->bsize);
     107                for (i = 1; i < vol->dev_no; i++) {
     108                        if (i == extent) {
     109                                xor(xorbuf, data, vol->bsize);
     110                        } else {
     111                                rc = block_read_direct(vol->extents[i].svc_id,
     112                                    block, 1, buf);
     113                                if (rc != EOK)
     114                                        goto end;
     115                                xor(xorbuf, buf, vol->bsize);
     116                        }
    113117                }
    114         }
    115 
    116         rc = block_write_direct(vol->extents[0].svc_id, block, 1, xorbuf);
    117 
     118                rc = block_write_direct(vol->extents[0].svc_id, block, 1,
     119                    xorbuf);
     120                if (rc != EOK)
     121                        goto end;
     122                data = (void *) ((uintptr_t) data + vol->bsize);
     123                block++;
     124        }
    118125end:
    119126        free(xorbuf);
     
    122129}
    123130
    124 static void raid4_geometry(uint64_t x, hr_volume_t *vol, size_t *extent,
    125     uint64_t *phys_block)
    126 {
    127         uint64_t N = vol->dev_no; /* extents */
    128         uint64_t L = vol->strip_size / vol->bsize; /* size of strip in blocks */
    129 
    130         uint64_t i = ((x / L) % (N - 1)) + 1; /* extent */
    131         uint64_t j = (x / L) / (N - 1); /* stripe */
    132         uint64_t k = x % L; /* strip offset */
    133 
    134         *extent = i;
    135         *phys_block = j * L + k;
    136 }
    137 
    138131static errno_t hr_raid4_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    139132{
     
    154147        errno_t rc;
    155148        uint64_t phys_block;
    156         size_t extent, left;
     149        size_t left;
    157150
    158151        if (type == HR_BD_READ || type == HR_BD_WRITE)
     
    164157                return rc;
    165158
     159        uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
     160        uint64_t stripe = (ba / strip_size); /* stripe number */
     161        uint64_t extent = (stripe % (vol->dev_no - 1)) + 1;
     162        uint64_t ext_stripe = stripe / (vol->dev_no - 1); /* stripe level */
     163        uint64_t strip_off = ba % strip_size; /* strip offset */
     164
    166165        fibril_mutex_lock(&vol->lock);
    167166
    168167        left = cnt;
    169168        while (left != 0) {
    170                 raid4_geometry(ba, vol, &extent, &phys_block);
     169                phys_block = ext_stripe * strip_size + strip_off;
     170                cnt = min(left, strip_size - strip_off);
    171171                hr_add_ba_offset(vol, &phys_block);
    172172                switch (type) {
    173173                case HR_BD_SYNC:
    174174                        rc = block_sync_cache(vol->extents[extent].svc_id,
    175                             phys_block, 1);
     175                            phys_block, cnt);
    176176                        break;
    177177                case HR_BD_READ:
    178178                        rc = block_read_direct(vol->extents[extent].svc_id,
    179                             phys_block, 1, data_read);
    180                         data_read = data_read + vol->bsize;
     179                            phys_block, cnt, data_read);
     180                        data_read = (void *) ((uintptr_t) data_read +
     181                            (vol->bsize * cnt));
    181182                        break;
    182183                case HR_BD_WRITE:
    183184                        rc = block_write_direct(vol->extents[extent].svc_id,
    184                             phys_block, 1, data_write);
     185                            phys_block, cnt, data_write);
    185186                        if (rc != EOK)
    186187                                goto error;
    187                         rc = write_parity(vol, extent, phys_block, data_write);
     188                        rc = write_parity(vol, extent, phys_block, data_write,
     189                            cnt);
    188190                        if (rc != EOK)
    189191                                goto error;
    190                         data_write = data_write + vol->bsize;
     192                        data_write = (void *) ((uintptr_t) data_write +
     193                            (vol->bsize * cnt));
    191194                        break;
    192195                default:
     
    197200                        goto error;
    198201
    199                 left--;
    200                 ba++;
     202                left -= cnt;
     203                strip_off = 0;
     204                extent++;
     205                if (extent >= vol->dev_no) {
     206                        ext_stripe++;
     207                        extent = 1;
     208                }
    201209        }
    202210
Note: See TracChangeset for help on using the changeset viewer.