FreeBSD/sys/fs/ext2fs/ext2_alloc.c
/*
 * Allocate a block in the filesystem.
 *
 * A preference may be optionally specified. If a preference is given
 * the following hierarchy is used to allocate a block:
 *   1) allocate the requested block.
 *   2) allocate a rotationally optimal block in the same cylinder.
 *   3) allocate a block in the same cylinder group.
 *   4) quadradically rehash into other cylinder groups, until an
 *        available block is located.
 * If no block preference is given the following hierarchy is used
 * to allocate a block:
 *   1) allocate a block in the cylinder group that contains the
 *        inode for the file.
 *   2) quadradically rehash into other cylinder groups, until an
 *        available block is located.
 */
Allocate a block in the filesystem.
A preference may be optionally specified. If a preference is given
the following hierarchy is used to allocate a block:
1) allocate the requested block.
2) allocate a rotationally optimal block in the same cylinder.
3) allocate a block in the same cylinder group.
4) quadradically rehash into other cylinder groups, until an
available block is located.
If no block preference is given the following hierarchy is used
to allocate a block:
1) allocate a block in the cylinder group that contains the
inode for the file.
2) quadradically rehash into other cylinder groups, until an
available block is located.
Allocate a block in the filesystem . A preference may be optionally specified . If a preference is given the following hierarchy is used to allocate a block : 1 ) allocate the requested block . 2 ) allocate a rotationally optimal block in the same cylinder . 3 ) allocate a block in the same cylinder group . 4 ) quadradically rehash into other cylinder groups until an available block is located . If no block preference is given the following hierarchy is used to allocate a block : 1 ) allocate a block in the cylinder group that contains the inode for the file . 2 ) quadradically rehash into other cylinder groups until an available block is located .
int
ext2_alloc(struct inode *ip, daddr_t lbn, e4fs_daddr_t bpref, int size,
    struct ucred *cred, e4fs_daddr_t *bnp)
{
	struct m_ext2fs *fs;
	struct ext2mount *ump;
	int32_t bno;
	int cg;	
	*bnp = 0;
	fs = ip->i_e2fs;
	ump = ip->i_ump;
	mtx_assert(EXT2_MTX(ump), MA_OWNED);
#ifdef INVARIANTS
	if ((u_int)size > fs->e2fs_bsize || blkoff(fs, size) != 0) {
		vn_printf(ip->i_devvp, "bsize = %lu, size = %d, fs = %s\n",
		    (long unsigned int)fs->e2fs_bsize, size, fs->e2fs_fsmnt);
		panic("ext2_alloc: bad size");
	}
	if (cred == NOCRED)
		panic("ext2_alloc: missing credential");
#endif 
	if (size == fs->e2fs_bsize && fs->e2fs->e2fs_fbcount == 0)
		goto nospace;
	if (cred->cr_uid != 0 && 
		fs->e2fs->e2fs_fbcount < fs->e2fs->e2fs_rbcount)
		goto nospace;
	if (bpref >= fs->e2fs->e2fs_bcount)
		bpref = 0;
	if (bpref == 0)
		cg = ino_to_cg(fs, ip->i_number);
	else
		cg = dtog(fs, bpref);
	bno = (daddr_t)ext2_hashalloc(ip, cg, bpref, fs->e2fs_bsize,
				      ext2_alloccg);
	if (bno > 0) {
		ip->i_next_alloc_block = lbn;
		ip->i_next_alloc_goal = bno;
		ip->i_blocks += btodb(fs->e2fs_bsize);
		ip->i_flag |= IN_CHANGE | IN_UPDATE;
		*bnp = bno;
		return (0);
	}
nospace:
	EXT2_UNLOCK(ump);
	ext2_fserr(fs, cred->cr_uid, "filesystem full");
	uprintf("\n%s: write failed, filesystem is full\n", fs->e2fs_fsmnt);
	return (ENOSPC);
}
int ext2_alloc ( struct inode * ip , daddr_t lbn , e4fs_daddr_t bpref , int size , struct ucred * cred , e4fs_daddr_t * bnp ) { struct m_ext2fs * fs ; struct ext2mount * ump ; int32_t bno ; int cg ; * bnp = 0 ; fs = ip -> i_e2fs ; ump = ip -> i_ump ; mtx_assert ( EXT2_MTX ( ump ) , MA_OWNED ) ; #ifdef INVARIANTS if ( ( u_int ) size > fs -> e2fs_bsize || blkoff ( fs , size ) != 0 ) { vn_printf ( ip -> i_devvp , " \n " , ( long unsigned int ) fs -> e2fs_bsize , size , fs -> e2fs_fsmnt ) ; panic ( " " ) ; } if ( cred == NOCRED ) panic ( " " ) ; #endif if ( size == fs -> e2fs_bsize && fs -> e2fs -> e2fs_fbcount == 0 ) goto nospace ; if ( cred -> cr_uid != 0 && fs -> e2fs -> e2fs_fbcount < fs -> e2fs -> e2fs_rbcount ) goto nospace ; if ( bpref >= fs -> e2fs -> e2fs_bcount ) bpref = 0 ; if ( bpref == 0 ) cg = ino_to_cg ( fs , ip -> i_number ) ; else cg = dtog ( fs , bpref ) ; bno = ( daddr_t ) ext2_hashalloc ( ip , cg , bpref , fs -> e2fs_bsize , ext2_alloccg ) ; if ( bno > 0 ) { ip -> i_next_alloc_block = lbn ; ip -> i_next_alloc_goal = bno ; ip -> i_blocks += btodb ( fs -> e2fs_bsize ) ; ip -> i_flag |= IN_CHANGE | IN_UPDATE ; * bnp = bno ; return ( 0 ) ; } nospace : EXT2_UNLOCK ( ump ) ; ext2_fserr ( fs , cred -> cr_uid , " " ) ; uprintf ( " \n \n " , fs -> e2fs_fsmnt ) ; return ( ENOSPC ) ; }
Allocate a block in the filesystem.
Allocate a block in the filesystem .
/* INVARIANTS */ /* set next_alloc fields as done in block_getblk */