예제 #1
0
/******************************************************************
 * NAME: 	scan_for_free_blocks
 *
 * FUNCTION: 	For each block on the sequential list of bad blocks,
 *		    Attempt to allocate the block to the JFS Bad Block inode.
 *
 *		    If this succeeds, the block was not already allocated to 
 *			and so no relocate was/is necessary.  Remove the
 *			block from the sequential list.  Notify the LVM
 *			that the bad LV blocks in this file system block
 *			can be removed from its list.
 *
 * 		    Otherwise, the block is allocated to some inode.  Leave
 *			it on the sequential list for relocation in a later
 *			step.
 *
 * PARAMETERS:	none
 *
 * NOTES:
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 scan_for_free_blocks() 
{
    int32 sffb_rc = 0;
    int32 atb_rc = 0;
    cbbl_bdblk_recptr bdblk_recptr, next_bdblk_recptr;

    bdblk_recptr = agg_recptr->bdblk_baltree.seq_list;
    while( bdblk_recptr != NULL ) {
	next_bdblk_recptr = bdblk_recptr->next;
	atb_rc = alloc_to_BBInode( bdblk_recptr );
	if( atb_rc == 0 ) {   /* the block is safely locked to the 
				* bad block inode 
				*/
	    sffb_rc = tell_LVM( bdblk_recptr );
	    if( sffb_rc == 0 ) {
		sffb_rc = seqlist_remove( bdblk_recptr );
		if( sffb_rc == 0 ) { 
		    sffb_rc = freelist_insert( bdblk_recptr );
		    }
		}
	    }  /* end the block is safely locked to the bad block inode */
	bdblk_recptr = next_bdblk_recptr;
	}
	
    return( sffb_rc );
}				/* end scan_for_free_blocks() */
예제 #2
0
/****************************************************************************
 * NAME: 	we_Did_Relocate 
 *		
 * FUNCTION:	For each entry (on the sequential list of bad blocks)
 *		which describes a block in the specified extent, attempt
 *		to allocate the block to the JFS Bad Block inode. 
 *
 *		If able to allocate the block to the Bad Block inode,
 *		remove the entry from the sequential list and tell the 
 *		LVM to remove applicable entries from its bad block list
 *
 *		If unable to allocate the block to the Bad Block inode,
 *		remove the entry from the sequential list and add it to 
 *		the retry list.  Increment counters as appropriate.
 *
 * PARAMETERS:	
 *	ext_firstblk	the first block in the extent which the caller
 *			has relocated
 *
 *	ext_lastblk	the last block in the extent which the caller 
 *			has relocated
 *
 *	bdblk_recptr	ptr to the first record in the sequential list 
 *			which describes a block in the extent which the
 *			caller has relocated
 *
 * NOTES:	
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 we_Did_Relocate( int64		ext_firstblk,
		       int64		ext_lastblk,
		       cbbl_bdblk_recptr	bdblk_recptr
		       )
{
    int32 fdr_rc = 0;
    int64 idx, block_limit;
    int8  done;
    cbbl_bdblk_recptr thisrec, nextrec;

	/* 
	 * Increment # of relocated extents
	 */
    agg_recptr->reloc_extents += 1;
    agg_recptr->reloc_blocks += ext_lastblk - ext_firstblk + 1;

    done = 0;
    block_limit = ext_lastblk + 1;
    thisrec = bdblk_recptr;
    for( idx = ext_firstblk; 
	 ((idx < block_limit) && (fdr_rc == 0) && (!done)); 
	 idx++ ) {	/* process each fs block in the extent */
	
	if( thisrec == NULL ) {  /* 
				* no more in sequential list 
				*/
	    done = -1;
	    }  /* end no more in sequential list */
	
	else if( thisrec->fs_blkno > block_limit ) {  /* 
				* no more in this extent 
				*/
	    done = -1;
	    }  /* end no more in this extent */
	
	else {	/* there may be more bad blocks in this extent */
		/*
		 * locate next on sequential list of bad blocks
		 */
	    nextrec = thisrec->next;  
	    if( thisrec->fs_blkno == idx ) {  /* this is a bad block */
			/*
			 * increment # times data relocated from this block
			 */
		thisrec->relocated_count += 1;
			/*
			 * attempt to allocate the block to the 
			 * JFS Bad Block inode
			 */
		fdr_rc = alloc_to_BBInode( thisrec );
		if( fdr_rc != 0 ) {  	/* 
					 * couldn't allocate the block 
					 */
		    fdr_rc = seqlist_remove( thisrec );
		    fdr_rc = retrylist_insert( thisrec );
		    thisrec->retry_list_count += 1;
		    thisrec->tooslow_count += 1;
		    }  /* end couldn't allocate the block */
		else {	/* 
			 * the block is allocated to the bad block inode 
			 */
		    fdr_rc = tell_LVM( thisrec );
			/*
			 * take the record off the sequential list and
			 * put it into the resolved blocks list.
			 *
			 * N.B. this record is STILL in the tree
			 */
		    fdr_rc = seqlist_remove( thisrec );  
		    fdr_rc = rslvdlist_insert( thisrec );
		    }  /* end else the block is allocated to the bad ... */
			/*
			 * move on to next in sequential list 
			 */
		thisrec = nextrec;
		}  /* end this is a bad block */
	    }  /* end else there may be more bad blocks in this extent */
	}  /* end for idx = ... */
	
    return( fdr_rc );
}				/* end we_Did_Relocate()	*/