Changeset 978130a in mainline for uspace/srv/bd/hr/raid5.c
- Timestamp:
- 2024-10-28T16:03:24Z (7 months ago)
- Children:
- 4dd650a
- Parents:
- 76cd345
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/hr/raid5.c
r76cd345 r978130a 43 43 #include <ipc/services.h> 44 44 #include <loc.h> 45 #include <mem.h> 45 46 #include <task.h> 46 47 #include <stdio.h> … … 85 86 86 87 static errno_t write_parity(hr_volume_t *vol, uint64_t p_extent, 87 uint64_t extent, uint64_t block, const void *data )88 uint64_t extent, uint64_t block, const void *data, size_t cnt) 88 89 { 89 90 errno_t rc; 90 size_t i ;91 size_t i, j; 91 92 void *xorbuf; 92 93 void *buf; 93 94 94 xorbuf = calloc(1,vol->bsize);95 xorbuf = malloc(vol->bsize); 95 96 if (xorbuf == NULL) 96 97 return ENOMEM; … … 102 103 } 103 104 104 for (i = 0; i < vol->dev_no; i++) { 105 if (i == p_extent) 106 continue; 107 108 if (i == extent) { 109 xor(xorbuf, data, vol->bsize); 110 } else { 111 rc = block_read_direct(vol->extents[i].svc_id, block, 1, 112 buf); 113 if (rc != EOK) 114 goto end; 115 xor(xorbuf, buf, vol->bsize); 105 for (j = 0; j < cnt; j++) { 106 memset(xorbuf, 0, vol->bsize); 107 for (i = 0; i < vol->dev_no; i++) { 108 if (i == p_extent) 109 continue; 110 111 if (i == extent) { 112 xor(xorbuf, data, vol->bsize); 113 } else { 114 rc = block_read_direct(vol->extents[i].svc_id, 115 block, 1, buf); 116 if (rc != EOK) 117 goto end; 118 xor(xorbuf, buf, vol->bsize); 119 } 116 120 } 121 122 rc = block_write_direct(vol->extents[p_extent].svc_id, block, 1, 123 xorbuf); 124 if (rc != EOK) 125 goto end; 126 data = (void *) ((uintptr_t) data + vol->bsize); 127 block++; 117 128 } 118 119 rc = block_write_direct(vol->extents[p_extent].svc_id, block, 1,120 xorbuf);121 129 122 130 end: … … 126 134 } 127 135 128 static void raid5_geometry(uint64_t x, hr_volume_t *vol, size_t *extent,129 uint64_t *phys_block, uint64_t *p_extent)130 {131 uint64_t N = vol->dev_no; /* extents */132 uint64_t L = vol->strip_size / vol->bsize; /* size of strip in blocks */133 134 uint64_t p = ((x / L) / (N - 1)) % N;135 136 uint64_t i; /* extent */137 if (((x / L) % (N - 1)) < p)138 i = (x / L) % (N - 1);139 else140 i = ((x / L) % (N - 1)) + 1;141 142 uint64_t j = (x / L) / (N - 1); /* stripe */143 uint64_t k = x % L; /* strip offset */144 145 *extent = i;146 *phys_block = j * L + k;147 if (p_extent != NULL)148 *p_extent = p;149 }150 151 136 static errno_t hr_raid5_bd_open(bd_srvs_t *bds, bd_srv_t *bd) 152 137 { … … 166 151 hr_volume_t *vol = bd->srvs->sarg; 167 152 errno_t rc; 168 uint64_t phys_block , p_extent;169 size_t extent,left;153 uint64_t phys_block; 154 size_t left; 170 155 171 156 if (type == HR_BD_READ || type == HR_BD_WRITE) … … 177 162 return rc; 178 163 164 uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */ 165 uint64_t stripe = (ba / strip_size); /* stripe number */ 166 uint64_t p_extent = (stripe / (vol->dev_no - 1)) % vol->dev_no; /* parity extent */ 167 uint64_t extent; 168 if ((stripe % (vol->dev_no - 1)) < p_extent) 169 extent = (stripe % (vol->dev_no - 1)); 170 else 171 extent = ((stripe % (vol->dev_no - 1)) + 1); 172 uint64_t ext_stripe = stripe / (vol->dev_no - 1); /* stripe level */ 173 uint64_t strip_off = ba % strip_size; /* strip offset */ 174 179 175 fibril_mutex_lock(&vol->lock); 180 176 181 177 left = cnt; 182 178 while (left != 0) { 179 phys_block = ext_stripe * strip_size + strip_off; 180 cnt = min(left, strip_size - strip_off); 181 hr_add_ba_offset(vol, &phys_block); 183 182 switch (type) { 184 183 case HR_BD_SYNC: 185 raid5_geometry(ba, vol, &extent, &phys_block, NULL);186 hr_add_ba_offset(vol, &phys_block);187 184 rc = block_sync_cache(vol->extents[extent].svc_id, 188 phys_block, 1);185 phys_block, cnt); 189 186 break; 190 187 case HR_BD_READ: 191 raid5_geometry(ba, vol, &extent, &phys_block, NULL);192 hr_add_ba_offset(vol, &phys_block);193 188 rc = block_read_direct(vol->extents[extent].svc_id, 194 phys_block, 1, data_read); 195 data_read = data_read + vol->bsize; 189 phys_block, cnt, data_read); 190 data_read = (void *) ((uintptr_t) data_read + 191 (vol->bsize * cnt)); 196 192 break; 197 193 case HR_BD_WRITE: 198 raid5_geometry(ba, vol, &extent, &phys_block,199 &p_extent);200 hr_add_ba_offset(vol, &phys_block);201 194 rc = block_write_direct(vol->extents[extent].svc_id, 202 phys_block, 1, data_write);195 phys_block, cnt, data_write); 203 196 if (rc != EOK) 204 197 goto error; 205 198 rc = write_parity(vol, p_extent, extent, phys_block, 206 data_write );199 data_write, cnt); 207 200 if (rc != EOK) 208 201 goto error; 209 data_write = data_write + vol->bsize; 202 data_write = (void *) ((uintptr_t) data_write + 203 (vol->bsize * cnt)); 210 204 break; 211 205 default: … … 216 210 goto error; 217 211 218 left--; 219 ba++; 212 left -= cnt; 213 strip_off = 0; 214 if (extent + 1 >= vol->dev_no || 215 (extent + 1 == p_extent && p_extent + 1 >= vol->dev_no)) 216 ext_stripe++; 217 stripe++; 218 p_extent = (stripe / (vol->dev_no - 1)) % vol->dev_no; /* parity extent */ 219 if ((stripe % (vol->dev_no - 1)) < p_extent) 220 extent = (stripe % (vol->dev_no - 1)); 221 else 222 extent = ((stripe % (vol->dev_no - 1)) + 1); 220 223 } 221 224
Note:
See TracChangeset
for help on using the changeset viewer.