亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? vhd-util-resize.c

?? xen source 推出最新的VHD操作工具VHD-UTIL 實現源碼,超強
?? C
?? 第 1 頁 / 共 2 頁
字號:
	next = 0;
	spp  = getpagesize() >> VHD_SECTOR_SHIFT;

	for (i = 0; i < vhd->bat.entries; i++) {
		blk = vhd->bat.bat[i];

		if (blk != DD_BLK_UNUSED) {
			end  = blk + vhd->spb + vhd->bm_secs;
			next = MAX(next, end);
		}
	}

	return next;
}

static inline int
in_range(off64_t off, off64_t start, off64_t size)
{
	return (start < off && start + size > off);
}

#define SKIP_HEADER 0x01
#define SKIP_BAT    0x02
#define SKIP_BATMAP 0x04
#define SKIP_PLOC   0x08
#define SKIP_DATA   0x10

static inline int
skip_check(int mode, int type)
{
	return mode & type;
}

static int
vhd_check_for_clobber(vhd_context_t *vhd, off64_t off, int mode)
{
	int i, n;
	char *msg;
	size_t size;
	vhd_block_t fb;
	vhd_parent_locator_t *loc;

	msg = NULL;

	if (!vhd_type_dynamic(vhd))
		return 0;

	if (off < VHD_SECTOR_SIZE) {
		msg = "backup footer";
		goto fail;
	}

	if (!skip_check(mode, SKIP_HEADER))
		if (in_range(off,
			     vhd->footer.data_offset, sizeof(vhd_header_t))) {
			msg = "header";
			goto fail;
		}

	if (!skip_check(mode, SKIP_BAT))
		if (in_range(off, vhd->header.table_offset,
			     vhd_bytes_padded(vhd->header.max_bat_size *
					      sizeof(uint32_t)))) {
			msg = "bat";
			goto fail;
		}

	if (!skip_check(mode, SKIP_BATMAP))
		if (vhd_has_batmap(vhd) &&
		    in_range(off, vhd->batmap.header.batmap_offset,
			     vhd_bytes_padded(vhd->batmap.header.batmap_size))) {
			msg = "batmap";
			goto fail;
		}

	if (!skip_check(mode, SKIP_PLOC)) {
		n = sizeof(vhd->header.loc) / sizeof(vhd_parent_locator_t);
		for (i = 0; i < n; i++) {
			loc = vhd->header.loc + i;
			if (loc->code == PLAT_CODE_NONE)
				continue;

			size = vhd_parent_locator_size(loc);
			if (in_range(off, loc->data_offset, size)) {
				msg = "parent locator";
				goto fail;
			}
		}
	}

	if (!skip_check(mode, SKIP_DATA)) {
		vhd_first_data_block(vhd, &fb);
		if (fb.offset && in_range(off,
					  vhd_sectors_to_bytes(fb.offset),
					  VHD_BLOCK_SIZE)) {
			msg = "data block";
			goto fail;
		}
	}

	return 0;

fail:
	EPRINTF("write to 0x%08"PRIx64" would clobber %s\n", off, msg);
	return -EINVAL;
}

/*
 * take any metadata after the bat (@eob) and shift it
 */
static int
vhd_shift_metadata(vhd_journal_t *journal, off64_t eob,
		   size_t bat_needed, size_t map_needed)
{
	int i, n, err;
	vhd_context_t *vhd;
	size_t size_needed;
	char *buf, **locators;
	vhd_parent_locator_t *loc;

	vhd         = &journal->vhd;
	size_needed = bat_needed + map_needed;

	n = sizeof(vhd->header.loc) / sizeof(vhd_parent_locator_t);

	locators = calloc(n, sizeof(char *));
	if (!locators)
		return -ENOMEM;

	for (i = 0; i < n; i++) {
		size_t size;

		loc = vhd->header.loc + i;
		if (loc->code == PLAT_CODE_NONE)
			continue;

		if (loc->data_offset < eob)
			continue;

		size = vhd_parent_locator_size(loc);
		err  = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, size);
		if (err) {
			err = -err;
			buf = NULL;
			goto out;
		}

		err  = vhd_seek(vhd, loc->data_offset, SEEK_SET);
		if (err)
			goto out;

		err  = vhd_read(vhd, buf, size);
		if (err)
			goto out;

		locators[i] = buf;
	}

	for (i = 0; i < n; i++) {
		off64_t off;
		size_t size;

		if (!locators[i])
			continue;

		loc  = vhd->header.loc + i;
		off  = loc->data_offset + size_needed;
		size = vhd_parent_locator_size(loc);

		if (vhd_check_for_clobber(vhd, off + size, SKIP_PLOC)) {
			EPRINTF("%s: shifting locator %d would clobber data\n",
				vhd->file, i);
			return -EINVAL;
		}

		err  = vhd_seek(vhd, off, SEEK_SET);
		if (err)
			goto out;

		err  = vhd_write(vhd, locators[i], size);
		if (err)
			goto out;

		free(locators[i]);
		locators[i]      = NULL;
		loc->data_offset = off;

		/* write the new header after writing the new bat */
	}

	if (vhd_has_batmap(vhd) && vhd->batmap.header.batmap_offset > eob) {
		vhd->batmap.header.batmap_offset += bat_needed;

		/* write the new batmap after writing the new bat */
	}

	err = 0;

