📄 mscp_bbr.c
字号:
* * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step15( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register RCT_DESC *sp; u_long prev_block; u_long prev_offset; u_long new_event; Cprintf("mscp_bbr_step15: entered\n"); /* Calculate the offset of the new replacement descriptor and * mark it as unallocated, with an LBN of 0. */ sp = ( RCT_DESC * )bbrp->buf2 + ( bbrp->rbn % 128 ); sp->code = RCT_DS_UNALLOC; sp->lbn = 0; /* Calculate the LBN and offset of the previous replacement descriptor. * Fill in the descriptor with the "unusable" descriptor code and a zero * lbn. If the previous descriptor is in a different RCT block from the * current descriptor, multi-write the previous block into the RCT. * If the descriptors are in the same block, redispatch to write that * block immediately. */ prev_block = ( bbrp->match_rbn / 128 ) + up->unt_size + 2; prev_offset = bbrp->match_rbn % 128; if( prev_block != bbrp->cur_block ) { sp = ( RCT_DESC * )bbrp->buf3 + prev_offset; sp->lbn = bbrp->prev_desc.lbn; sp->code = bbrp->prev_desc.code; bbrp->multi_buf = bbrp->buf3; rp->p1 = ( bbrp->match_rbn / 128 ) + up->unt_size + 2; new_event = mscp_multi_write( rp ); } else { sp = ( RCT_DESC * )bbrp->buf2 + prev_offset; sp->lbn = bbrp->prev_desc.lbn; sp->code = bbrp->prev_desc.code; new_event = EV_BBRSUBSTEP; } return( new_event );}/**//* * * Name: mscp_bbr_step15a - * * Abstract: This function writes the second "restored" RCT * block to the RCT. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step15a( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; u_long new_event; Cprintf("mscp_bbr_step15a: entered\n"); /* Multi-write the descriptor block back into the RCT. */ bbrp->multi_buf = bbrp->buf2; rp->p1 = ( bbrp->rbn / 128 ) + up->unt_size + 2; new_event = mscp_multi_write( rp ); return( new_event );}/**//* * * Name: mscp_bbr_step16 - * * Abstract: This function attempts to write the saved data back to * the original LBN. It also logs an error to the system * error log if the RCT is full or corrupt. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step16( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register MSCP *mp = rp->msgptr; u_long new_event, flags, subcode; Cprintf("mscp_bbr_step16: entered\n"); flags = 0; switch( event ) { case EV_BBRRCTFULL: bbrp->flags.bit.full = 1; subcode = MSCP_SC_NORBL; mscp_bbr_log(rp, MSLG_FM_DISK_TRN, flags, subcode); break; case EV_BBRINVRCT: bbrp->flags.bit.corrupt = 1; subcode = MSCP_SC_RCTBD; mscp_bbr_log(rp, MSLG_FM_DISK_TRN, flags, subcode); break; default: break; } rp->p1 = bbrp->lbn; rp->p2 = 0; if( bbrp->flags.bit.fe ) rp->p2 |= MSCP_MD_ERROR; new_event = mscp_bbr_write( rp, bbrp->buf1 ); return( new_event );}/**//* * * Name: mscp_bbr_step17 - End of replacement update to RCT 0 * * Abstract: This function updates RCT sector 0 to reflect the * fact that replacement is no longer taking place. * The sector, read in step 6, is modified and rewritten * to the RCT. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step17( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register RCT_SECTOR_0 *sp = ( RCT_SECTOR_0 * )bbrp->buf0; Cprintf("mscp_bbr_step17: entered\n"); /* Update RCT sector 0 by clearing the replacement flags, the lbn * being replaced, the replacement block number, and the bad * replacement block number. */ sp->flags = 0; sp->lbn = 0; sp->rbn = 0; sp->badrbn = 0; /* Set up the buffer address and RCT sector 0 logical block * number and start the multicopy write. */ bbrp->multi_buf = bbrp->buf0; rp->p1 = up->unt_size; return( mscp_multi_write( rp ));}/**//* * * Name: mscp_bbr_step18 - Write protect the disk * * Abstract: This function logs the replacement attempt to the system * error log and calls bbr_unlock() to restart the stalled * I/O. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step18( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; u_long flags, subcode; Cprintf("mscp_bbr_step18: entered\n"); subcode = 0; flags = 0; if(bbrp->flags.bit.full) { subcode = MSCP_SC_RCTFL; if(bbrp->flags.bit.match) flags = MSLG_LFR_BR; } else if(bbrp->flags.bit.mwfail) { flags = MSLG_LFR_RI; subcode = MSCP_SC_ICRCT; if(bbrp->flags.bit.match) flags |= MSLG_LFR_BR; if(bbrp->flags.bit.rplatt) flags |= MSLG_LFR_RP; } else if(bbrp->flags.bit.mrfail) { flags = 0; subcode = MSCP_SC_ICRCT; if(bbrp->flags.bit.match) flags |= MSLG_LFR_BR; } else if(bbrp->flags.bit.corrupt) { flags = MSLG_LFR_RI; subcode = MSCP_SC_ICRCT; if(bbrp->flags.bit.match) flags |= MSLG_LFR_BR; } else if(bbrp->flags.bit.recurs) { subcode = MSCP_SC_RCTRC; flags = (MSLG_LFR_BR | MSLG_LFR_RP); } else if(bbrp->flags.bit.repfail) { flags = (MSLG_LFR_RP | MSLG_LFR_RF); if(bbrp->flags.bit.match) flags |= MSLG_LFR_BR; subcode = MSCP_SC_RPLFL; } mscp_bbr_log(rp, MSLG_FM_REPLACE, flags, subcode); mscp_bbr_unlock(rp); return( EV_NULL );}/**//* * * Name: mscp_rct_search - * * Abstract: This function issues the multi-read for the RCT block * which contains the primary RBN entry for the LBN we are * replacing. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_rct_search( event, rp ) u_long event; register REQB *rp;{ register UNITB *up = rp->unitb; register BBRB *bbrp = rp->connb->bbrb; Cprintf("mscp_rct_search: entered\n"); Push_bbr_state( ST_BB_RCTSEARCH ); bbrp->hash_rbn = ( bbrp->lbn / up->track ) * up->rbns; bbrp->max_host_rbn = ((( up->unt_size - 1 ) / up->track ) + 1 ) * up->rbns; bbrp->hash_block = ( bbrp->hash_rbn / 128 ) + up->unt_size + 2; bbrp->hash_offset = bbrp->hash_rbn % 128; bbrp->cur_block = bbrp->hash_block; bbrp->cur_rbn = bbrp->hash_rbn; bbrp->multi_buf = bbrp->buf2; rp->p1 = bbrp->hash_block; return( mscp_multi_read( rp ));}/**//* * * Name: mscp_rct_searcha - * * Abstract: This function searchs the original hashed RCT block for * a free RBN. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_rct_searcha( event, rp ) u_long event; REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register RCT_SECTOR_K *sp = ( RCT_SECTOR_K * )bbrp->buf2; register RCT_DESC *descp; register int delta = 0; register int offset = bbrp->hash_offset; register int step; u_long new_event = EV_NULL; Cprintf("mscp_rct_searcha: entered\n"); /* Search outward from the primary replacement block descriptor * until an available descriptor is found or another terminating * condition is seen: * descriptor block overflow or underflow, * end of the RCT, * or corrupted RCT. */ while(( offset >= 0 ) && ( offset < 128 ) && ( new_event == EV_NULL ) && ( !bbrp->flags.bit.eot )) { descp = &sp->desc[offset]; new_event = mscp_test_descr( bbrp, descp ); delta = -delta; if( delta >= 0 ) delta++; offset = bbrp->hash_offset + delta; bbrp->cur_rbn = bbrp->hash_rbn + delta; } /* If block overflow or underflow occurred without finding an * available descriptor or the end of the RCT, find the next * unexamined descriptor, and do a linear search of the remainder * of the block. */ if( new_event == EV_NULL && !bbrp->flags.bit.eot ) { delta = -delta; if( delta >= 0 ) { delta++; step = 1; } else step = -1; offset = bbrp->hash_offset + delta; bbrp->cur_rbn = bbrp->hash_rbn + delta; while(( offset >= 0 ) && ( offset < 128 ) && ( new_event == EV_NULL ) && ( !bbrp->flags.bit.eot )) { descp = &sp->desc[offset]; new_event = mscp_test_descr( bbrp, descp ); offset += step; bbrp->cur_rbn += step; } } /* If an available descriptor has been found or the RCT is corrupted, * pop the BBR state stack, and return status to the caller. */ if( new_event != EV_NULL ) { Pop_bbr_state(); /* No available descriptor has been found; continue * processing in the next search substep. */ } else new_event = EV_BBRSUBSTEP; return( new_event ); }/**//* * * Name: mscp_rct_searchb - * * Abstract: This function searchs RCT blocks other than the original * hashed block. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_rct_searchb( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register RCT_DESC *descp; register RCT_SECTOR_K *sp = ( RCT_SECTOR_K * )bbrp->buf2; int offset = 0; u_long new_event = EV_NULL; Cprintf("mscp_rct_searchb: entered, Event = %x\n", event); while( new_event == EV_NULL ) { /* If first time through or end of RCT block, calculate the LBN of * the next RCT block to read. If the end of the RCT has been seen, * wrap around to the beginning. Calculate the RBN corresponding to * the start of the RCT block. If the RBN is equal to the original * hashed primary descriptor RBN, the entire RCT has been searched * without encountering an available replacement block. In this case, * return RCT full status; otherwise, read the new block and exit to * wait for the read to complete. */ if(( event == EV_BBRSUBSTEP ) || ( offset >= 128 )) { if( !bbrp->flags.bit.eot ) bbrp->cur_block++; else { bbrp->cur_block = rp->unitb->unt_size + 2; bbrp->flags.bit.eot = 0; } bbrp->cur_rbn = 128 * ( bbrp->cur_block - ( rp->unitb->unt_size + 2 )); if( bbrp->cur_rbn == bbrp->hash_rbn ) { new_event = EV_BBRRCTFULL; } else { bbrp->multi_buf = bbrp->buf2; rp->p1 = bbrp->cur_block; return( mscp_multi_read( rp ) ); break; } /* The read completed. Do a linear search of the RCT block, looking * for an available replacement block descriptor. If the current * RBN matches the hashed primary descriptor RBN at any point in the * search, exit with RCT full status. */ } else { while(( offset < 128 ) && ( new_event == EV_NULL ) && ( !bbrp->flags.bit.eot )) { descp = &sp->desc[offset]; new_event = mscp_test_descr( bbrp, descp ); offset++; bbrp->cur_rbn++; /* If bumped rbn equals start and previous RBN was not * free, then RCT is full. */ if( (bbrp->cur_rbn == bbrp->hash_rbn) && (new_event == EV_NULL) ) new_event = EV_BBRRCTFULL; } } } /* If the new_event is not null, the search has terminated. Pop into * the context of the caller before exiting. If the new_event IS null, * the multi-read is underway and will return to this routine when * it completes. */ if( new_event != EV_NULL ) Pop_bbr_state(); /* If at the end of the RCT then wrap to beginning */ if( bbrp->flags.bit.eot ) new_event = EV_BBRSUBSTEP; return( new_event );}/**//* * * Name: mscp_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -