示例#1
0
int
vhd_util_fill(int argc, char **argv)
{
	int err, c;
	char *name;
	void *buf;
	vhd_context_t vhd;
	uint64_t i, sec, secs, from_sector, to_sector;
	int init_bat;
	bool ignore_2tb_limit;

	buf          = NULL;
	name         = NULL;
	init_bat     = 0;
	from_sector  = ULLONG_MAX;
	to_sector    = ULLONG_MAX;
	ignore_2tb_limit = false;

	if (!argc || !argv)
		goto usage;

	optind = 0;
	while ((c = getopt(argc, argv, "n:f:t:bBh")) != -1) {
		switch (c) {
		case 'n':
			name = optarg;
			break;
		case 'f':
			from_sector = strtoull(optarg, NULL, 10);
			break;
		case 't':
			to_sector = strtoull(optarg, NULL, 10);
			break;
		case 'b':
			init_bat = 1;
			break;
		case 'B':
			ignore_2tb_limit = true;
			break;
		case 'h':
		default:
			goto usage;
		}
	}

	if (!name || optind != argc)
		goto usage;

	if ((from_sector != ULLONG_MAX || to_sector != ULLONG_MAX) && !init_bat) {
		printf("-f/-t can only be used with -b\n");
		goto usage;
	}

	if (from_sector != ULLONG_MAX && to_sector != ULLONG_MAX) {
		if (to_sector < from_sector) {
			printf("invalid sector range %llu-%llu\n",
					(unsigned long long)from_sector,
					(unsigned long long)to_sector);
			goto usage;
		}
	}

	if (ignore_2tb_limit && !init_bat) {
		printf("-B can only be used with -b\n");
		goto usage;
	}

	err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
	if (err) {
		printf("error opening %s: %d\n", name, err);
		return err;
	}

	err = vhd_get_bat(&vhd);
	if (err)
		goto done;

	if (init_bat) {
		uint32_t from_extent;
		uint32_t to_extent;

		if (from_sector != ULLONG_MAX)
			from_extent = from_sector / vhd.spb;
		else
			from_extent = 0;
		if (to_sector != ULLONG_MAX)
			to_extent = to_sector / vhd.spb;
		else
			to_extent = vhd.bat.entries - 1;
		err = vhd_io_allocate_blocks_fast(&vhd, from_extent, to_extent,
				ignore_2tb_limit);
		if (err)
			goto done;
	} else {
		err = posix_memalign(&buf, 4096, vhd.header.block_size);
		if (err) {
			err = -err;
			goto done;
		}

		sec = 0;
		secs = vhd.header.block_size >> VHD_SECTOR_SHIFT;

		for (i = 0; i < vhd.header.max_bat_size; i++) {
			err = vhd_io_read(&vhd, buf, sec, secs);
			if (err)
				goto done;

			err = vhd_io_write(&vhd, buf, sec, secs);
			if (err)
				goto done;

			sec += secs;
		}

		err = 0;
	}

done:
	free(buf);
	vhd_close(&vhd);
	return err;

usage:
	printf("options: <-n name> [-h help] [-b initialise the BAT and bitmaps, "
			"don't write to the data blocks (much faster)] [-f start "
			"intialisation from this sector, only usable with -b] [-t "
			"intialise up to this sector (inclusive), only usable with -b] "
			"[-B ignore the 2 TB limit, only usable with -b]\n");
	return -EINVAL;
}
int
vhd_util_fill(int argc, char **argv)
{
	int err, c;
	char *name;
	void *buf;
	vhd_context_t vhd;
	uint64_t i, sec, secs;

	buf  = NULL;
	name = NULL;

	if (!argc || !argv)
		goto usage;

	optind = 0;
	while ((c = getopt(argc, argv, "n:h")) != -1) {
		switch (c) {
		case 'n':
			name = optarg;
			break;
		case 'h':
		default:
			goto usage;
		}
	}

	if (!name || optind != argc)
		goto usage;

	err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
	if (err) {
		printf("error opening %s: %d\n", name, err);
		return err;
	}

	err = vhd_get_bat(&vhd);
	if (err)
		goto done;

	err = posix_memalign(&buf, 4096, vhd.header.block_size);
	if (err) {
		err = -err;
		goto done;
	}

	sec  = 0;
	secs = vhd.header.block_size >> VHD_SECTOR_SHIFT;

	for (i = 0; i < vhd.header.max_bat_size; i++) {
		err = vhd_io_read(&vhd, buf, sec, secs);
		if (err)
			goto done;

		err = vhd_io_write(&vhd, buf, sec, secs);
		if (err)
			goto done;

		sec += secs;
	}

	err = 0;

 done:
	free(buf);
	vhd_close(&vhd);
	return err;

usage:
	printf("options: <-n name> [-h help]\n");
	return -EINVAL;
}