out:
	for (i = 0; i < n; i++)
		free(locators[i]);
	free(locators);

	return err;
}

static int
vhd_add_bat_entries(vhd_journal_t *journal, int entries)
{
	int i, err;
	off64_t off;
	vhd_bat_t new_bat;
	vhd_context_t *vhd;
	uint32_t new_entries;
	vhd_batmap_t new_batmap;
	uint64_t bat_size, new_bat_size, map_size, new_map_size;

	vhd          = &journal->vhd;
	new_entries  = vhd->header.max_bat_size + entries;

	bat_size     = vhd_bytes_padded(vhd->header.max_bat_size *
					sizeof(uint32_t));
	new_bat_size = vhd_bytes_padded(new_entries * sizeof(uint32_t));

	map_size     = vhd_bytes_padded((vhd->header.max_bat_size + 7) >> 3);
	new_map_size = vhd_bytes_padded((new_entries + 7) >> 3);

	off = vhd->header.table_offset + new_bat_size;
	if (vhd_check_for_clobber(vhd, off, SKIP_BAT | SKIP_BATMAP)) {
		EPRINTF("%s: writing new bat of 0x%"PRIx64" bytes "
			"at 0x%08llx would clobber data\n", 
			vhd->file, new_bat_size, vhd->header.table_offset);
		return -EINVAL;
	}

	if (vhd_has_batmap(vhd)) {
		off = vhd->batmap.header.batmap_offset + new_map_size;
		if (vhd_check_for_clobber(vhd, off, 0)) {
			EPRINTF("%s: writing new batmap of 0x%"PRIx64" bytes"
				" at 0x%08llx would clobber data\n", vhd->file,
				new_map_size, vhd->batmap.header.batmap_offset);
			return -EINVAL;
		}
	}

	/* update header */
	vhd->header.max_bat_size = new_entries;
	err = vhd_write_header(vhd, &vhd->header);
	if (err)
		return err;

	/* update footer */
	vhd->footer.curr_size = (uint64_t)new_entries * vhd->header.block_size;
	vhd->footer.geometry  = vhd_chs(vhd->footer.curr_size);
	vhd->footer.checksum  = vhd_checksum_footer(&vhd->footer);
	err = vhd_write_footer(vhd, &vhd->footer);
	if (err)
		return err;

	/* allocate new bat */
	err = posix_memalign((void **)&new_bat.bat, VHD_SECTOR_SIZE, new_bat_size);
	if (err)
		return -err;

	new_bat.spb     = vhd->bat.spb;
	new_bat.entries = new_entries;
	memcpy(new_bat.bat, vhd->bat.bat, bat_size);
	for (i = vhd->bat.entries; i < new_entries; i++)
		new_bat.bat[i] = DD_BLK_UNUSED;

	/* write new bat */
	err = vhd_write_bat(vhd, &new_bat);
	if (err) {
		free(new_bat.bat);
		return err;
	}

	/* update in-memory bat */
	free(vhd->bat.bat);
	vhd->bat = new_bat;

	if (!vhd_has_batmap(vhd))
		return 0;

	/* allocate new batmap */
	err = posix_memalign((void **)&new_batmap.map,
			     VHD_SECTOR_SIZE, new_map_size);
	if (err)
		return err;

	new_batmap.header = vhd->batmap.header;
	new_batmap.header.batmap_size = secs_round_up_no_zero(new_map_size);
	memcpy(new_batmap.map, vhd->batmap.map, map_size);
	memset(new_batmap.map + map_size, 0, new_map_size - map_size);

	/* write new batmap */
	err = vhd_write_batmap(vhd, &new_batmap);
	if (err) {
		free(new_batmap.map);
		return err;
	}

	/* update in-memory batmap */
	free(vhd->batmap.map);
	vhd->batmap = new_batmap;

	return 0;
}

