kernels/linux-2.4.0/fs/affs/bitmap.c
/*
 * Allocate a block in the given allocation zone.
 * Since we have to byte-swap the bitmap on little-endian
 * machines, this is rather expensive. Therefor we will
 * preallocate up to 16 blocks from the same word, if
 * possible. We are not doing preallocations in the
 * header zone, though.
 */
Allocate a block in the given allocation zone.
Since we have to byte-swap the bitmap on little-endian
machines, this is rather expensive. Therefor we will
preallocate up to 16 blocks from the same word, if
possible. We are not doing preallocations in the
header zone, though.
Allocate a block in the given allocation zone . Since we have to byte - swap the bitmap on little - endian machines this is rather expensive . Therefor we will preallocate up to 16 blocks from the same word if possible . We are not doing preallocations in the header zone though .
static s32
affs_balloc(struct inode *inode, int zone_no)
{
	u32			 w;
	u32			*bm;
	int			 fb;
	int			 i;
	int			 fwb;
	s32			 block;
	struct affs_zone	*zone;
	struct affs_alloc_zone	*az;
	struct super_block	*sb;
	sb   = inode->i_sb;
	zone = &sb->u.affs_sb.s_zones[zone_no];
	if (!zone->z_bm || !zone->z_bm->bm_bh)
		return 0;	
	pr_debug("AFFS: balloc(inode=%lu,zone=%d)\n",inode->i_ino,zone_no);
	az = &sb->u.affs_sb.s_alloc[zone->z_az_no];
	bm = (u32 *)zone->z_bm->bm_bh->b_data;
repeat:
	for (i = zone->z_start; i < zone->z_end; i++) {
		if (bm[i])
			goto found;
	}
	return 0;	
found:
	fwb = zone->z_bm->bm_firstblk + (i - 1) * 32;
	lock_super(sb);
	zone->z_start = i;
	w   = ~be32_to_cpu(bm[i]);
	fb  = find_first_zero_bit(&w,32);
	if (fb > 31 || !test_and_clear_bit(fb ^ BO_EXBITS,&bm[i])) {
		unlock_super(sb);
		affs_warning(sb,"balloc","Empty block disappeared somehow");
		goto repeat;
	}
	block = fwb + fb;
	az->az_free--;
	if (zone_no) {
		while (inode->u.affs_i.i_pa_cnt < AFFS_MAX_PREALLOC && ++fb < 32) {
			fb = find_next_zero_bit(&w,32,fb);
			if (fb > 31)
				break;
			if (!test_and_clear_bit(fb ^ BO_EXBITS,&bm[i])) {
				affs_warning(sb,"balloc","Empty block disappeared somehow");
				break;
			}
			inode->u.affs_i.i_data[inode->u.affs_i.i_pa_last++] = fwb + fb;
			inode->u.affs_i.i_pa_last &= AFFS_MAX_PREALLOC - 1;
			inode->u.affs_i.i_pa_cnt++;
			az->az_free--;
		}
	}
	w     = ~w - be32_to_cpu(bm[i]);
	bm[0] = cpu_to_be32(be32_to_cpu(bm[0]) + w);
	unlock_super(sb);
	mark_buffer_dirty(zone->z_bm->bm_bh);
	sb->s_dirt = 1;
	zone->z_lru_time = jiffies;
	return block;
}
static s32 affs_balloc ( struct inode * inode , int zone_no ) { u32 w ; u32 * bm ; int fb ; int i ; int fwb ; s32 block ; struct affs_zone * zone ; struct affs_alloc_zone * az ; struct super_block * sb ; sb = inode -> i_sb ; zone = & sb -> u . affs_sb . s_zones [ zone_no ] ; if ( ! zone -> z_bm || ! zone -> z_bm -> bm_bh ) return 0 ; pr_debug ( " \n " , inode -> i_ino , zone_no ) ; az = & sb -> u . affs_sb . s_alloc [ zone -> z_az_no ] ; bm = ( u32 * ) zone -> z_bm -> bm_bh -> b_data ; repeat : for ( i = zone -> z_start ; i < zone -> z_end ; i ++ ) { if ( bm [ i ] ) goto found ; } return 0 ; found : fwb = zone -> z_bm -> bm_firstblk + ( i - 1 ) * 32 ; lock_super ( sb ) ; zone -> z_start = i ; w = ~ be32_to_cpu ( bm [ i ] ) ; fb = find_first_zero_bit ( & w , 32 ) ; if ( fb > 31 || ! test_and_clear_bit ( fb ^ BO_EXBITS , & bm [ i ] ) ) { unlock_super ( sb ) ; affs_warning ( sb , " " , " " ) ; goto repeat ; } block = fwb + fb ; az -> az_free -- ; if ( zone_no ) { while ( inode -> u . affs_i . i_pa_cnt < AFFS_MAX_PREALLOC && ++ fb < 32 ) { fb = find_next_zero_bit ( & w , 32 , fb ) ; if ( fb > 31 ) break ; if ( ! test_and_clear_bit ( fb ^ BO_EXBITS , & bm [ i ] ) ) { affs_warning ( sb , " " , " " ) ; break ; } inode -> u . affs_i . i_data [ inode -> u . affs_i . i_pa_last ++ ] = fwb + fb ; inode -> u . affs_i . i_pa_last &= AFFS_MAX_PREALLOC - 1 ; inode -> u . affs_i . i_pa_cnt ++ ; az -> az_free -- ; } } w = ~ w - be32_to_cpu ( bm [ i ] ) ; bm [ 0 ] = cpu_to_be32 ( be32_to_cpu ( bm [ 0 ] ) + w ) ; unlock_super ( sb ) ; mark_buffer_dirty ( zone -> z_bm -> bm_bh ) ; sb -> s_dirt = 1 ; zone -> z_lru_time = jiffies ; return block ; }
Allocate a block in the given allocation zone.
Allocate a block in the given allocation zone .
/* prealloc as much as possible within this word, but not in header zone */