FreeBSD/sys/fs/ext2fs/ext2_alloc.c
/*
 * Determine whether an inode can be allocated.
 *
 * Check to see if an inode is available, and if it is,
 * allocate it using tode in the specified cylinder group.
 */
Determine whether an inode can be allocated.
Check to see if an inode is available, and if it is,
allocate it using tode in the specified cylinder group.
Determine whether an inode can be allocated . Check to see if an inode is available and if it is allocate it using tode in the specified cylinder group .
static daddr_t
ext2_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode)
{
	struct m_ext2fs *fs;
	struct buf *bp;
	struct ext2mount *ump;
	int error, start, len;
	char *ibp, *loc;
	ipref--; 
	if (ipref == -1)
		ipref = 0;
	fs = ip->i_e2fs;
	ump = ip->i_ump;
	if (fs->e2fs_gd[cg].ext2bgd_nifree == 0)
		return (0);
	EXT2_UNLOCK(ump);	
	error = bread(ip->i_devvp, fsbtodb(fs,
		fs->e2fs_gd[cg].ext2bgd_i_bitmap),
		(int)fs->e2fs_bsize, NOCRED, &bp);
	if (error) {
		brelse(bp);
		EXT2_LOCK(ump);
		return (0);
	}
	if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) {
		brelse(bp);
		EXT2_LOCK(ump);
		return (0);
	}
	ibp = (char *)bp->b_data;
	if (ipref) {
		ipref %= fs->e2fs->e2fs_ipg;
		if (isclr(ibp, ipref))
			goto gotit;
	}
	start = ipref / NBBY;
	len = howmany(fs->e2fs->e2fs_ipg - ipref, NBBY);
	loc = memcchr(&ibp[start], 0xff, len);
	if (loc == NULL) {
		len = start + 1;
		start = 0;
		loc = memcchr(&ibp[start], 0xff, len);
		if (loc == NULL) {
			printf("cg = %d, ipref = %lld, fs = %s\n",
				cg, (long long)ipref, fs->e2fs_fsmnt);
			panic("ext2fs_nodealloccg: map corrupted");
		}
	}
	ipref = (loc - ibp) * NBBY + ffs(~*loc) - 1;
gotit:
	setbit(ibp, ipref);
	EXT2_LOCK(ump);
	fs->e2fs_gd[cg].ext2bgd_nifree--;
	fs->e2fs->e2fs_ficount--;
	fs->e2fs_fmod = 1;
	if ((mode & IFMT) == IFDIR) {
		fs->e2fs_gd[cg].ext2bgd_ndirs++;
		fs->e2fs_total_dir++;
	}
	EXT2_UNLOCK(ump);
	bdwrite(bp);
	return (cg * fs->e2fs->e2fs_ipg + ipref +1);
}
static daddr_t ext2_nodealloccg ( struct inode * ip , int cg , daddr_t ipref , int mode ) { struct m_ext2fs * fs ; struct buf * bp ; struct ext2mount * ump ; int error , start , len ; char * ibp , * loc ; ipref -- ; if ( ipref == -1 ) ipref = 0 ; fs = ip -> i_e2fs ; ump = ip -> i_ump ; if ( fs -> e2fs_gd [ cg ] . ext2bgd_nifree == 0 ) return ( 0 ) ; EXT2_UNLOCK ( ump ) ; error = bread ( ip -> i_devvp , fsbtodb ( fs , fs -> e2fs_gd [ cg ] . ext2bgd_i_bitmap ) , ( int ) fs -> e2fs_bsize , NOCRED , & bp ) ; if ( error ) { brelse ( bp ) ; EXT2_LOCK ( ump ) ; return ( 0 ) ; } if ( fs -> e2fs_gd [ cg ] . ext2bgd_nifree == 0 ) { brelse ( bp ) ; EXT2_LOCK ( ump ) ; return ( 0 ) ; } ibp = ( char * ) bp -> b_data ; if ( ipref ) { ipref %= fs -> e2fs -> e2fs_ipg ; if ( isclr ( ibp , ipref ) ) goto gotit ; } start = ipref / NBBY ; len = howmany ( fs -> e2fs -> e2fs_ipg - ipref , NBBY ) ; loc = memcchr ( & ibp [ start ] , 0xff , len ) ; if ( loc == NULL ) { len = start + 1 ; start = 0 ; loc = memcchr ( & ibp [ start ] , 0xff , len ) ; if ( loc == NULL ) { printf ( " \n " , cg , ( long long ) ipref , fs -> e2fs_fsmnt ) ; panic ( " " ) ; } } ipref = ( loc - ibp ) * NBBY + ffs ( ~ * loc ) - 1 ; gotit : setbit ( ibp , ipref ) ; EXT2_LOCK ( ump ) ; fs -> e2fs_gd [ cg ] . ext2bgd_nifree -- ; fs -> e2fs -> e2fs_ficount -- ; fs -> e2fs_fmod = 1 ; if ( ( mode & IFMT ) == IFDIR ) { fs -> e2fs_gd [ cg ] . ext2bgd_ndirs ++ ; fs -> e2fs_total_dir ++ ; } EXT2_UNLOCK ( ump ) ; bdwrite ( bp ) ; return ( cg * fs -> e2fs -> e2fs_ipg + ipref + 1 ) ; }
Determine whether an inode can be allocated.
Determine whether an inode can be allocated .
/* to avoid a lot of (ipref -1) */ /*
		 * Another thread allocated the last i-node in this
		 * group while we were waiting for the buffer.
		 */ /* NOTREACHED */