static int
vhd_dynamic_grow(vhd_journal_t *journal, uint64_t secs)
{
	int i, err;
	off64_t eob, eom;
	vhd_context_t *vhd;
	vhd_block_t first_block;
	uint64_t blocks, size_needed;
	uint64_t bat_needed, bat_size, bat_avail, bat_bytes, bat_secs;
	uint64_t map_needed, map_size, map_avail, map_bytes, map_secs;

	vhd         = &journal->vhd;

	size_needed = 0;
	bat_needed  = 0;
	map_needed  = 0;

	/* number of vhd blocks to add */
	blocks      = secs_to_blocks_up(vhd, secs);

	/* size in bytes needed for new bat entries */
	bat_needed  = blocks * sizeof(uint32_t);
	map_needed  = (blocks >> 3) + 1;

	/* available bytes in current bat */
	bat_bytes   = vhd->header.max_bat_size * sizeof(uint32_t);
	bat_secs    = secs_round_up_no_zero(bat_bytes);
	bat_size    = vhd_sectors_to_bytes(bat_secs);
	bat_avail   = bat_size - bat_bytes;

	if (vhd_has_batmap(vhd)) {
		/* avaliable bytes in current batmap */
		map_bytes   = (vhd->header.max_bat_size + 7) >> 3;
		map_secs    = vhd->batmap.header.batmap_size;
		map_size    = vhd_sectors_to_bytes(map_secs);
		map_avail   = map_size - map_bytes;
	} else {
		map_needed  = 0;
		map_avail   = 0;
	}

	/* we have enough space already; just extend the bat */
	if (bat_needed <= bat_avail && map_needed <= map_avail)
		goto add_entries;

	/* we need to add new sectors to the bat */
	if (bat_needed > bat_avail) {
		bat_needed -= bat_avail;
		bat_needed  = vhd_bytes_padded(bat_needed);
	} else
		bat_needed  = 0;

	/* we need to add new sectors to the batmap */
	if (map_needed > map_avail) {
		map_needed -= map_avail;
		map_needed  = vhd_bytes_padded(map_needed);
	} else
		map_needed  = 0;

	/* how many additional bytes do we need? */
	size_needed = bat_needed + map_needed;

	/* calculate space between end of headers and beginning of data */
	err = vhd_end_of_headers(vhd, &eom);
	if (err)
		return err;

	eob = vhd->header.table_offset + vhd_sectors_to_bytes(bat_secs);
	vhd_first_data_block(vhd, &first_block);

	/* no blocks allocated; just shift post-bat metadata */
	if (!first_block.offset)
		goto shift_metadata;

	/* 
	 * not enough space -- 
	 * move vhd data blocks to the end of the file to make room 
	 */
	do {
		off64_t new_off, bm_size, gap_size;

		new_off = vhd_sectors_to_bytes(vhd_next_block_offset(vhd));

		/* data region of segment should begin on page boundary */
		bm_size = vhd_sectors_to_bytes(vhd->bm_secs);
		if ((new_off + bm_size) % 4096) {
			gap_size = 4096 - ((new_off + bm_size) % 4096);

			err = vhd_write_zeros(journal, new_off, gap_size);
			if (err)
				return err;

			new_off += gap_size;
		}

		err = vhd_move_block(journal, first_block.block, new_off);
		if (err)
			return err;

		vhd_first_data_block(vhd, &first_block);

	} while (eom + size_needed >= vhd_sectors_to_bytes(first_block.offset));

	TEST_FAIL_AT(FAIL_RESIZE_DATA_MOVED);

shift_metadata:
	/* shift any metadata after the bat to make room for new bat sectors */
	err = vhd_shift_metadata(journal, eob, bat_needed, map_needed);
	if (err)
		return err;

	TEST_FAIL_AT(FAIL_RESIZE_METADATA_MOVED);

add_entries:
	return vhd_add_bat_entries(journal, blocks);
}

static int
vhd_dynamic_resize(vhd_journal_t *journal, uint64_t size)
{
	int err;
	vhd_context_t *vhd;
	uint64_t cur_secs, new_secs;

	vhd      = &journal->vhd;
	cur_secs = vhd->footer.curr_size >> VHD_SECTOR_SHIFT;
	new_secs = size << (20 - VHD_SECTOR_SHIFT);

	if (cur_secs == new_secs)
		return 0;

	err = vhd_get_header(vhd);
	if (err)
		return err;

	err = vhd_get_bat(vhd);
	if (err)
		return err;

	if (vhd_has_batmap(vhd)) {
		err = vhd_get_batmap(vhd);
		if (err)
			return err;
	}

	if (cur_secs > new_secs)
		err = vhd_dynamic_shrink(journal, cur_secs - new_secs);
	else
		err = vhd_dynamic_grow(journal, new_secs - cur_secs);

	return err;
}

