📄 rf_map.c
字号:
t_pda = pdaList; pdaList = pdaList->next; bzero((char *)t_pda, sizeof(RF_PhysDiskAddr_t)); pda_p = asm_p->parityInfo = t_pda; pda_p->type = RF_PDA_TYPE_PARITY; (layoutPtr->map->MapParity)(raidPtr, rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, startAddrWithinStripe), &(pda_p->row), &(pda_p->col), &(pda_p->startSector), remap); pda_p->numSector = layoutPtr->sectorsPerStripeUnit; /* raidAddr may be needed to find unit to redirect to */ pda_p->raidAddress = rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, startAddrWithinStripe); rf_ASMCheckStatus(raidPtr,pda_p,asm_p,disks,1); rf_ASMParityAdjust(asm_p->parityInfo,startAddrWithinStripe,endAddress,layoutPtr,asm_p); break; case 2: /* two fault tolerant */ RF_ASSERT(pdaList && pdaList->next); t_pda = pdaList; pdaList = pdaList->next; bzero((char *)t_pda, sizeof(RF_PhysDiskAddr_t)); pda_p = asm_p->parityInfo = t_pda; pda_p->type = RF_PDA_TYPE_PARITY; t_pda = pdaList; pdaList = pdaList->next; bzero((char *)t_pda, sizeof(RF_PhysDiskAddr_t)); pda_q = asm_p->qInfo = t_pda; pda_q->type = RF_PDA_TYPE_Q; (layoutPtr->map->MapParity)(raidPtr, rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, startAddrWithinStripe), &(pda_p->row), &(pda_p->col), &(pda_p->startSector), remap); (layoutPtr->map->MapQ)(raidPtr, rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, startAddrWithinStripe), &(pda_q->row), &(pda_q->col), &(pda_q->startSector), remap); pda_q->numSector = pda_p->numSector = layoutPtr->sectorsPerStripeUnit; /* raidAddr may be needed to find unit to redirect to */ pda_p->raidAddress = rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, startAddrWithinStripe); pda_q->raidAddress = rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, startAddrWithinStripe); /* failure mode stuff */ rf_ASMCheckStatus(raidPtr,pda_p,asm_p,disks,1); rf_ASMCheckStatus(raidPtr,pda_q,asm_p,disks,1); rf_ASMParityAdjust(asm_p->parityInfo,startAddrWithinStripe,endAddress,layoutPtr,asm_p); rf_ASMParityAdjust(asm_p->qInfo,startAddrWithinStripe,endAddress,layoutPtr,asm_p); break; } } RF_ASSERT(asmList == NULL && pdaList == NULL); /* make the header structure */ asm_hdr = rf_AllocAccessStripeMapHeader(); RF_ASSERT(numStripes == totStripes); asm_hdr->numStripes = numStripes; asm_hdr->stripeMap = asm_list; if (rf_mapDebug) rf_PrintAccessStripeMap(asm_hdr); return(asm_hdr);}/***************************************************************************************** * This routine walks through an ASM list and marks the PDAs that have failed. * It's called only when a disk failure causes an in-flight DAG to fail. * The parity may consist of two components, but we want to use only one failedPDA * pointer. Thus we set failedPDA to point to the first parity component, and rely * on the rest of the code to do the right thing with this. ****************************************************************************************/void rf_MarkFailuresInASMList(raidPtr, asm_h) RF_Raid_t *raidPtr; RF_AccessStripeMapHeader_t *asm_h;{ RF_RaidDisk_t **disks = raidPtr->Disks; RF_AccessStripeMap_t *asmap; RF_PhysDiskAddr_t *pda; for (asmap = asm_h->stripeMap; asmap; asmap = asmap->next) { asmap->numDataFailed = asmap->numParityFailed = asmap->numQFailed = 0; asmap->failedPDAtwo = asmap->failedPDA = NULL; for (pda = asmap->physInfo; pda; pda=pda->next) { if (RF_DEAD_DISK(disks[pda->row][pda->col].status)) { asmap->numDataFailed++; if (asmap->failedPDA) asmap->failedPDAtwo = pda; else asmap->failedPDA = pda; } } pda = asmap->parityInfo; if (pda && RF_DEAD_DISK(disks[pda->row][pda->col].status)) { asmap->numParityFailed++; if (asmap->failedPDA) asmap->failedPDAtwo = pda; else asmap->failedPDA = pda; } pda = asmap->qInfo; if (pda && RF_DEAD_DISK(disks[pda->row][pda->col].status)) { asmap->numQFailed++; if (asmap->failedPDA) asmap->failedPDAtwo = pda; else asmap->failedPDA = pda; } }}/***************************************************************************************** * * DuplicateASM -- duplicates an ASM and returns the new one * ****************************************************************************************/RF_AccessStripeMap_t *rf_DuplicateASM(asmap) RF_AccessStripeMap_t *asmap;{ RF_AccessStripeMap_t *new_asm; RF_PhysDiskAddr_t *pda, *new_pda, *t_pda; new_asm = rf_AllocAccessStripeMapComponent(); bcopy((char *)asmap, (char *)new_asm, sizeof(RF_AccessStripeMap_t)); new_asm->failedPDA = NULL; new_asm->physInfo = NULL; new_asm->parityInfo = NULL; new_asm->next = NULL; for (pda = asmap->physInfo; pda; pda=pda->next) { /* copy the physInfo list */ t_pda = rf_AllocPhysDiskAddr(); bcopy((char *)pda, (char *)t_pda, sizeof(RF_PhysDiskAddr_t)); t_pda->next = NULL; if (!new_asm->physInfo) {new_asm->physInfo = t_pda; new_pda = t_pda;} else {new_pda->next = t_pda; new_pda = new_pda->next;} if (pda == asmap->failedPDA) new_asm->failedPDA = t_pda; } for (pda = asmap->parityInfo; pda; pda=pda->next) { /* copy the parityInfo list */ t_pda = rf_AllocPhysDiskAddr(); bcopy((char *)pda, (char *)t_pda, sizeof(RF_PhysDiskAddr_t)); t_pda->next = NULL; if (!new_asm->parityInfo) {new_asm->parityInfo = t_pda; new_pda = t_pda;} else {new_pda->next = t_pda; new_pda = new_pda->next;} if (pda == asmap->failedPDA) new_asm->failedPDA = t_pda; } return(new_asm);}/***************************************************************************************** * * DuplicatePDA -- duplicates a PDA and returns the new one * ****************************************************************************************/RF_PhysDiskAddr_t *rf_DuplicatePDA(pda) RF_PhysDiskAddr_t *pda;{ RF_PhysDiskAddr_t *new; new = rf_AllocPhysDiskAddr(); bcopy((char *)pda, (char *)new, sizeof(RF_PhysDiskAddr_t)); return(new);}/***************************************************************************************** * * routines to allocate and free list elements. All allocation routines zero the * structure before returning it. * * FreePhysDiskAddr is static. It should never be called directly, because * FreeAccessStripeMap takes care of freeing the PhysDiskAddr list. * ****************************************************************************************/static RF_FreeList_t *rf_asmhdr_freelist;#define RF_MAX_FREE_ASMHDR 128#define RF_ASMHDR_INC 16#define RF_ASMHDR_INITIAL 32static RF_FreeList_t *rf_asm_freelist;#define RF_MAX_FREE_ASM 192#define RF_ASM_INC 24#define RF_ASM_INITIAL 64static RF_FreeList_t *rf_pda_freelist;#define RF_MAX_FREE_PDA 192#define RF_PDA_INC 24#define RF_PDA_INITIAL 64/* called at shutdown time. So far, all that is necessary is to release all the free lists */static void rf_ShutdownMapModule(ignored) void *ignored;{ RF_FREELIST_DESTROY(rf_asmhdr_freelist,next,(RF_AccessStripeMapHeader_t *)); RF_FREELIST_DESTROY(rf_pda_freelist,next,(RF_PhysDiskAddr_t *)); RF_FREELIST_DESTROY(rf_asm_freelist,next,(RF_AccessStripeMap_t *));}int rf_ConfigureMapModule(listp) RF_ShutdownList_t **listp;{ int rc; RF_FREELIST_CREATE(rf_asmhdr_freelist, RF_MAX_FREE_ASMHDR, RF_ASMHDR_INC, sizeof(RF_AccessStripeMapHeader_t)); if (rf_asmhdr_freelist == NULL) { return(ENOMEM); } RF_FREELIST_CREATE(rf_asm_freelist, RF_MAX_FREE_ASM, RF_ASM_INC, sizeof(RF_AccessStripeMap_t)); if (rf_asm_freelist == NULL) { RF_FREELIST_DESTROY(rf_asmhdr_freelist,next,(RF_AccessStripeMapHeader_t *)); return(ENOMEM); } RF_FREELIST_CREATE(rf_pda_freelist, RF_MAX_FREE_PDA, RF_PDA_INC, sizeof(RF_PhysDiskAddr_t)); if (rf_pda_freelist == NULL) { RF_FREELIST_DESTROY(rf_asmhdr_freelist,next,(RF_AccessStripeMapHeader_t *)); RF_FREELIST_DESTROY(rf_pda_freelist,next,(RF_PhysDiskAddr_t *)); return(ENOMEM); } rc = rf_ShutdownCreate(listp, rf_ShutdownMapModule, NULL); if (rc) { RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n", __FILE__, __LINE__, rc); rf_ShutdownMapModule(NULL); return(rc); } RF_FREELIST_PRIME(rf_asmhdr_freelist, RF_ASMHDR_INITIAL,next, (RF_AccessStripeMapHeader_t *)); RF_FREELIST_PRIME(rf_asm_freelist, RF_ASM_INITIAL,next, (RF_AccessStripeMap_t *)); RF_FREELIST_PRIME(rf_pda_freelist, RF_PDA_INITIAL,next, (RF_PhysDiskAddr_t *)); return(0);}RF_AccessStripeMapHeader_t *rf_AllocAccessStripeMapHeader(){ RF_AccessStripeMapHeader_t *p; RF_FREELIST_GET(rf_asmhdr_freelist,p,next,(RF_AccessStripeMapHeader_t *)); bzero((char *)p, sizeof(RF_AccessStripeMapHeader_t)); return(p);}void rf_FreeAccessStripeMapHeader(p) RF_AccessStripeMapHeader_t *p;{ RF_FREELIST_FREE(rf_asmhdr_freelist,p,next);}RF_PhysDiskAddr_t *rf_AllocPhysDiskAddr(){ RF_PhysDiskAddr_t *p; RF_FREELIST_GET(rf_pda_freelist,p,next,(RF_PhysDiskAddr_t *)); bzero((char *)p, sizeof(RF_PhysDiskAddr_t)); return(p);}/* allocates a list of PDAs, locking the free list only once * when we have to call calloc, we do it one component at a time to simplify * the process of freeing the list at program shutdown. This should not be * much of a performance hit, because it should be very infrequently executed. */RF_PhysDiskAddr_t *rf_AllocPDAList(count) int count;{ RF_PhysDiskAddr_t *p; RF_FREELIST_GET_N(rf_pda_freelist,p,next,(RF_PhysDiskAddr_t *),count); return(p);}void rf_FreePhysDiskAddr(p) RF_PhysDiskAddr_t *p;{ RF_FREELIST_FREE(rf_pda_freelist,p,next);}static void rf_FreePDAList(l_start, l_end, count) RF_PhysDiskAddr_t *l_start, *l_end; /* pointers to start and end of list */ int count; /* number of elements in list */{ RF_FREELIST_FREE_N(rf_pda_freelist,l_start,next,(RF_PhysDiskAddr_t *),count);}RF_AccessStripeMap_t *rf_AllocAccessStripeMapComponent(){ RF_AccessStripeMap_t *p; RF_FREELIST_GET(rf_asm_freelist,p,next,(RF_AccessStripeMap_t *)); bzero((char *)p, sizeof(RF_AccessStripeMap_t)); return(p);}/* this is essentially identical to AllocPDAList. I should combine the two. * when we have to call calloc, we do it one component at a time to simplify * the process of freeing the list at program shutdown. This should not be * much of a performance hit, because it should be very infrequently executed. */RF_AccessStripeMap_t *rf_AllocASMList(count) int count;{ RF_AccessStripeMap_t *p; RF_FREELIST_GET_N(rf_asm_freelist,p,next,(RF_AccessStripeMap_t *),count); return(p);}void rf_FreeAccessStripeMapComponent(p) RF_AccessStripeMap_t *p;{ RF_FREELIST_FREE(rf_asm_freelist,p,next);}static void rf_FreeASMList(l_start, l_end, count) RF_AccessStripeMap_t *l_start, *l_end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -