Re: question on ext2fs_get_free_blocks() in e2fsprogs

Eric Sandeen <[email protected]> Fri, 25 Aug 2006 12:52:27 -0500
Newsgroups gmane.comp.file-systems.ext2.devel
Message-ID <[email protected]>
Andreas Dilger wrote:

> This is what I'd think the behaviour _should_ be, but you need some
> input from Ted.

This is what I came up with; seems like it should be prettier than this, though :)

Ted?

/*
 * Look for num contiguous free blocks in the filesystem.
 *
 * If num is 0, search for a single block.
 *
 * start and finish may specify a range (inclusive) for the searh.
 *
 * If finish is nonzero, then the start-finish range is mandatory.
 * If num free blocks cannot be found within this range, then fail.
 *
 * If finish is 0, start is a hint only; search the whole filesystem, 
 * starting at block "start", wrapping if needed.
 *
 * If found, num blocks are available in the range starting at block ret.
 *
 * Return EXT2_ET_BLOCK_ALLOC_FAIL if requested blocks are not available
 * in the range. 
 */

errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
				 unsigned int num, ext2fs_block_bitmap map,
				 blk_t *ret)
{
	int wrap_ok = 0;	/* true if not mandatory range */

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!map)
		map = fs->block_map;
	if (!map)
		return EXT2_ET_NO_BLOCK_BITMAP;
	if (!start)
		start = fs->super->s_first_data_block;
	if (!num)
		num = 1;
	/* wrapping is ok only if finish isn't specified */
	if (!finish) {
		wrap_ok = 1;
		if (num > fs->super->s_blocks_count - start + 1)
			start = fs->super->s_first_data_block;
		finish = start;
	}
	/* probably no reason to fail this case */
	if (finish > fs->super->s_blocks_count)
		finish = fs->super->s_blocks_count;
	/* requested num larger than requested mandatory range */
	if ((num > finish - start + 1) && !wrap_ok)
		return EXT2_ET_BLOCK_ALLOC_FAIL;
	/* check for overflows or reversed range*/
	if ((start + num - 1 < start) || (finish < start))
		return EXT2_ET_BLOCK_ALLOC_FAIL;

	do {
		if (ext2fs_fast_test_block_bitmap_range(map, start, num)) {
			*ret = start;
			return 0;
		}
		start++;
		if ((start > fs->super->s_blocks_count - num + 1) && wrap_ok) {
			start = fs->super->s_first_data_block;
		}
	} while (( wrap_ok && (start != finish)) ||
		 (!wrap_ok && (start <= finish - num + 1)));

	return EXT2_ET_BLOCK_ALLOC_FAIL;
}




-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642