Esempio n. 1
0
/*
 * Stupid algorithm --- we now just search forward starting from the
 * goal.  Should put in a smarter one someday....
 */
errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
			   ext2fs_block_bitmap map, blk64_t *ret)
{
	errcode_t retval;
	blk64_t	b = 0;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!map)
		map = fs->block_map;
	if (!map)
		return EXT2_ET_NO_BLOCK_BITMAP;
	if (!goal || (goal >= ext2fs_blocks_count(fs->super)))
		goal = fs->super->s_first_data_block;
	goal &= ~EXT2FS_CLUSTER_MASK(fs);

	retval = ext2fs_find_first_zero_block_bitmap2(map,
			goal, ext2fs_blocks_count(fs->super) - 1, &b);
	if ((retval == ENOENT) && (goal != fs->super->s_first_data_block))
		retval = ext2fs_find_first_zero_block_bitmap2(map,
			fs->super->s_first_data_block, goal - 1, &b);
	if (retval == ENOENT)
		return EXT2_ET_BLOCK_ALLOC_FAIL;
	if (retval)
		return retval;

	clear_block_uninit(fs, ext2fs_group_of_blk2(fs, b));
	*ret = b;
	return 0;
}
Esempio n. 2
0
/*
 * Find the place where we should start allocating blocks for the huge
 * files.  Leave <slack> free blocks at the beginning of the file
 * system for things like metadata blocks.
 */
static blk64_t get_start_block(ext2_filsys fs, blk64_t slack)
{
    errcode_t retval;
    blk64_t blk = fs->super->s_first_data_block, next;
    blk64_t last_blk = ext2fs_blocks_count(fs->super) - 1;

    while (slack) {
        retval = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
                 blk, last_blk, &blk);
        if (retval)
            break;

        retval = ext2fs_find_first_set_block_bitmap2(fs->block_map,
                 blk, last_blk, &next);
        if (retval)
            next = last_blk;

        if (next - blk > slack) {
            blk += slack;
            break;
        }

        slack -= (next - blk);
        blk = next;
    }
    return blk;
}
Esempio n. 3
0
void do_ffzb(int argc, char *argv[])
{
	unsigned int start, end;
	int err;
	errcode_t retval;
	blk64_t out;

	if (check_fs_open(argv[0]))
		return;

	if (argc != 3 && argc != 3) {
		com_err(argv[0], 0, "Usage: ffzb <start> <end>");
		return;
	}

	start = parse_ulong(argv[1], argv[0], "start", &err);
	if (err)
		return;

	end = parse_ulong(argv[2], argv[0], "end", &err);
	if (err)
		return;

	retval = ext2fs_find_first_zero_block_bitmap2(test_fs->block_map,
						      start, end, &out);
	if (retval) {
		printf("ext2fs_find_first_zero_block_bitmap2() returned %s\n",
		       error_message(retval));
		return;
	}
	printf("First unmarked block is %llu\n", out);
}
Esempio n. 4
0
static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
			     ext2_ino_t dir, unsigned long idx, ext2_ino_t *ino)

{
	errcode_t		retval;
	blk64_t			lblk, bend = 0;
	__u64			size;
	blk64_t			left;
	blk64_t			count = 0;
	struct ext2_inode	inode;
	ext2_extent_handle_t	handle;

	retval = ext2fs_new_inode(fs, 0, LINUX_S_IFREG, NULL, ino);
	if (retval)
		return retval;

	memset(&inode, 0, sizeof(struct ext2_inode));
	inode.i_mode = LINUX_S_IFREG | (0666 & ~fs->umask);
	inode.i_links_count = 1;
	inode.i_uid = uid & 0xFFFF;
	ext2fs_set_i_uid_high(inode, (uid >> 16) & 0xffff);
	inode.i_gid = gid & 0xFFFF;
	ext2fs_set_i_gid_high(inode, (gid >> 16) & 0xffff);

	retval = ext2fs_write_new_inode(fs, *ino, &inode);
	if (retval)
		return retval;

	ext2fs_inode_alloc_stats2(fs, *ino, +1, 0);

	retval = ext2fs_extent_open2(fs, *ino, &inode, &handle);
	if (retval)
		return retval;

	/*
	 * We don't use ext2fs_fallocate() here because hugefiles are
	 * designed to be physically contiguous (if the block group
	 * descriptors are configured to be in a single block at the
	 * beginning of the file system, by using the
	 * packed_meta_blocks layout), with the extent tree blocks
	 * allocated near the beginning of the file system.
	 */
	lblk = 0;
	left = num ? num : 1;
	while (left) {
		blk64_t pblk, end;
		blk64_t n = left;

		retval =  ext2fs_find_first_zero_block_bitmap2(fs->block_map,
			goal, ext2fs_blocks_count(fs->super) - 1, &end);
		if (retval)
			goto errout;
		goal = end;

		retval =  ext2fs_find_first_set_block_bitmap2(fs->block_map, goal,
			       ext2fs_blocks_count(fs->super) - 1, &bend);
		if (retval == ENOENT) {
			bend = ext2fs_blocks_count(fs->super);
			if (num == 0)
				left = 0;
		}
		if (!num || bend - goal < left)
			n = bend - goal;
		pblk = goal;
		if (num)
			left -= n;
		goal += n;
		count += n;
		ext2fs_block_alloc_stats_range(fs, pblk, n, +1);

		if (zero_hugefile) {
			blk64_t ret_blk;
			retval = ext2fs_zero_blocks2(fs, pblk, n,
						     &ret_blk, NULL);

			if (retval)
				com_err(program_name, retval,
					_("while zeroing block %llu "
					  "for hugefile"), ret_blk);
		}

		while (n) {
			blk64_t l = n;
			struct ext2fs_extent newextent;

			if (l > EXT_INIT_MAX_LEN)
				l = EXT_INIT_MAX_LEN;

			newextent.e_len = l;
			newextent.e_pblk = pblk;
			newextent.e_lblk = lblk;
			newextent.e_flags = 0;

			retval = ext2fs_extent_insert(handle,
					EXT2_EXTENT_INSERT_AFTER, &newextent);
			if (retval)
				return retval;
			pblk += l;
			lblk += l;
			n -= l;
		}
	}

	retval = ext2fs_read_inode(fs, *ino, &inode);
	if (retval)
		goto errout;

	retval = ext2fs_iblk_add_blocks(fs, &inode,
					count / EXT2FS_CLUSTER_RATIO(fs));
	if (retval)
		goto errout;
	size = (__u64) count * fs->blocksize;
	retval = ext2fs_inode_size_set(fs, &inode, size);
	if (retval)
		goto errout;

	retval = ext2fs_write_new_inode(fs, *ino, &inode);
	if (retval)
		goto errout;

	if (idx_digits)
		sprintf(fn_numbuf, "%0*lu", idx_digits, idx);
	else if (num_files > 1)
		sprintf(fn_numbuf, "%lu", idx);

retry:
	retval = ext2fs_link(fs, dir, fn_buf, *ino, EXT2_FT_REG_FILE);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		retval = ext2fs_expand_dir(fs, dir);
		if (retval)
			goto errout;
		goto retry;
	}

	if (retval)
		goto errout;

errout:
	if (handle)
		ext2fs_extent_free(handle);

	return retval;
}