⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mscp_bbr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * *   Name:	mscp_bbr_step7b - Stress test bad block, continued * *   Abstract:	Step 7 of the bad block replacement algorithm *		issues reads and writes with correction and error *		recovery disabled to test the block in question. *		This function writes the saved data, then reads it *		back up to 4 times.  An error during writing or *		reading means that the stress test has failed and *		the block will have to be replaced. * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step7b( event, rp )    u_long			event;    register REQB		*rp;{    register BBRB		*bbrp = rp->connb->bbrb;    register MSCP		*mp = rp->msgptr;    register u_long		new_event = EV_NULL;    u_long			code = mp->mscp_status & MSCP_ST_MASK;    u_long			subcode = mp->mscp_status >> MSCP_ST_SBBIT;    Dprintf("mscp_bbr_step7b: entered, Event = %x\n", event);    /* If the event indicates initial entry for this substep, initialize     * the loop counter and write the saved data into the block in question.     */    if( event == EV_BBRSUCCESS ) {	bbrp->loop_ct1 = 4;	rp->p1 = bbrp->lbn;	rp->p2 = MSCP_MD_SECOR | MSCP_MD_SEREC;	new_event = mscp_bbr_write( rp, bbrp->buf1 );    /* Not initial entry, so an end message must have arrived.  If the     * the message was a write, and the write succeeded, start up the     * first read.  If the write failed, set an error flag and set the      * return status to cause redispatch to step 8.     */    } else if( mp->mscp_endcode == ( MSCP_OP_WRITE | MSCP_OP_END )) {	if( code == MSCP_ST_SUCC ) {	    new_event = mscp_bbr_read( rp, bbrp->buf3 );	} else {	    bbrp->flags.bit.error = 1;	    new_event = EV_BBRERROR;	}	        /* The end message was a read.  If the end message status is success     * and the bad block reported flag is set or the status is a data     * error other than forced error, the read failed.  Set an error flag     * and the return status.     */    } else if( (( code == MSCP_ST_SUCC ) && ( mp->mscp_flags & MSCP_EF_BBLKR ))	|| (( code == MSCP_ST_DATA ) && ( subcode != MSCP_SC_FRCER )) ) {	bbrp->flags.bit.error = 1;	new_event = EV_BBRERROR;    /* If the read succeeded and there are more reads to do, issue the     * next one.     */    } else if( --bbrp->loop_ct1 ) {	new_event = mscp_bbr_read( rp, bbrp->buf3 );    /* All of the stress reads succeeded.  Continue to the next substep.     */    } else {	new_event = EV_BBRSUCCESS;    }    return( new_event );}/**//* * *   Name:	mscp_bbr_step7c - Stress test bad block, continued * *   Abstract:	Step 7 of the bad block replacement algorithm *		issues reads and writes with correction and error *		recovery disabled to test the block in question. *		This function writes the inverse (one's complement) of *		the saved data, then reads it back up to 4 times.  An *		error during writing or	reading means that the stress *		test has failed and the block will have to be replaced. * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step7c( event, rp )    u_long			event;    register REQB		*rp;{    register BBRB		*bbrp = rp->connb->bbrb;    register MSCP		*mp = rp->msgptr;    register u_long		new_event = EV_NULL;    u_long			code = mp->mscp_status & MSCP_ST_MASK;    u_long			subcode = mp->mscp_status >> MSCP_ST_SBBIT;    Dprintf("mscp_bbr_step7c: entered, Event = %x\n", event);    /* If the event indicates initial entry for this substep, initialize     * the loop counter and write the inverse of the saved data into the     * block in question.  The data is written with error correction and     * error recovery suppressed, and with the forced error modifier set     * to protect the integrity of the block.     */    if( event == EV_BBRSUCCESS ) {	bbrp->loop_ct1 = 4;	rp->p1 = bbrp->lbn;	rp->p2 = MSCP_MD_SECOR | MSCP_MD_SEREC | MSCP_MD_ERROR;	new_event = mscp_bbr_write( rp, bbrp->buf2 );    /* Not initial entry, so an end message must have arrived.  If the     * the message was a write, and the write succeeded, start up the     * first read.  If the write failed, set an error flag and set the      * return status to EV_BBRERROR causing redispatch to step 8.     */    } else if( mp->mscp_endcode == ( MSCP_OP_WRITE | MSCP_OP_END )) {	if( code == MSCP_ST_SUCC ) {	    new_event = mscp_bbr_read( rp, bbrp->buf3 );	} else {	    bbrp->flags.bit.error = 1;	    new_event = EV_BBRERROR;	}	        /* The end message was a read.  If the end message status is success     * and the bad block reported flag is set or the status is a data     * error other than forced error, the read failed.  Set an error flag     * and set the return status to EV_BBRERROR.     */    } else if( (( code == MSCP_ST_SUCC ) && ( mp->mscp_flags & MSCP_EF_BBLKR ))	|| (( code == MSCP_ST_DATA ) && ( subcode != MSCP_SC_FRCER )) ) {	bbrp->flags.bit.error = 1;	new_event = EV_BBRERROR;    /* If the read succeeded and there are more reads to do, issue the     * next one.     */    } else if( --bbrp->loop_ct1 ) {	new_event = mscp_bbr_read( rp, bbrp->buf3 );    /* All of the stress reads succeeded.  If any more repetitions of the     * stress test remain, loop back to the substep corresponding to step     * 7b of the algorithm.  Otherwise,  set the return status to continue     * on to step 8.     */    } else if( --bbrp->loop_ct2 ) {	new_event = EV_BBRSUCCESS;    } else {	new_event = EV_BBRERROR;    }    return( new_event );}/**//* * *   Name:	mscp_bbr_step8 - Write back saved data * *   Abstract:	Step 8 of the bad block replacement algorithm *		writes the saved data back to the bad block, then *		reads it back and compares it to the saved data. *		If the step 7 stress testing and the step 8 write, *		read and compare operations all succeed, the block *		in question is not bad and doesn't need to be *		replaced. * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step8( event, rp )    u_long			event;    register REQB		*rp;{    register BBRB		*bbrp = rp->connb->bbrb;    register MSCP		*mp = rp->msgptr;    register u_long		new_event = EV_NULL;    u_long			code = mp->mscp_status & MSCP_ST_MASK;    u_long			subcode = mp->mscp_status >> MSCP_ST_SBBIT;    Cprintf("mscp_bbr_step8: entered, Event = %x\n", event);    /* On initial entry into this substep, initialize the loop counter     * and write the saved data into the block in question. If the FE flag     * is set, write the data with the forced error modifier.     */    if( (event == EV_BBRSUCCESS) || (event == EV_BBRERROR) ) {	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 );    /* Not the initial entry, so an end message arrived.  If the message was     * a write, and it succeeded, read back the data into another work     * buffer.  If the write failed or the error flag is set from step 7,     * set the status to EV_BBRERROR.     */    } else if( mp->mscp_endcode == ( MSCP_OP_WRITE | MSCP_OP_END )) {	if(( code != MSCP_ST_SUCC ) || ( bbrp->flags.bit.error ))	    new_event = EV_BBRERROR;	else	    new_event = mscp_bbr_read( rp, bbrp->buf3 );	        /* The end message was a read.  If the end message status is success     * or the status is a forced error and the data was written with the     * forced error modifier, the read succeeded.  Compare the saved data     * to the data read back.  If the read and the compare both succeeded,     * set the return status to EV_BBRSUCCESS.  Otherwise set it to     * EV_BBRERROR.     */    } else if(( code == MSCP_ST_SUCC ) || (( code == MSCP_ST_DATA ) &&	( subcode == MSCP_SC_FRCER ) && ( bbrp->flags.bit.fe )) &&	( bcmp( bbrp->buf1, bbrp->buf3, 512 ) == 0 )) {	new_event = EV_BBRSUCCESS;	bbrp->flags.bit.trans = 1;    /* The read failed:  set the error flag.     */    } else	new_event = EV_BBRERROR;    return( new_event );}/**//* * *   Name:	mscp_bbr_step9 - Search RCT for available RBN * *   Abstract:	This function invokes the RCT search routine to *		find an available replacement block.  In addition, *		a recursion counter is checked to ensure that this *		step is not reentered an excessive number of times *		from step 12 when replacing a bad replacement block. * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step9( event, rp )    u_long			event;    register REQB		*rp;{    register BBRB		*bbrp = rp->connb->bbrb;    register u_long		new_event;    Cprintf("mscp_bbr_step9: entered\n");    /* If the recursion count has not yet gone to zero, search the     * RCT for an available replacement block.  Otherwise, log the     * error and redispatch with error status.     */    if( bbrp->recursion_ct-- )	new_event = mscp_rct_search( EV_NULL, rp );    else {	bbrp->flags.bit.recurs = 1;	new_event = EV_BBRERROR;    }    return( new_event );}/**//* * *   Name:	mscp_bbr_step10 - Phase 2 update to RCT sector 0 * *   Abstract:	This function updates RCT sector 0 to reflect the  *		phase 2 state.	The sector, read in step 6, is *		modified and written to the RCT.   * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step10( 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_step10: entered\n");    /* Update RCT sector 0.  Set the phase 2 flag, clear the phase 1 and     * bad replacement block flags, and store the replacement block number.     * If the logical block has been replaced previously, set the bad     * replacement block flag and store the previous (bad) RBN.     */    sp->flags |=  RCT_S0_P2;    sp->flags &=  ~( RCT_S0_P1 | RCT_S0_BR );    sp->rbn = bbrp->rbn;    if( bbrp->flags.bit.match ) {	sp->flags |=  RCT_S0_BR;	sp->badrbn = bbrp->match_rbn;    }    /* 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_step11 -  * *   Abstract:	This function issues a read for the target RCT descriptor *		block if the block has not already been read (i.e. we got *		here from online processing) * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step11( 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			new_block;    u_long			new_event = EV_BBRSUCCESS;    Cprintf("mscp_bbr_step11: entered, Event = %x\n", event);    /* If in Phase 2 recovery must read in RCT block for destination RBN */    if( (event == EV_INITIAL) && bbrp->flags.bit.p2recov) {	new_block = ( bbrp->rbn / 128 ) + up->unt_size + 2;	bbrp->cur_block = new_block;	bbrp->multi_buf = bbrp->buf2;	rp->p1 = new_block;	new_event = mscp_multi_read( rp );    }    /* If it was necessary to read in a RCT block, processing     * will be continued in step11a when the multi-read completes.     * Otherwise, pass control to step11b.     */    return( new_event );}/**//* * *   Name:	mscp_bbr_step11a -  * *   Abstract:	This function updates the RCT descriptor block to record *		the replacement. If a previous replacement of this block had *		occurred and the descriptor is in a different RCT block, issue *		a read for that block. * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step11a( 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			new_block, old_block;    u_long			new_event = EV_BBRSUBSTEP;    Cprintf("mscp_bbr_step11a: entered\n");    Cprintf("lbn = %x, rbn = %x, block = %x\n", bbrp->lbn, bbrp->rbn, bbrp->cur_block);    /* Calculate the offset of the new replacement descriptor, then     * fill it in with the bad block lbn and primary/non-primary code.     * Set a flag to indicate that the RCT has been modified.     */	bbrp->flags.bit.rplatt = 1;	sp = (( RCT_DESC * )bbrp->buf2 ) + ( bbrp->rbn % 128 );	sp->lbn = bbrp->lbn;	if( bbrp->flags.bit.nonprim )	    sp->code = RCT_DS_NONPRIM;	else	    sp->code = RCT_DS_PRIMARY;    /* If there has been a previous replacement of the bad block and the     * current and previous replacement block descriptors fall into     * different RCT blocks, read the RCT block that contains the     * previous replacement block descriptor.  If the descriptors fall     * into the same RCT block, save a copy of the old descriptor in the     * BBRB, and fill in the old descriptor with the "unusable" code and a     * zero LBN.     */	if( bbrp->flags.bit.match ) {	    old_block = ( bbrp->match_rbn / 128 ) + up->unt_size + 2;	    if( old_block != bbrp->cur_block ) {		bbrp->multi_buf = bbrp->buf3;		rp->p1 = old_block;		new_event = mscp_multi_read( rp );	    } else {		sp = (( RCT_DESC * )bbrp->buf2 ) + ( bbrp->match_rbn % 128 );		bbrp->prev_desc.code = sp->code;		bbrp->prev_desc.lbn = sp->lbn;		sp->code = RCT_DS_UNUSABL;		sp->lbn = 0;	    }	}    /* If it was necessary to read in a second RCT block, processing     * will be continued in step11b when the multi-read completes.     * Otherwise, pass control to step11c.     */    return( new_event );}/**//* * *   Name:	mscp_bbr_step11b -  * *   Abstract:	This function writes the second updated RCT descriptor *		block to disk. * *   Inputs:	IPL_SCS *		event			Event code *		rp			Request block pointer * *   Implicit *   Inputs:	 * *   Outputs: * * *   Return	 *   Values:	EV_NULL */u_longmscp_bbr_step11b( 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			new_event;    Cprintf("mscp_bbr_step11b: entered\n");    /* Calculate the offset of the previous replacement descriptor, save a     * copy of the descriptor in the BBRB, and fill it in with the "unusable"     * descriptor code and a zero lbn.  Then multi-write the block back into     * the RCT.     */    sp = ( RCT_DESC * )bbrp->buf3 + ( bbrp->match_rbn % 128 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -