1 /* $NetBSD: rf_declusterPQ.c,v 1.14 2006/10/12 01:31:50 christos Exp $ */
3 * Copyright (c) 1995 Carnegie-Mellon University.
6 * Authors: Daniel Stodolsky, Mark Holland, Jim Zelenka
8 * Permission to use, copy, modify and distribute this software and
9 * its documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
29 /*--------------------------------------------------
32 * mapping code for declustered P & Q or declustered EvenOdd
33 * much code borrowed from rf_decluster.c
35 *--------------------------------------------------*/
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: rf_declusterPQ.c,v 1.14 2006/10/12 01:31:50 christos Exp $");
40 #include <dev/raidframe/raidframevar.h>
44 #include "rf_decluster.h"
45 #include "rf_declusterPQ.h"
46 #include "rf_debugMem.h"
48 #include "rf_alloclist.h"
49 #include "rf_general.h"
51 #if (RF_INCLUDE_PARITY_DECLUSTERING_PQ > 0) || (RF_INCLUDE_EVENODD > 0)
52 /* configuration code */
55 rf_ConfigureDeclusteredPQ(RF_ShutdownList_t
**listp
, RF_Raid_t
*raidPtr
,
58 RF_RaidLayout_t
*layoutPtr
= &(raidPtr
->Layout
);
59 int b
, v
, k
, r
, lambda
; /* block design params */
61 int *first_avail_slot
;
62 int complete_FT_count
, SUID
;
63 RF_DeclusteredConfigInfo_t
*info
;
64 int numCompleteFullTablesPerDisk
;
65 int PUsPerDisk
, spareRegionDepthInPUs
, numCompleteSpareRegionsPerDisk
= 0,
67 int totSparePUsPerDisk
;
68 int diskOffsetOfLastFullTableInSUs
, SpareSpaceInSUs
;
69 char *cfgBuf
= (char *) (cfgPtr
->layoutSpecific
);
71 cfgBuf
+= RF_SPAREMAP_NAME_LEN
;
73 b
= *((int *) cfgBuf
);
74 cfgBuf
+= sizeof(int);
75 v
= *((int *) cfgBuf
);
76 cfgBuf
+= sizeof(int);
77 k
= *((int *) cfgBuf
);
78 cfgBuf
+= sizeof(int);
79 r
= *((int *) cfgBuf
);
80 cfgBuf
+= sizeof(int);
81 lambda
= *((int *) cfgBuf
);
82 cfgBuf
+= sizeof(int);
83 raidPtr
->noRotate
= *((int *) cfgBuf
);
84 cfgBuf
+= sizeof(int);
87 printf("RAIDFRAME: k=%d, minimum value 2\n", k
);
90 /* 1. create layout specific structure */
91 RF_MallocAndAdd(info
, sizeof(RF_DeclusteredConfigInfo_t
), (RF_DeclusteredConfigInfo_t
*), raidPtr
->cleanupList
);
94 layoutPtr
->layoutSpecificInfo
= (void *) info
;
96 /* the sparemaps are generated assuming that parity is rotated, so we
97 * issue a warning if both distributed sparing and no-rotate are on at
99 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
) && raidPtr
->noRotate
) {
100 RF_ERRORMSG("Warning: distributed sparing specified without parity rotation.\n");
102 if (raidPtr
->numCol
!= v
) {
103 RF_ERRORMSG2("RAID: config error: table element count (%d) not equal to no. of cols (%d)\n", v
, raidPtr
->numCol
);
106 /* 3. set up the values used in devRaidMap */
107 info
->BlocksPerTable
= b
;
108 info
->NumParityReps
= info
->groupSize
= k
;
109 info
->PUsPerBlock
= k
- 2; /* PQ */
110 info
->SUsPerTable
= b
* info
->PUsPerBlock
* layoutPtr
->SUsPerPU
; /* b blks, k-1 SUs each */
111 info
->SUsPerFullTable
= k
* info
->SUsPerTable
; /* rot k times */
112 info
->SUsPerBlock
= info
->PUsPerBlock
* layoutPtr
->SUsPerPU
;
113 info
->TableDepthInPUs
= (b
* k
) / v
;
114 info
->FullTableDepthInPUs
= info
->TableDepthInPUs
* k
; /* k repetitions */
116 /* used only in distributed sparing case */
117 info
->FullTablesPerSpareRegion
= (v
- 1) / rf_gcd(r
, v
- 1); /* (v-1)/gcd fulltables */
118 info
->TablesPerSpareRegion
= k
* info
->FullTablesPerSpareRegion
;
119 info
->SpareSpaceDepthPerRegionInSUs
= (r
* info
->TablesPerSpareRegion
/ (v
- 1)) * layoutPtr
->SUsPerPU
;
121 /* check to make sure the block design is sufficiently small */
122 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
)) {
123 if (info
->FullTableDepthInPUs
* layoutPtr
->SUsPerPU
+ info
->SpareSpaceDepthPerRegionInSUs
> layoutPtr
->stripeUnitsPerDisk
) {
124 RF_ERRORMSG3("RAID: config error: Full Table depth (%d) + Spare Space (%d) larger than disk size (%d) (BD too big)\n",
125 (int) info
->FullTableDepthInPUs
,
126 (int) info
->SpareSpaceDepthPerRegionInSUs
,
127 (int) layoutPtr
->stripeUnitsPerDisk
);
131 if (info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
> layoutPtr
->stripeUnitsPerDisk
) {
132 RF_ERRORMSG2("RAID: config error: Table depth (%d) larger than disk size (%d) (BD too big)\n",
133 (int) (info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
),
134 (int) layoutPtr
->stripeUnitsPerDisk
);
140 /* compute the size of each disk, and the number of tables in the last
141 * fulltable (which need not be complete) */
142 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
)) {
144 PUsPerDisk
= layoutPtr
->stripeUnitsPerDisk
/ layoutPtr
->SUsPerPU
;
145 spareRegionDepthInPUs
= (info
->TablesPerSpareRegion
* info
->TableDepthInPUs
+
146 (info
->TablesPerSpareRegion
* info
->TableDepthInPUs
) / (v
- 1));
147 info
->SpareRegionDepthInSUs
= spareRegionDepthInPUs
* layoutPtr
->SUsPerPU
;
149 numCompleteSpareRegionsPerDisk
= PUsPerDisk
/ spareRegionDepthInPUs
;
150 info
->NumCompleteSRs
= numCompleteSpareRegionsPerDisk
;
151 extraPUsPerDisk
= PUsPerDisk
% spareRegionDepthInPUs
;
153 /* assume conservatively that we need the full amount of spare
154 * space in one region in order to provide spares for the
155 * partial spare region at the end of the array. We set "i"
156 * to the number of tables in the partial spare region. This
157 * may actually include some fulltables. */
158 extraPUsPerDisk
-= (info
->SpareSpaceDepthPerRegionInSUs
/ layoutPtr
->SUsPerPU
);
159 if (extraPUsPerDisk
<= 0)
162 i
= extraPUsPerDisk
/ info
->TableDepthInPUs
;
164 complete_FT_count
= /* raidPtr->numRow */ 1 * (numCompleteSpareRegionsPerDisk
* (info
->TablesPerSpareRegion
/ k
) + i
/ k
);
165 info
->FullTableLimitSUID
= complete_FT_count
* info
->SUsPerFullTable
;
166 info
->ExtraTablesPerDisk
= i
% k
;
168 /* note that in the last spare region, the spare space is
169 * complete even though data/parity space is not */
170 totSparePUsPerDisk
= (numCompleteSpareRegionsPerDisk
+ 1) * (info
->SpareSpaceDepthPerRegionInSUs
/ layoutPtr
->SUsPerPU
);
171 info
->TotSparePUsPerDisk
= totSparePUsPerDisk
;
173 layoutPtr
->stripeUnitsPerDisk
=
174 ((complete_FT_count
/ /* raidPtr->numRow*/ 1) * info
->FullTableDepthInPUs
+ /* data & parity space */
175 info
->ExtraTablesPerDisk
* info
->TableDepthInPUs
+
176 totSparePUsPerDisk
/* spare space */
177 ) * layoutPtr
->SUsPerPU
;
178 layoutPtr
->dataStripeUnitsPerDisk
=
179 (complete_FT_count
* info
->FullTableDepthInPUs
+ info
->ExtraTablesPerDisk
* info
->TableDepthInPUs
)
180 * layoutPtr
->SUsPerPU
* (k
- 1) / k
;
183 /* non-dist spare case: force each disk to contain an
184 * integral number of tables */
185 layoutPtr
->stripeUnitsPerDisk
/= (info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
);
186 layoutPtr
->stripeUnitsPerDisk
*= (info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
);
188 /* compute the number of tables in the last fulltable, which
189 * need not be complete */
191 ((layoutPtr
->stripeUnitsPerDisk
/ layoutPtr
->SUsPerPU
) / info
->FullTableDepthInPUs
) * /* raidPtr->numRow */ 1;
193 info
->FullTableLimitSUID
= complete_FT_count
* info
->SUsPerFullTable
;
194 info
->ExtraTablesPerDisk
=
195 ((layoutPtr
->stripeUnitsPerDisk
/ layoutPtr
->SUsPerPU
) / info
->TableDepthInPUs
) % k
;
198 raidPtr
->sectorsPerDisk
= layoutPtr
->stripeUnitsPerDisk
* layoutPtr
->sectorsPerStripeUnit
;
200 /* find the disk offset of the stripe unit where the last fulltable
202 numCompleteFullTablesPerDisk
= complete_FT_count
/ /* raidPtr->numRow */ 1;
203 diskOffsetOfLastFullTableInSUs
= numCompleteFullTablesPerDisk
* info
->FullTableDepthInPUs
* layoutPtr
->SUsPerPU
;
204 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
)) {
205 SpareSpaceInSUs
= numCompleteSpareRegionsPerDisk
* info
->SpareSpaceDepthPerRegionInSUs
;
206 diskOffsetOfLastFullTableInSUs
+= SpareSpaceInSUs
;
207 info
->DiskOffsetOfLastSpareSpaceChunkInSUs
=
208 diskOffsetOfLastFullTableInSUs
+ info
->ExtraTablesPerDisk
* info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
;
210 info
->DiskOffsetOfLastFullTableInSUs
= diskOffsetOfLastFullTableInSUs
;
211 info
->numCompleteFullTablesPerDisk
= numCompleteFullTablesPerDisk
;
213 /* 4. create and initialize the lookup tables */
214 info
->LayoutTable
= rf_make_2d_array(b
, k
, raidPtr
->cleanupList
);
215 if (info
->LayoutTable
== NULL
)
217 info
->OffsetTable
= rf_make_2d_array(b
, k
, raidPtr
->cleanupList
);
218 if (info
->OffsetTable
== NULL
)
220 info
->BlockTable
= rf_make_2d_array(info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
, raidPtr
->numCol
, raidPtr
->cleanupList
);
221 if (info
->BlockTable
== NULL
)
224 first_avail_slot
= (int *) rf_make_1d_array(v
, NULL
);
225 if (first_avail_slot
== NULL
)
228 for (i
= 0; i
< b
; i
++)
229 for (j
= 0; j
< k
; j
++)
230 info
->LayoutTable
[i
][j
] = *cfgBuf
++;
232 /* initialize offset table */
233 for (i
= 0; i
< b
; i
++)
234 for (j
= 0; j
< k
; j
++) {
235 info
->OffsetTable
[i
][j
] = first_avail_slot
[info
->LayoutTable
[i
][j
]];
236 first_avail_slot
[info
->LayoutTable
[i
][j
]]++;
239 /* initialize block table */
240 for (SUID
= l
= 0; l
< layoutPtr
->SUsPerPU
; l
++) {
241 for (i
= 0; i
< b
; i
++) {
242 for (j
= 0; j
< k
; j
++) {
243 info
->BlockTable
[(info
->OffsetTable
[i
][j
] * layoutPtr
->SUsPerPU
) + l
]
244 [info
->LayoutTable
[i
][j
]] = SUID
;
250 rf_free_1d_array(first_avail_slot
, v
);
252 /* 5. set up the remaining redundant-but-useful parameters */
254 raidPtr
->totalSectors
= (k
* complete_FT_count
+ /* raidPtr->numRow */ 1 * info
->ExtraTablesPerDisk
) *
255 info
->SUsPerTable
* layoutPtr
->sectorsPerStripeUnit
;
256 layoutPtr
->numStripe
= (raidPtr
->totalSectors
/ layoutPtr
->sectorsPerStripeUnit
) / (k
- 2);
258 /* strange evaluation order below to try and minimize overflow
261 layoutPtr
->dataSectorsPerStripe
= (k
- 2) * layoutPtr
->sectorsPerStripeUnit
;
262 layoutPtr
->numDataCol
= k
- 2;
263 layoutPtr
->numParityCol
= 2;
269 rf_GetDefaultNumFloatingReconBuffersPQ(RF_Raid_t
*raidPtr
)
273 def_decl
= rf_GetDefaultNumFloatingReconBuffersDeclustered(raidPtr
);
274 return (RF_MAX(3 * raidPtr
->numCol
, def_decl
));
278 rf_MapSectorDeclusteredPQ(RF_Raid_t
*raidPtr
, RF_RaidAddr_t raidSector
,
280 RF_SectorNum_t
*diskSector
, int remap
)
282 RF_RaidLayout_t
*layoutPtr
= &(raidPtr
->Layout
);
283 RF_DeclusteredConfigInfo_t
*info
= (RF_DeclusteredConfigInfo_t
*) layoutPtr
->layoutSpecificInfo
;
284 RF_StripeNum_t SUID
= raidSector
/ layoutPtr
->sectorsPerStripeUnit
;
285 RF_StripeNum_t FullTableID
, FullTableOffset
, TableID
, TableOffset
;
286 RF_StripeNum_t BlockID
, BlockOffset
, RepIndex
;
287 RF_StripeCount_t sus_per_fulltable
= info
->SUsPerFullTable
;
288 RF_StripeCount_t fulltable_depth
= info
->FullTableDepthInPUs
* layoutPtr
->SUsPerPU
;
289 RF_StripeNum_t base_suid
= 0, outSU
, SpareRegion
= 0, SpareSpace
= 0;
291 rf_decluster_adjust_params(layoutPtr
, &SUID
, &sus_per_fulltable
, &fulltable_depth
, &base_suid
);
293 FullTableID
= SUID
/ sus_per_fulltable
; /* fulltable ID within array
295 FullTableID
/= /* raidPtr->numRow */ 1; /* convert to fulltable ID on this
297 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
)) {
298 SpareRegion
= FullTableID
/ info
->FullTablesPerSpareRegion
;
299 SpareSpace
= SpareRegion
* info
->SpareSpaceDepthPerRegionInSUs
;
301 FullTableOffset
= SUID
% sus_per_fulltable
;
302 TableID
= FullTableOffset
/ info
->SUsPerTable
;
303 TableOffset
= FullTableOffset
- TableID
* info
->SUsPerTable
;
304 BlockID
= TableOffset
/ info
->PUsPerBlock
;
305 BlockOffset
= TableOffset
- BlockID
* info
->PUsPerBlock
;
306 BlockID
%= info
->BlocksPerTable
;
307 RF_ASSERT(BlockOffset
< info
->groupSize
- 2);
309 TableIDs go from 0 .. GroupSize-1 inclusive.
311 We want the tableIDs to rotate from the
312 right, so use GroupSize
314 RepIndex
= info
->groupSize
- 1 - TableID
;
315 RF_ASSERT(RepIndex
>= 0);
316 if (!raidPtr
->noRotate
) {
318 BlockOffset
++; /* P on last drive, Q on first */
320 BlockOffset
+= ((BlockOffset
>= RepIndex
) ? 2 : 0); /* skip over PQ */
321 RF_ASSERT(BlockOffset
< info
->groupSize
);
322 *col
= info
->LayoutTable
[BlockID
][BlockOffset
];
324 /* remap to distributed spare space if indicated */
326 rf_remap_to_spare_space(layoutPtr
, info
, FullTableID
, TableID
, BlockID
, (base_suid
) ? 1 : 0, SpareRegion
, col
, &outSU
);
330 outSU
+= FullTableID
* fulltable_depth
; /* offs to strt of FT */
331 outSU
+= SpareSpace
; /* skip rsvd spare space */
332 outSU
+= TableID
* info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
; /* offs to strt of tble */
333 outSU
+= info
->OffsetTable
[BlockID
][BlockOffset
] * layoutPtr
->SUsPerPU
; /* offs to the PU */
335 outSU
+= TableOffset
/ (info
->BlocksPerTable
* info
->PUsPerBlock
); /* offs to the SU within
338 /* convert SUs to sectors, and, if not aligned to SU boundary, add in
339 * offset to sector */
340 *diskSector
= outSU
* layoutPtr
->sectorsPerStripeUnit
+ (raidSector
% layoutPtr
->sectorsPerStripeUnit
);
345 rf_MapParityDeclusteredPQ(RF_Raid_t
*raidPtr
, RF_RaidAddr_t raidSector
,
347 RF_SectorNum_t
*diskSector
, int remap
)
349 RF_RaidLayout_t
*layoutPtr
= &(raidPtr
->Layout
);
350 RF_DeclusteredConfigInfo_t
*info
= (RF_DeclusteredConfigInfo_t
*) layoutPtr
->layoutSpecificInfo
;
351 RF_StripeNum_t SUID
= raidSector
/ layoutPtr
->sectorsPerStripeUnit
;
352 RF_StripeNum_t FullTableID
, FullTableOffset
, TableID
, TableOffset
;
353 RF_StripeNum_t BlockID
, BlockOffset
, RepIndex
;
354 RF_StripeCount_t sus_per_fulltable
= info
->SUsPerFullTable
;
355 RF_StripeCount_t fulltable_depth
= info
->FullTableDepthInPUs
* layoutPtr
->SUsPerPU
;
356 RF_StripeNum_t base_suid
= 0, outSU
, SpareRegion
, SpareSpace
= 0;
358 rf_decluster_adjust_params(layoutPtr
, &SUID
, &sus_per_fulltable
, &fulltable_depth
, &base_suid
);
360 /* compute row & (possibly) spare space exactly as before */
361 FullTableID
= SUID
/ sus_per_fulltable
;
362 FullTableID
/= /* raidPtr->numRow */ 1; /* convert to fulltable ID on this
364 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
)) {
365 SpareRegion
= FullTableID
/ info
->FullTablesPerSpareRegion
;
366 SpareSpace
= SpareRegion
* info
->SpareSpaceDepthPerRegionInSUs
;
368 /* compute BlockID and RepIndex exactly as before */
369 FullTableOffset
= SUID
% sus_per_fulltable
;
370 TableID
= FullTableOffset
/ info
->SUsPerTable
;
371 TableOffset
= FullTableOffset
- TableID
* info
->SUsPerTable
;
372 BlockID
= TableOffset
/ info
->PUsPerBlock
;
373 BlockOffset
= TableOffset
- BlockID
* info
->PUsPerBlock
;
374 BlockID
%= info
->BlocksPerTable
;
376 /* the parity block is in the position indicated by RepIndex */
377 RepIndex
= (raidPtr
->noRotate
) ? info
->PUsPerBlock
: info
->groupSize
- 1 - TableID
;
378 *col
= info
->LayoutTable
[BlockID
][RepIndex
];
383 /* compute sector as before, except use RepIndex instead of
386 outSU
+= FullTableID
* fulltable_depth
;
387 outSU
+= SpareSpace
; /* skip rsvd spare space */
388 outSU
+= TableID
* info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
;
389 outSU
+= info
->OffsetTable
[BlockID
][RepIndex
] * layoutPtr
->SUsPerPU
;
390 outSU
+= TableOffset
/ (info
->BlocksPerTable
* info
->PUsPerBlock
);
392 *diskSector
= outSU
* layoutPtr
->sectorsPerStripeUnit
+ (raidSector
% layoutPtr
->sectorsPerStripeUnit
);
396 rf_MapQDeclusteredPQ(RF_Raid_t
*raidPtr
, RF_RaidAddr_t raidSector
,
398 RF_SectorNum_t
*diskSector
, int remap
)
400 RF_RaidLayout_t
*layoutPtr
= &(raidPtr
->Layout
);
401 RF_DeclusteredConfigInfo_t
*info
= (RF_DeclusteredConfigInfo_t
*) layoutPtr
->layoutSpecificInfo
;
402 RF_StripeNum_t SUID
= raidSector
/ layoutPtr
->sectorsPerStripeUnit
;
403 RF_StripeNum_t FullTableID
, FullTableOffset
, TableID
, TableOffset
;
404 RF_StripeNum_t BlockID
, BlockOffset
, RepIndex
, RepIndexQ
;
405 RF_StripeCount_t sus_per_fulltable
= info
->SUsPerFullTable
;
406 RF_StripeCount_t fulltable_depth
= info
->FullTableDepthInPUs
* layoutPtr
->SUsPerPU
;
407 RF_StripeNum_t base_suid
= 0, outSU
, SpareRegion
, SpareSpace
= 0;
409 rf_decluster_adjust_params(layoutPtr
, &SUID
, &sus_per_fulltable
, &fulltable_depth
, &base_suid
);
411 /* compute row & (possibly) spare space exactly as before */
412 FullTableID
= SUID
/ sus_per_fulltable
;
413 FullTableID
/= /* raidPtr->numRow */ 1; /* convert to fulltable ID on this
415 if ((raidPtr
->Layout
.map
->flags
& RF_DISTRIBUTE_SPARE
)) {
416 SpareRegion
= FullTableID
/ info
->FullTablesPerSpareRegion
;
417 SpareSpace
= SpareRegion
* info
->SpareSpaceDepthPerRegionInSUs
;
419 /* compute BlockID and RepIndex exactly as before */
420 FullTableOffset
= SUID
% sus_per_fulltable
;
421 TableID
= FullTableOffset
/ info
->SUsPerTable
;
422 TableOffset
= FullTableOffset
- TableID
* info
->SUsPerTable
;
423 BlockID
= TableOffset
/ info
->PUsPerBlock
;
424 BlockOffset
= TableOffset
- BlockID
* info
->PUsPerBlock
;
425 BlockID
%= info
->BlocksPerTable
;
427 /* the q block is in the position indicated by RepIndex */
428 RepIndex
= (raidPtr
->noRotate
) ? info
->PUsPerBlock
: info
->groupSize
- 1 - TableID
;
429 RepIndexQ
= ((RepIndex
== (info
->groupSize
- 1)) ? 0 : RepIndex
+ 1);
430 *col
= info
->LayoutTable
[BlockID
][RepIndexQ
];
435 /* compute sector as before, except use RepIndex instead of
438 outSU
+= FullTableID
* fulltable_depth
;
439 outSU
+= SpareSpace
; /* skip rsvd spare space */
440 outSU
+= TableID
* info
->TableDepthInPUs
* layoutPtr
->SUsPerPU
;
441 outSU
+= TableOffset
/ (info
->BlocksPerTable
* info
->PUsPerBlock
);
443 outSU
+= info
->OffsetTable
[BlockID
][RepIndexQ
] * layoutPtr
->SUsPerPU
;
444 *diskSector
= outSU
* layoutPtr
->sectorsPerStripeUnit
+ (raidSector
% layoutPtr
->sectorsPerStripeUnit
);
446 /* returns an array of ints identifying the disks that comprise the stripe containing the indicated address.
447 * the caller must _never_ attempt to modify this array.
450 rf_IdentifyStripeDeclusteredPQ(RF_Raid_t
*raidPtr
, RF_RaidAddr_t addr
,
451 RF_RowCol_t
**diskids
)
453 RF_RaidLayout_t
*layoutPtr
= &(raidPtr
->Layout
);
454 RF_DeclusteredConfigInfo_t
*info
= (RF_DeclusteredConfigInfo_t
*) layoutPtr
->layoutSpecificInfo
;
455 RF_StripeCount_t sus_per_fulltable
= info
->SUsPerFullTable
;
456 RF_StripeCount_t fulltable_depth
= info
->FullTableDepthInPUs
* layoutPtr
->SUsPerPU
;
457 RF_StripeNum_t base_suid
= 0;
458 RF_StripeNum_t SUID
= rf_RaidAddressToStripeUnitID(layoutPtr
, addr
);
459 RF_StripeNum_t stripeID
, FullTableID
;
462 rf_decluster_adjust_params(layoutPtr
, &SUID
, &sus_per_fulltable
, &fulltable_depth
, &base_suid
);
463 FullTableID
= SUID
/ sus_per_fulltable
; /* fulltable ID within array
465 stripeID
= rf_StripeUnitIDToStripeID(layoutPtr
, SUID
); /* find stripe offset
467 tableOffset
= (stripeID
% info
->BlocksPerTable
); /* find offset into
468 * block design table */
469 *diskids
= info
->LayoutTable
[tableOffset
];
471 #endif /* (RF_INCLUDE_PARITY_DECLUSTERING_PQ > 0) || (RF_INCLUDE_EVENODD > 0) */