static int
vhd_util_resize_check_creator(const char *name)
{
	int err;
	vhd_context_t vhd;

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

	if (!vhd_creator_tapdisk(&vhd)) {
		printf("%s not created by xen; resize not supported\n", name);
		err = -EINVAL;
	}

	vhd_close(&vhd);
	return err;
}

int
vhd_util_resize(int argc, char **argv)
{
	char *name, *jname;
	uint64_t size;
	int c, err, jerr;
	vhd_journal_t journal;
	vhd_context_t *vhd;

	err   = -EINVAL;
	size  = 0;
	name  = NULL;
	jname = NULL;

	optind = 0;
	while ((c = getopt(argc, argv, "n:j:s:h")) != -1) {
		switch (c) {
		case 'n':
			name = optarg;
			break;
		case 'j':
			jname = optarg;
			break;
		case 's':
			err  = 0;
			size = strtoull(optarg, NULL, 10);
			break;
		case 'h':
		default:
			goto usage;
		}
	}

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

	err = vhd_util_resize_check_creator(name);
	if (err)
		return err;

	libvhd_set_log_level(1);
	err = vhd_journal_create(&journal, name, jname);
	if (err) {
		printf("creating journal failed: %d\n", err);
		return err;
	}

	vhd = &journal.vhd;

	err = vhd_get_footer(vhd);
	if (err)
		goto out;

	TEST_FAIL_AT(FAIL_RESIZE_BEGIN);

	if (vhd_type_dynamic(vhd))
		err = vhd_dynamic_resize(&journal, size);
	else
		err = vhd_fixed_resize(&journal, size);

	TEST_FAIL_AT(FAIL_RESIZE_END);

out:
	if (err) {
		printf("resize failed: %d\n", err);
		jerr = vhd_journal_revert(&journal);
	} else
		jerr = vhd_journal_commit(&journal);

	if (jerr) {
		printf("closing journal failed: %d\n", jerr);
		vhd_journal_close(&journal);
	} else
		vhd_journal_remove(&journal);

	return (err ? : jerr);

usage:
	printf("options: <-n name> <-j journal> <-s size (in MB)> [-h help]\n");
	return -EINVAL;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久91精品国产91久久小草| 国产精品夜夜嗨| 国产在线精品一区二区夜色 | 一本一道综合狠狠老| 欧美人与禽zozo性伦| 国产精品丝袜久久久久久app| 五月天视频一区| 高清国产一区二区三区| 欧美一区欧美二区| 成人免费在线视频观看| 精品一区二区三区免费毛片爱| av高清不卡在线| 2017欧美狠狠色| 日韩在线卡一卡二| 欧美综合亚洲图片综合区| 久久久精品tv| 久久精品国产亚洲一区二区三区| 欧洲中文字幕精品| 亚洲三级免费电影| 成人美女在线观看| 精品粉嫩aⅴ一区二区三区四区| 亚洲一区日韩精品中文字幕| 成人午夜免费av| 国产视频一区在线播放| 精品一区二区在线免费观看| 在线成人av网站| 无吗不卡中文字幕| 欧美午夜精品一区二区三区| 亚洲免费视频成人| a亚洲天堂av| 亚洲色图.com| 91国模大尺度私拍在线视频 | 91精品国产综合久久久久| 亚洲精品日韩一| 97超碰欧美中文字幕| 中文字幕第一区第二区| 国产成a人亚洲| 国产清纯美女被跳蛋高潮一区二区久久w | 亚洲午夜精品网| 色88888久久久久久影院按摩| 最新欧美精品一区二区三区| 成人性生交大片免费看视频在线 | 成人黄色免费短视频| 国产欧美精品一区aⅴ影院 | 久久婷婷国产综合国色天香| 捆绑紧缚一区二区三区视频| 日韩精品一区二区在线| 精品无人区卡一卡二卡三乱码免费卡| 日韩欧美不卡一区| 国产美女精品人人做人人爽| 久久久久9999亚洲精品| 成人18视频日本| 亚洲精品乱码久久久久| 欧美日韩精品一区二区| 日本成人在线不卡视频| 欧美成人激情免费网| 国产激情精品久久久第一区二区| 国产欧美日韩麻豆91| 91网站在线播放| 午夜久久电影网| 亚洲精品一区在线观看| 99久久精品国产一区二区三区| 亚洲视频一区二区在线| 3d动漫精品啪啪1区2区免费| 美国十次了思思久久精品导航| 国产亚洲婷婷免费| 91视视频在线直接观看在线看网页在线看| 亚洲精品欧美激情| 欧美岛国在线观看| k8久久久一区二区三区| 五月婷婷综合激情| 亚洲国产精品t66y| 日本伦理一区二区| 丝袜亚洲精品中文字幕一区| 久久久久久久综合日本| 一本高清dvd不卡在线观看| 日本三级韩国三级欧美三级| 国产欧美日韩三区| 欧美一区二区黄| 99精品视频在线播放观看| 男男gaygay亚洲| 亚洲情趣在线观看| 久久亚洲一区二区三区四区| 日本高清成人免费播放| 国产激情一区二区三区四区 | 在线观看视频一区二区| 国模娜娜一区二区三区| 亚洲.国产.中文慕字在线| www国产精品av| 欧美手机在线视频| 不卡一区二区三区四区| 美女视频免费一区| 午夜影院久久久| 中文字幕一区二区三区在线不卡 | 久久久精品tv| 欧美一区二区三区日韩视频| 色悠悠久久综合| 丰满放荡岳乱妇91ww| 久久狠狠亚洲综合| 视频一区二区中文字幕| 亚洲精品国产一区二区精华液| 久久久精品2019中文字幕之3| 欧美一级日韩不卡播放免费| 在线观看一区二区视频| 色综合色综合色综合| 国产91色综合久久免费分享| 韩国一区二区视频| 麻豆一区二区三| 日本成人在线视频网站| 性做久久久久久免费观看| 亚洲国产精品精华液网站| 一区二区三区免费在线观看| 亚洲天堂中文字幕| 亚洲四区在线观看| 成人免费在线观看入口| 中文字幕中文字幕一区| 国产精品三级视频| 国产精品久久毛片a| 国产精品人人做人人爽人人添| 久久九九久久九九| 久久综合久色欧美综合狠狠| 日韩女优电影在线观看| 欧美成人在线直播| 精品国产一区二区国模嫣然| 精品电影一区二区| 国产日韩在线不卡| 国产精品网站在线| 亚洲精品一二三区| 亚洲国产精品久久久男人的天堂| 亚洲成av人片在线观看无码| 日韩中文字幕91| 精品一区二区av| 成人av在线资源网站| 不卡的av网站| 91久久线看在观草草青青| 欧美在线一区二区三区| 51久久夜色精品国产麻豆| 日韩视频一区在线观看| 欧美精品一区二区在线观看| 国产欧美一二三区| 亚洲欧洲综合另类在线| 五月天视频一区| 国产东北露脸精品视频| 91免费版pro下载短视频| 欧美三级一区二区| 欧美tickling挠脚心丨vk| 国产日韩欧美高清| 亚洲精品成a人| 免费不卡在线视频| 成人黄色片在线观看| 欧美军同video69gay| 久久免费视频色| 亚洲视频综合在线| 欧美aⅴ一区二区三区视频| 国产精品影视在线| 欧美午夜精品一区| 久久久久久久久久久电影| 一区二区三区四区视频精品免费| 日韩高清中文字幕一区| 成人激情免费视频| 在线91免费看| 国产精品国产三级国产aⅴ入口| 午夜免费欧美电影| 99精品欧美一区二区三区综合在线| 欧美巨大另类极品videosbest | 日韩一区二区免费高清| 中文字幕av不卡| 青青草国产精品97视觉盛宴 | 国产精品妹子av| 日本美女一区二区三区| 色综合天天做天天爱| 久久综合狠狠综合| 天天免费综合色| 色婷婷久久综合| 久久久三级国产网站| 偷拍自拍另类欧美| 97se亚洲国产综合在线| 26uuu精品一区二区在线观看| 亚洲一区二区三区四区在线免费观看| 国产精品一色哟哟哟| 欧美一区二区三区四区视频| 亚洲男女毛片无遮挡| 国产盗摄视频一区二区三区| 欧美一级黄色片| 亚欧色一区w666天堂| 日本精品视频一区二区| 国产欧美精品在线观看| 国产精品18久久久久久久久| 欧美www视频| 强制捆绑调教一区二区| 欧美人妇做爰xxxⅹ性高电影| 亚洲欧美偷拍三级| 不卡高清视频专区| 欧美韩国日本不卡| 国产精品1024| 久久午夜国产精品| 国产一区二区福利| 久久亚洲免费视频| 国产精品一区二区无线| 久久嫩草精品久久久精品|