kernels/linux-2.4.0/fs/affs/bitmap.c
/* Find a new allocation zone, starting at zone_no. */
Find a new allocation zone, starting at zone_no.
Find a new allocation zone starting at zone_no .
static int
affs_find_new_zone(struct super_block *sb, int zone_no)
{
	struct affs_bm_info	*bm;
	struct affs_zone	*zone;
	struct affs_alloc_zone	*az;
	int			 bestfree;
	int			 bestno;
	int			 bestused;
	int			 lusers;
	int			 i;
	int			 min;
	pr_debug("AFFS: find_new_zone(zone_no=%d)\n",zone_no);
	bestfree = 0;
	bestused = -1;
	bestno   = -1;
	lusers   = MAX_ZONES;
	min      = zone_no ? AFFS_DATA_MIN_FREE : AFFS_HDR_MIN_FREE;
	lock_super(sb);
	zone = &sb->u.affs_sb.s_zones[zone_no];
	i    = zone->z_az_no;
	az   = &sb->u.affs_sb.s_alloc[i];
	if (zone->z_bm && zone->z_bm->bm_count) {
		if (--zone->z_bm->bm_count == 0) {
			affs_brelse(zone->z_bm->bm_bh);
			zone->z_bm->bm_bh = NULL;
		}
		if (az->az_count)
			az->az_count--;
		else
			affs_error(sb,"find_new_zone","az_count=0, but bm used");
	}
	while (1) {
		az = &sb->u.affs_sb.s_alloc[i];
		if (!az->az_count) {
			if (az->az_free > min) {
				break;
			}
			if (az->az_free > bestfree) {
				bestfree = az->az_free;
				bestno   = i;
			}
		} else if (az->az_free && az->az_count < lusers) {
			lusers   = az->az_count;
			bestused = i;
		}
		if (++i >= sb->u.affs_sb.s_num_az)
			i = 0;
		if (i == zone->z_az_no) {		
			if (bestno >= 0) {
				i = bestno;
			} else {
				i = bestused;
			}
			break;
		}
	}
	if (i < 0) {
		unlock_super(sb);
		return 0;
	}
	az = &sb->u.affs_sb.s_alloc[i];
	az->az_count++;
	bm = &sb->u.affs_sb.s_bitmap[i >> (sb->s_blocksize_bits - 7)];
	bm->bm_count++;
	if (!bm->bm_bh)
		bm->bm_bh = affs_bread(sb->s_dev,bm->bm_key,sb->s_blocksize);
	if (!bm->bm_bh) {
		bm->bm_count--;
		az->az_count--;
		unlock_super(sb);
		affs_error(sb,"find_new_zone","Cannot read bitmap");
		return 0;
	}
	zone->z_bm    = bm;
	zone->z_start = (i & ((sb->s_blocksize / 128) - 1)) * 32 + 1;
	zone->z_end   = zone->z_start + az->az_size;
	zone->z_az_no = i;
	zone->z_lru_time = jiffies;
	pr_debug("AFFS: found zone (%d) in bm %d at lw offset %d with %d free blocks\n",
		 i,(i >> (sb->s_blocksize_bits - 7)),zone->z_start,az->az_free);
	unlock_super(sb);
	return az->az_free;
}
static int affs_find_new_zone ( struct super_block * sb , int zone_no ) { struct affs_bm_info * bm ; struct affs_zone * zone ; struct affs_alloc_zone * az ; int bestfree ; int bestno ; int bestused ; int lusers ; int i ; int min ; pr_debug ( " \n " , zone_no ) ; bestfree = 0 ; bestused = -1 ; bestno = -1 ; lusers = MAX_ZONES ; min = zone_no ? AFFS_DATA_MIN_FREE : AFFS_HDR_MIN_FREE ; lock_super ( sb ) ; zone = & sb -> u . affs_sb . s_zones [ zone_no ] ; i = zone -> z_az_no ; az = & sb -> u . affs_sb . s_alloc [ i ] ; if ( zone -> z_bm && zone -> z_bm -> bm_count ) { if ( -- zone -> z_bm -> bm_count == 0 ) { affs_brelse ( zone -> z_bm -> bm_bh ) ; zone -> z_bm -> bm_bh = NULL ; } if ( az -> az_count ) az -> az_count -- ; else affs_error ( sb , " " , " " ) ; } while ( 1 ) { az = & sb -> u . affs_sb . s_alloc [ i ] ; if ( ! az -> az_count ) { if ( az -> az_free > min ) { break ; } if ( az -> az_free > bestfree ) { bestfree = az -> az_free ; bestno = i ; } } else if ( az -> az_free && az -> az_count < lusers ) { lusers = az -> az_count ; bestused = i ; } if ( ++ i >= sb -> u . affs_sb . s_num_az ) i = 0 ; if ( i == zone -> z_az_no ) { if ( bestno >= 0 ) { i = bestno ; } else { i = bestused ; } break ; } } if ( i < 0 ) { unlock_super ( sb ) ; return 0 ; } az = & sb -> u . affs_sb . s_alloc [ i ] ; az -> az_count ++ ; bm = & sb -> u . affs_sb . s_bitmap [ i >> ( sb -> s_blocksize_bits - 7 ) ] ; bm -> bm_count ++ ; if ( ! bm -> bm_bh ) bm -> bm_bh = affs_bread ( sb -> s_dev , bm -> bm_key , sb -> s_blocksize ) ; if ( ! bm -> bm_bh ) { bm -> bm_count -- ; az -> az_count -- ; unlock_super ( sb ) ; affs_error ( sb , " " , " " ) ; return 0 ; } zone -> z_bm = bm ; zone -> z_start = ( i & ( ( sb -> s_blocksize / 128 ) - 1 ) ) * 32 + 1 ; zone -> z_end = zone -> z_start + az -> az_size ; zone -> z_az_no = i ; zone -> z_lru_time = jiffies ; pr_debug ( " \n " , i , ( i >> ( sb -> s_blocksize_bits - 7 ) ) , zone -> z_start , az -> az_free ) ; unlock_super ( sb ) ; return az -> az_free ; }
Find a new allocation zone, starting at zone_no.
Find a new allocation zone starting at zone_no .
/* Seen all */ /* Didn't find a single free block anywhere. */