This source file includes following definitions.
- rf_ConfigureDeclusteredPQ
- rf_GetDefaultNumFloatingReconBuffersPQ
- rf_MapSectorDeclusteredPQ
- rf_MapParityDeclusteredPQ
- rf_MapQDeclusteredPQ
- rf_IdentifyStripeDeclusteredPQ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include "rf_types.h"
41 #include "rf_raid.h"
42 #include "rf_configure.h"
43 #include "rf_decluster.h"
44 #include "rf_declusterPQ.h"
45 #include "rf_debugMem.h"
46 #include "rf_utils.h"
47 #include "rf_alloclist.h"
48 #include "rf_general.h"
49
50
51
52 int
53 rf_ConfigureDeclusteredPQ(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
54 RF_Config_t *cfgPtr)
55 {
56 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
57 int b, v, k, r, lambda;
58 int i, j, l;
59 int *first_avail_slot;
60 int complete_FT_count, SUID;
61 RF_DeclusteredConfigInfo_t *info;
62 int numCompleteFullTablesPerDisk;
63 int PUsPerDisk, spareRegionDepthInPUs, extraPUsPerDisk;
64 int numCompleteSpareRegionsPerDisk = 0;
65 int totSparePUsPerDisk;
66 int diskOffsetOfLastFullTableInSUs, SpareSpaceInSUs;
67 char *cfgBuf = (char *)(cfgPtr->layoutSpecific);
68
69 cfgBuf += RF_SPAREMAP_NAME_LEN;
70
71 b = *((int *) cfgBuf);
72 cfgBuf += sizeof(int);
73 v = *((int *) cfgBuf);
74 cfgBuf += sizeof(int);
75 k = *((int *) cfgBuf);
76 cfgBuf += sizeof(int);
77 r = *((int *) cfgBuf);
78 cfgBuf += sizeof(int);
79 lambda = *((int *) cfgBuf);
80 cfgBuf += sizeof(int);
81 raidPtr->noRotate = *((int *) cfgBuf);
82 cfgBuf += sizeof(int);
83
84 if (k <= 2) {
85 #ifdef RAIDDEBUG
86 printf("RAIDFRAME: k=%d, minimum value 2\n", k);
87 #endif
88 return (EINVAL);
89 }
90
91 RF_MallocAndAdd(info, sizeof(RF_DeclusteredConfigInfo_t),
92 (RF_DeclusteredConfigInfo_t *), raidPtr->cleanupList);
93 if (info == NULL)
94 return (ENOMEM);
95 layoutPtr->layoutSpecificInfo = (void *) info;
96
97
98
99
100
101
102 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) &&
103 raidPtr->noRotate) {
104 RF_ERRORMSG("Warning: distributed sparing specified without"
105 " parity rotation.\n");
106 }
107 if (raidPtr->numCol != v) {
108 RF_ERRORMSG2("RAID: config error: table element count (%d)"
109 " not equal to no. of cols (%d).\n", v, raidPtr->numCol);
110 return (EINVAL);
111 }
112
113 info->BlocksPerTable = b;
114 info->NumParityReps = info->groupSize = k;
115 info->PUsPerBlock = k - 2;
116 info->SUsPerTable = b * info->PUsPerBlock * layoutPtr->SUsPerPU;
117
118 info->SUsPerFullTable = k * info->SUsPerTable;
119 info->SUsPerBlock = info->PUsPerBlock * layoutPtr->SUsPerPU;
120 info->TableDepthInPUs = (b * k) / v;
121 info->FullTableDepthInPUs = info->TableDepthInPUs * k;
122
123
124
125 info->FullTablesPerSpareRegion = (v - 1) / rf_gcd(r, v - 1);
126
127 info->TablesPerSpareRegion = k * info->FullTablesPerSpareRegion;
128 info->SpareSpaceDepthPerRegionInSUs = (r * info->TablesPerSpareRegion
129 / (v - 1)) * layoutPtr->SUsPerPU;
130
131
132 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
133 if (info->FullTableDepthInPUs * layoutPtr->SUsPerPU +
134 info->SpareSpaceDepthPerRegionInSUs >
135 layoutPtr->stripeUnitsPerDisk) {
136 RF_ERRORMSG3("RAID: config error: Full Table depth"
137 " (%d) + Spare Space (%d) larger than disk size"
138 " (%d) (BD too big).\n",
139 (int)info->FullTableDepthInPUs,
140 (int)info->SpareSpaceDepthPerRegionInSUs,
141 (int)layoutPtr->stripeUnitsPerDisk);
142 return (EINVAL);
143 }
144 } else {
145 if (info->TableDepthInPUs * layoutPtr->SUsPerPU >
146 layoutPtr->stripeUnitsPerDisk) {
147 RF_ERRORMSG2("RAID: config error: Table depth (%d)"
148 " larger than disk size (%d) (BD too big).\n",
149 (int) (info->TableDepthInPUs * layoutPtr->SUsPerPU),
150 (int) layoutPtr->stripeUnitsPerDisk);
151 return (EINVAL);
152 }
153 }
154
155
156
157
158
159 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
160
161 PUsPerDisk = layoutPtr->stripeUnitsPerDisk /
162 layoutPtr->SUsPerPU;
163 spareRegionDepthInPUs = (info->TablesPerSpareRegion *
164 info->TableDepthInPUs + (info->TablesPerSpareRegion *
165 info->TableDepthInPUs) / (v - 1));
166 info->SpareRegionDepthInSUs = spareRegionDepthInPUs *
167 layoutPtr->SUsPerPU;
168
169 numCompleteSpareRegionsPerDisk = PUsPerDisk /
170 spareRegionDepthInPUs;
171 info->NumCompleteSRs = numCompleteSpareRegionsPerDisk;
172 extraPUsPerDisk = PUsPerDisk % spareRegionDepthInPUs;
173
174
175
176
177
178
179
180
181 extraPUsPerDisk -= (info->SpareSpaceDepthPerRegionInSUs /
182 layoutPtr->SUsPerPU);
183 if (extraPUsPerDisk <= 0)
184 i = 0;
185 else
186 i = extraPUsPerDisk / info->TableDepthInPUs;
187
188 complete_FT_count = raidPtr->numRow *
189 (numCompleteSpareRegionsPerDisk *
190 (info->TablesPerSpareRegion / k) + i / k);
191 info->FullTableLimitSUID = complete_FT_count *
192 info->SUsPerFullTable;
193 info->ExtraTablesPerDisk = i % k;
194
195
196
197
198
199 totSparePUsPerDisk = (numCompleteSpareRegionsPerDisk + 1) *
200 (info->SpareSpaceDepthPerRegionInSUs / layoutPtr->SUsPerPU);
201 info->TotSparePUsPerDisk = totSparePUsPerDisk;
202
203 layoutPtr->stripeUnitsPerDisk =
204 ((complete_FT_count / raidPtr->numRow) *
205 info->FullTableDepthInPUs +
206 info->ExtraTablesPerDisk * info->TableDepthInPUs +
207 totSparePUsPerDisk
208 ) * layoutPtr->SUsPerPU;
209 layoutPtr->dataStripeUnitsPerDisk =
210 (complete_FT_count * info->FullTableDepthInPUs +
211 info->ExtraTablesPerDisk * info->TableDepthInPUs)
212 * layoutPtr->SUsPerPU * (k - 1) / k;
213
214 } else {
215
216
217
218
219 layoutPtr->stripeUnitsPerDisk /=
220 (info->TableDepthInPUs * layoutPtr->SUsPerPU);
221 layoutPtr->stripeUnitsPerDisk *=
222 (info->TableDepthInPUs * layoutPtr->SUsPerPU);
223
224
225
226
227
228 complete_FT_count = ((layoutPtr->stripeUnitsPerDisk /
229 layoutPtr->SUsPerPU) / info->FullTableDepthInPUs) *
230 raidPtr->numRow;
231
232 info->FullTableLimitSUID = complete_FT_count *
233 info->SUsPerFullTable;
234 info->ExtraTablesPerDisk = ((layoutPtr->stripeUnitsPerDisk /
235 layoutPtr->SUsPerPU) / info->TableDepthInPUs) % k;
236 }
237
238 raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk *
239 layoutPtr->sectorsPerStripeUnit;
240
241
242
243
244
245 numCompleteFullTablesPerDisk = complete_FT_count / raidPtr->numRow;
246 diskOffsetOfLastFullTableInSUs = numCompleteFullTablesPerDisk *
247 info->FullTableDepthInPUs * layoutPtr->SUsPerPU;
248 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
249 SpareSpaceInSUs = numCompleteSpareRegionsPerDisk *
250 info->SpareSpaceDepthPerRegionInSUs;
251 diskOffsetOfLastFullTableInSUs += SpareSpaceInSUs;
252 info->DiskOffsetOfLastSpareSpaceChunkInSUs =
253 diskOffsetOfLastFullTableInSUs + info->ExtraTablesPerDisk *
254 info->TableDepthInPUs * layoutPtr->SUsPerPU;
255 }
256 info->DiskOffsetOfLastFullTableInSUs = diskOffsetOfLastFullTableInSUs;
257 info->numCompleteFullTablesPerDisk = numCompleteFullTablesPerDisk;
258
259
260 info->LayoutTable = rf_make_2d_array(b, k, raidPtr->cleanupList);
261 if (info->LayoutTable == NULL)
262 return (ENOMEM);
263
264 info->OffsetTable = rf_make_2d_array(b, k, raidPtr->cleanupList);
265 if (info->OffsetTable == NULL)
266 return (ENOMEM);
267
268 info->BlockTable = rf_make_2d_array(info->TableDepthInPUs *
269 layoutPtr->SUsPerPU, raidPtr->numCol, raidPtr->cleanupList);
270 if (info->BlockTable == NULL)
271 return (ENOMEM);
272
273 first_avail_slot = (int *) rf_make_1d_array(v, NULL);
274 if (first_avail_slot == NULL)
275 return (ENOMEM);
276
277 for (i = 0; i < b; i++)
278 for (j = 0; j < k; j++)
279 info->LayoutTable[i][j] = *cfgBuf++;
280
281
282 for (i = 0; i < b; i++)
283 for (j = 0; j < k; j++) {
284 info->OffsetTable[i][j] =
285 first_avail_slot[info->LayoutTable[i][j]];
286 first_avail_slot[info->LayoutTable[i][j]]++;
287 }
288
289
290 for (SUID = l = 0; l < layoutPtr->SUsPerPU; l++) {
291 for (i = 0; i < b; i++) {
292 for (j = 0; j < k; j++) {
293 info->BlockTable[(info->OffsetTable[i][j] *
294 layoutPtr->SUsPerPU) + l]
295 [info->LayoutTable[i][j]] = SUID;
296 }
297 SUID++;
298 }
299 }
300
301 rf_free_1d_array(first_avail_slot, v);
302
303
304
305 raidPtr->totalSectors = (k * complete_FT_count + raidPtr->numRow *
306 info->ExtraTablesPerDisk) * info->SUsPerTable *
307 layoutPtr->sectorsPerStripeUnit;
308 layoutPtr->numStripe = (raidPtr->totalSectors /
309 layoutPtr->sectorsPerStripeUnit) / (k - 2);
310
311
312
313
314
315
316 layoutPtr->dataSectorsPerStripe = (k - 2) *
317 layoutPtr->sectorsPerStripeUnit;
318 layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit <<
319 raidPtr->logBytesPerSector;
320 layoutPtr->numDataCol = k - 2;
321 layoutPtr->numParityCol = 2;
322
323 return (0);
324 }
325
326 int
327 rf_GetDefaultNumFloatingReconBuffersPQ(RF_Raid_t *raidPtr)
328 {
329 int def_decl;
330
331 def_decl = rf_GetDefaultNumFloatingReconBuffersDeclustered(raidPtr);
332 return (RF_MAX(3 * raidPtr->numCol, def_decl));
333 }
334
335 void
336 rf_MapSectorDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
337 RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
338 {
339 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
340 RF_DeclusteredConfigInfo_t *info =
341 (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
342 RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;
343 RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;
344 RF_StripeNum_t BlockID, BlockOffset, RepIndex;
345 RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
346 RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
347 layoutPtr->SUsPerPU;
348 RF_StripeNum_t base_suid = 0, outSU, SpareRegion = 0, SpareSpace = 0;
349
350 rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
351 &fulltable_depth, &base_suid);
352
353
354 FullTableID = SUID / sus_per_fulltable;
355 *row = FullTableID % raidPtr->numRow;
356
357
358 FullTableID /= raidPtr->numRow;
359
360 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
361 SpareRegion = FullTableID / info->FullTablesPerSpareRegion;
362 SpareSpace = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;
363 }
364 FullTableOffset = SUID % sus_per_fulltable;
365 TableID = FullTableOffset / info->SUsPerTable;
366 TableOffset = FullTableOffset - TableID * info->SUsPerTable;
367 BlockID = TableOffset / info->PUsPerBlock;
368 BlockOffset = TableOffset - BlockID * info->PUsPerBlock;
369 BlockID %= info->BlocksPerTable;
370 RF_ASSERT(BlockOffset < info->groupSize - 2);
371
372
373
374
375
376
377 RepIndex = info->groupSize - 1 - TableID;
378 RF_ASSERT(RepIndex >= 0);
379 if (!raidPtr->noRotate) {
380 if (TableID == 0)
381
382 BlockOffset++;
383 else
384
385 BlockOffset += ((BlockOffset >= RepIndex) ? 2 : 0);
386
387 RF_ASSERT(BlockOffset < info->groupSize);
388 *col = info->LayoutTable[BlockID][BlockOffset];
389 }
390
391 if (remap) {
392 rf_remap_to_spare_space(layoutPtr, info, *row, FullTableID,
393 TableID, BlockID, (base_suid) ? 1 : 0, SpareRegion, col,
394 &outSU);
395 } else {
396
397 outSU = base_suid;
398 outSU += FullTableID * fulltable_depth;
399
400 outSU += SpareSpace;
401
402 outSU += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;
403
404 outSU += info->OffsetTable[BlockID][BlockOffset] *
405 layoutPtr->SUsPerPU;
406
407 }
408 outSU += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);
409
410
411
412
413
414
415 *diskSector = outSU * layoutPtr->sectorsPerStripeUnit +
416 (raidSector % layoutPtr->sectorsPerStripeUnit);
417 }
418
419
420 void
421 rf_MapParityDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
422 RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
423 {
424 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
425 RF_DeclusteredConfigInfo_t *info =
426 (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
427 RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;
428 RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;
429 RF_StripeNum_t BlockID, BlockOffset, RepIndex;
430 RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
431 RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
432 layoutPtr->SUsPerPU;
433 RF_StripeNum_t base_suid = 0, outSU, SpareRegion, SpareSpace = 0;
434
435 rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
436 &fulltable_depth, &base_suid);
437
438
439 FullTableID = SUID / sus_per_fulltable;
440 *row = FullTableID % raidPtr->numRow;
441
442 FullTableID /= raidPtr->numRow;
443 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
444 SpareRegion = FullTableID / info->FullTablesPerSpareRegion;
445 SpareSpace = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;
446 }
447
448 FullTableOffset = SUID % sus_per_fulltable;
449 TableID = FullTableOffset / info->SUsPerTable;
450 TableOffset = FullTableOffset - TableID * info->SUsPerTable;
451 BlockID = TableOffset / info->PUsPerBlock;
452 BlockOffset = TableOffset - BlockID * info->PUsPerBlock;
453 BlockID %= info->BlocksPerTable;
454
455
456 RepIndex = (raidPtr->noRotate) ?
457 info->PUsPerBlock : info->groupSize - 1 - TableID;
458 *col = info->LayoutTable[BlockID][RepIndex];
459
460 if (remap)
461 RF_PANIC();
462
463
464
465
466
467 outSU = base_suid;
468 outSU += FullTableID * fulltable_depth;
469 outSU += SpareSpace;
470 outSU += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;
471 outSU += info->OffsetTable[BlockID][RepIndex] * layoutPtr->SUsPerPU;
472 outSU += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);
473
474 *diskSector = outSU * layoutPtr->sectorsPerStripeUnit +
475 (raidSector % layoutPtr->sectorsPerStripeUnit);
476 }
477
478 void
479 rf_MapQDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
480 RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
481 {
482 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
483 RF_DeclusteredConfigInfo_t *info =
484 (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
485 RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;
486 RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;
487 RF_StripeNum_t BlockID, BlockOffset, RepIndex, RepIndexQ;
488 RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
489 RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
490 layoutPtr->SUsPerPU;
491 RF_StripeNum_t base_suid = 0, outSU, SpareRegion, SpareSpace = 0;
492
493 rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
494 &fulltable_depth, &base_suid);
495
496
497 FullTableID = SUID / sus_per_fulltable;
498 *row = FullTableID % raidPtr->numRow;
499
500 FullTableID /= raidPtr->numRow;
501 if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
502 SpareRegion = FullTableID / info->FullTablesPerSpareRegion;
503 SpareSpace = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;
504 }
505
506 FullTableOffset = SUID % sus_per_fulltable;
507 TableID = FullTableOffset / info->SUsPerTable;
508 TableOffset = FullTableOffset - TableID * info->SUsPerTable;
509 BlockID = TableOffset / info->PUsPerBlock;
510 BlockOffset = TableOffset - BlockID * info->PUsPerBlock;
511 BlockID %= info->BlocksPerTable;
512
513
514 RepIndex = (raidPtr->noRotate) ?
515 info->PUsPerBlock : info->groupSize - 1 - TableID;
516 RepIndexQ = ((RepIndex == (info->groupSize - 1)) ? 0 : RepIndex + 1);
517 *col = info->LayoutTable[BlockID][RepIndexQ];
518
519 if (remap)
520 RF_PANIC();
521
522
523
524
525
526 outSU = base_suid;
527 outSU += FullTableID * fulltable_depth;
528 outSU += SpareSpace;
529 outSU += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;
530 outSU += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);
531
532 outSU += info->OffsetTable[BlockID][RepIndexQ] * layoutPtr->SUsPerPU;
533 *diskSector = outSU * layoutPtr->sectorsPerStripeUnit +
534 (raidSector % layoutPtr->sectorsPerStripeUnit);
535 }
536
537
538
539
540
541
542 void
543 rf_IdentifyStripeDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t addr,
544 RF_RowCol_t **diskids, RF_RowCol_t *outRow)
545 {
546 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
547 RF_DeclusteredConfigInfo_t *info =
548 (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
549 RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
550 RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
551 layoutPtr->SUsPerPU;
552 RF_StripeNum_t base_suid = 0;
553 RF_StripeNum_t SUID = rf_RaidAddressToStripeUnitID(layoutPtr, addr);
554 RF_StripeNum_t stripeID, FullTableID;
555 int tableOffset;
556
557 rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
558 &fulltable_depth, &base_suid);
559
560 FullTableID = SUID / sus_per_fulltable;
561 *outRow = FullTableID % raidPtr->numRow;
562
563 stripeID = rf_StripeUnitIDToStripeID(layoutPtr, SUID);
564
565 tableOffset = (stripeID % info->BlocksPerTable);
566 *diskids = info->LayoutTable[tableOffset];
567 }