/****************************************************************** * 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() */
/**************************************************************************** * 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() */