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

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

?? vhd-util-resize.c

?? xen source 推出最新的VHD操作工具VHD-UTIL 實現源碼,超強
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* Copyright (c) 2008, XenSource Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of XenSource Inc. nor the names of its contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <inttypes.h>
#include <sys/mman.h>

#include "libvhd-journal.h"

#if 1
#define DFPRINTF(_f, _a...) fprintf(stdout, _f, ##_a)
#else
#define DFPRINTF(_f, _a...) ((void)0)
#endif

#define EPRINTF(_f, _a...)					\
	do {							\
		syslog(LOG_INFO, "%s: " _f, __func__, ##_a);	\
		DFPRINTF(_f, _a);				\
	} while (0)

typedef struct vhd_block {
	uint32_t block;
	uint32_t offset;
} vhd_block_t;

TEST_FAIL_EXTERN_VARS;

static inline uint32_t
secs_to_blocks_down(vhd_context_t *vhd, uint64_t secs)
{
	return secs / vhd->spb;
}

static uint32_t
secs_to_blocks_up(vhd_context_t *vhd, uint64_t secs)
{
	uint32_t blocks;

	blocks = secs / vhd->spb;
	if (secs % vhd->spb)
		blocks++;

	return blocks;
}

static int
vhd_fixed_shrink(vhd_journal_t *journal, uint64_t secs)
{
	int err;
	uint64_t new_eof;
	vhd_context_t *vhd;

	vhd = &journal->vhd;

	new_eof = vhd->footer.curr_size - vhd_sectors_to_bytes(secs);
	if (new_eof <= sizeof(vhd_footer_t))
		return -EINVAL;

	err = ftruncate(vhd->fd, new_eof);
	if (err)
		return errno;

	vhd->footer.curr_size = new_eof;
	return vhd_write_footer(vhd, &vhd->footer);
}

static int
vhd_write_zeros(vhd_journal_t *journal, off64_t off, uint64_t size)
{
	int err;
	char *buf;
	vhd_context_t *vhd;
	uint64_t bytes, map;

	vhd = &journal->vhd;
	map = MIN(size, VHD_BLOCK_SIZE);

	err = vhd_seek(vhd, off, SEEK_SET);
	if (err)
		return err;

	buf = mmap(0, map, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	if (buf == MAP_FAILED)
		return -errno;

	do {
		bytes = MIN(size, map);

		err = vhd_write(vhd, buf, bytes);
		if (err)
			break;

		size -= bytes;
	} while (size);

	munmap(buf, map);

	return err;
}

static int
vhd_fixed_grow(vhd_journal_t *journal, uint64_t secs)
{
	int err;
	vhd_context_t *vhd;
	uint64_t size, eof, new_eof;

	size = vhd_sectors_to_bytes(secs);
	vhd  = &journal->vhd;

	err = vhd_seek(vhd, 0, SEEK_END);
	if (err)
		goto out;

	eof = vhd_position(vhd);
	if (eof == (off64_t)-1) {
		err = -errno;
		goto out;
	}

	err = vhd_write_zeros(journal, eof - sizeof(vhd_footer_t), size);
	if (err)
		goto out;

	new_eof = eof + size;
	err = vhd_seek(vhd, new_eof, SEEK_SET);
	if (err)
		goto out;

	vhd->footer.curr_size += size;
	err = vhd_write_footer(vhd, &vhd->footer);
	if (err)
		goto out;

	err = 0;

out:
	return err;
}

static int
vhd_fixed_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;
	else if (cur_secs > new_secs)
		err = vhd_fixed_shrink(journal, cur_secs - new_secs);
	else
		err = vhd_fixed_grow(journal, new_secs - cur_secs);

	return err;
}

static inline void
swap(vhd_block_t *list, int a, int b)
{
	vhd_block_t tmp;

	tmp     = list[a];
	list[a] = list[b];
	list[b] = tmp;
}

static int
partition(vhd_block_t *list, int left, int right, int pidx)
{
	int i, sidx;
	long long pval;

	sidx = left;
	pval = list[pidx].offset;
	swap(list, pidx, right);

	for (i = left; i < right; i++)
		if (list[i].offset >= pval) {
			swap(list, sidx, i);
			++sidx;
		}

	swap(list, right, sidx);
	return sidx;
}

static void
quicksort(vhd_block_t *list, int left, int right)
{
	int pidx, new_pidx;

	if (right < left)
		return;

	pidx     = left;
	new_pidx = partition(list, left, right, pidx);
	quicksort(list, left, new_pidx - 1);
	quicksort(list, new_pidx + 1, right);
}

static int
vhd_move_block(vhd_journal_t *journal, uint32_t src, off64_t offset)
{
	int err;
	char *buf;
	size_t size;
	vhd_context_t *vhd;
	off64_t off, src_off;

	buf     = NULL;
	vhd     = &journal->vhd;
	off     = offset;
	size    = vhd_sectors_to_bytes(vhd->bm_secs);
	src_off = vhd->bat.bat[src];

	if (src_off == DD_BLK_UNUSED)
		return -EINVAL;
	src_off = vhd_sectors_to_bytes(src_off);

	err  = vhd_journal_add_block(journal, src,
				     VHD_JOURNAL_DATA | VHD_JOURNAL_METADATA);
	if (err)
		goto out;

	err  = vhd_read_bitmap(vhd, src, &buf);
	if (err)
		goto out;

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

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

	free(buf);
	buf   = NULL;
	off  += size;
	size  = vhd_sectors_to_bytes(vhd->spb);

	err  = vhd_read_block(vhd, src, &buf);
	if (err)
		goto out;

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

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

	vhd->bat.bat[src] = offset >> VHD_SECTOR_SHIFT;

	err = vhd_write_zeros(journal, src_off,
			      vhd_sectors_to_bytes(vhd->bm_secs + vhd->spb));

out:
	free(buf);
	return err;
}

static int
vhd_clobber_block(vhd_journal_t *journal, uint32_t src, uint32_t dest)
{
	int err;
	off64_t off;
	vhd_context_t *vhd;

	vhd = &journal->vhd;
	off = vhd_sectors_to_bytes(vhd->bat.bat[dest]);

	err = vhd_journal_add_block(journal, dest,
				    VHD_JOURNAL_DATA | VHD_JOURNAL_METADATA);
	if (err)
		return err;

	err = vhd_move_block(journal, src, off);
	if (err)
		return err;

	vhd->bat.bat[dest] = DD_BLK_UNUSED;

	return 0;
}

/*
 * remove a list of blocks from the vhd file
 * if a block to be removed:
 *   - resides at the end of the file: simply clear its bat entry
 *   - resides elsewhere: move the last block in the file into its position
 *                        and update the bat to reflect this
 */
static int
vhd_defrag_shrink(vhd_journal_t *journal,
		  vhd_block_t *original_free_list, int free_cnt)
{
	vhd_context_t *vhd;
	int i, j, free_idx, err;
	vhd_block_t *blocks, *free_list;

	err       = 0;
	blocks    = NULL;
	free_list = NULL;
	vhd       = &journal->vhd;

	blocks = malloc(vhd->bat.entries * sizeof(vhd_block_t));
	if (!blocks) {
		err = -ENOMEM;
		goto out;
	}

	free_list = malloc(free_cnt * sizeof(vhd_block_t));
	if (!free_list) {
		err = -ENOMEM;
		goto out;
	}

	for (i = 0; i < vhd->bat.entries; i++) {
		blocks[i].block  = i;
		blocks[i].offset = vhd->bat.bat[i];
	}

	memcpy(free_list, original_free_list,
	       free_cnt * sizeof(vhd_block_t));

	/* sort both the to-free list and the bat list
	 * in order of descending file offset */
	quicksort(free_list, 0, free_cnt - 1);
	quicksort(blocks, 0, vhd->bat.entries - 1);

	for (i = 0, free_idx = 0;
	     i < vhd->bat.entries && free_idx < free_cnt; i++) {
		vhd_block_t *b = blocks + i;

		if (b->offset == DD_BLK_UNUSED)
			continue;

		for (j = free_idx; j < free_cnt; j++)
			if (b->block == free_list[j].block) {
				/* the last block in the file is in the list of
				 * blocks to remove; no need to shuffle the
				 * data -- just clear the bat entry */
				vhd->bat.bat[free_list[j].block] = DD_BLK_UNUSED;
				free_idx++;
				continue;
			}

		err = vhd_clobber_block(journal, b->block,
					free_list[free_idx++].block);
		if (err)
			goto out;
	}

	/* clear any bat entries for blocks we did not shuffle */
	for (i = free_idx; i < free_cnt; i++)
		vhd->bat.bat[free_list[i].block] = DD_BLK_UNUSED;

out:
	free(blocks);
	free(free_list);

	return err;
}

static int
vhd_clear_bat_entries(vhd_journal_t *journal, uint32_t entries)
{
	int i, err;
	vhd_context_t *vhd;
	off64_t orig_map_off, new_map_off;
	uint32_t orig_entries, new_entries;

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

	if (vhd_has_batmap(vhd)) {
		err = vhd_batmap_header_offset(vhd, &orig_map_off);
		if (err)
			return err;
	}

	/* 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);
	err = vhd_write_footer(vhd, &vhd->footer);
	if (err)
		return err;

	/* update bat -- we don't reclaim space, just clear entries */
	for (i = new_entries; i < orig_entries; i++)
		vhd->bat.bat[i] = 0;

	err = vhd_write_bat(vhd, &vhd->bat);
	if (err)
		return err;

	/* update this after write_bat so the end of the bat is zeored */
	vhd->bat.entries = new_entries;

	if (!vhd_has_batmap(vhd))
		return 0;

	/* zero out old batmap header if new header has moved */
	err = vhd_batmap_header_offset(vhd, &new_map_off);
	if (err)
		return err;

	if (orig_map_off != new_map_off) {
		size_t size;

		size = vhd_bytes_padded(sizeof(struct dd_batmap_hdr));

		err = vhd_write_zeros(journal, orig_map_off, size);
		if (err)
			return err;
	}

	/* update batmap -- clear entries for freed blocks */
	for (i = new_entries; i < orig_entries; i++)
		vhd_batmap_clear(vhd, &vhd->batmap, i);

	err = vhd_write_batmap(vhd, &vhd->batmap);
	if (err)
		return err;

	return 0;
}

static int
vhd_dynamic_shrink(vhd_journal_t *journal, uint64_t secs)
{
	off64_t eof;
	uint32_t blocks;
	vhd_context_t *vhd;
	int i, j, err, free_cnt;
	struct vhd_block *free_list;

	printf("dynamic shrink not fully implemented\n");
	return -ENOSYS;

	eof       = 0;
	free_cnt  = 0;
	free_list = NULL;
	vhd       = &journal->vhd;

	blocks    = secs_to_blocks_down(vhd, secs);
	if (blocks == 0)
		return 0;

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

	free_list = malloc(blocks * sizeof(struct vhd_block));
	if (!free_list)
		return -ENOMEM;

	for (i = vhd->bat.entries - 1, j = 0; i >= 0 && j < blocks; i--, j++) {
		uint32_t blk = vhd->bat.bat[i];

		if (blk != DD_BLK_UNUSED) {
			free_list[free_cnt].block  = i;
			free_list[free_cnt].offset = blk;
			free_cnt++;
		}
	}

	if (free_cnt) {
		err = vhd_defrag_shrink(journal, free_list, free_cnt);
		if (err)
			goto out;
	}

	err = vhd_clear_bat_entries(journal, blocks);
	if (err)
		goto out;

	/* remove data beyond footer */
	err = vhd_end_of_data(vhd, &eof);
	if (err)
		goto out;

	err = ftruncate(vhd->fd, eof + sizeof(vhd_footer_t));
	if (err) {
		err = -errno;
		goto out;
	}

	err = 0;

out:
	free(free_list);
	return err;
}

static inline void
vhd_first_data_block(vhd_context_t *vhd, vhd_block_t *block)
{
	int i;
	uint32_t blk;

	memset(block, 0, sizeof(vhd_block_t));

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

		if (blk != DD_BLK_UNUSED) {
			if (!block->offset || blk < block->offset) {
				block->block  = i;
				block->offset = blk;
			}
		}
	}
}

static inline uint32_t
vhd_next_block_offset(vhd_context_t *vhd)
{
	int i;
	uint32_t blk, end, spp, next;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
中文字幕第一区二区| 欧美国产综合色视频| 91在线观看一区二区| 国产九色精品成人porny| 卡一卡二国产精品| 国产一区二区三区四区五区美女 | 国产精品亚洲专一区二区三区| 日韩国产一区二| 免费日本视频一区| 日韩av在线发布| 精品亚洲porn| 成人福利视频网站| 色综合婷婷久久| 91精品福利视频| 在线成人av影院| 欧美电影免费观看完整版| 久久影视一区二区| 中文字幕亚洲区| 亚洲午夜精品久久久久久久久| 一区二区不卡在线播放| 婷婷夜色潮精品综合在线| 美腿丝袜在线亚洲一区 | 一区二区三区在线免费视频| 一区二区三区国产豹纹内裤在线| 亚洲成人你懂的| 国产在线精品一区在线观看麻豆| 成人97人人超碰人人99| 91福利精品视频| 日韩欧美卡一卡二| 国产精品女同一区二区三区| 一区二区三区免费看视频| 免费人成网站在线观看欧美高清| 国产成人免费网站| 7777女厕盗摄久久久| 国产偷国产偷精品高清尤物| 亚洲午夜免费福利视频| 国产最新精品精品你懂的| 日本道在线观看一区二区| 欧美成人激情免费网| 一区二区欧美视频| 国产精品91xxx| 欧美丰满高潮xxxx喷水动漫| 国产午夜精品一区二区三区视频 | 国内精品视频666| a在线播放不卡| 精品国产露脸精彩对白| 一区2区3区在线看| 国产成人精品免费在线| 日韩欧美国产wwwww| 悠悠色在线精品| 成人美女视频在线观看18| 欧美一区二区在线视频| 亚洲精品乱码久久久久久日本蜜臀 | 日韩欧美一级片| 一区二区三区 在线观看视频| 国产高清成人在线| 2020国产精品久久精品美国| 一区二区三区免费在线观看| 成人高清视频在线| 久久久99精品免费观看| 蜜臀av一级做a爰片久久| 欧美日韩国产精品成人| 亚洲同性同志一二三专区| 国产99久久久久久免费看农村| 日韩欧美专区在线| 天天免费综合色| 欧美三级电影网站| 亚洲一区二区三区中文字幕 | 欧美日韩你懂的| 亚洲乱码国产乱码精品精小说| 成人av高清在线| 国产亚洲成av人在线观看导航| 国产精品自拍网站| 久久久久久久久久久久电影 | 蜜桃视频在线一区| 制服.丝袜.亚洲.中文.综合| 五月婷婷欧美视频| 欧美日韩1234| 日本不卡一区二区| 欧美一级专区免费大片| 精品制服美女丁香| 久久久国产一区二区三区四区小说| 国产乱子伦视频一区二区三区| 久久婷婷综合激情| 成人av在线电影| 亚洲精品乱码久久久久久| 欧洲一区二区av| 日本欧美一区二区| 亚洲精品一区二区三区福利| 国产精品一区不卡| 曰韩精品一区二区| 欧美日韩免费观看一区二区三区| 午夜欧美视频在线观看| 日韩欧美精品在线视频| 国产成人一区在线| 亚洲精品老司机| 日韩视频在线永久播放| 成人午夜激情在线| 亚洲一区二区三区免费视频| 日韩一区二区三区四区| 波多野结衣视频一区| 亚洲午夜激情av| 久久色.com| 色老汉av一区二区三区| 久久综合综合久久综合| 日韩美女啊v在线免费观看| 欧美老年两性高潮| 国产精品一级在线| 一区二区三区高清| 精品精品欲导航| 色综合一个色综合亚洲| 久久国产精品色| 一区二区三区国产| 日本一区二区成人在线| 欧美日韩性生活| caoporn国产一区二区| 麻豆一区二区三| 亚洲精品成人精品456| 精品国产网站在线观看| 91官网在线观看| 国产盗摄一区二区| 日韩不卡在线观看日韩不卡视频| 国产欧美精品区一区二区三区 | 中文子幕无线码一区tr| 欧美顶级少妇做爰| 91一区二区在线观看| 国产美女视频一区| 日韩中文字幕区一区有砖一区| 中文字幕+乱码+中文字幕一区| 欧美一区二区视频免费观看| 在线看国产一区二区| 成人av免费在线播放| 国产一二三精品| 久久99精品网久久| 热久久久久久久| 午夜一区二区三区在线观看| 国产精品少妇自拍| 久久看人人爽人人| 26uuu色噜噜精品一区| 日韩一区二区中文字幕| 欧美高清视频一二三区| 欧美日韩专区在线| 欧美三级午夜理伦三级中视频| 99久久婷婷国产| av毛片久久久久**hd| 成人动漫一区二区在线| 成人黄色免费短视频| 国产成人久久精品77777最新版本| 麻豆精品一区二区综合av| 日本不卡不码高清免费观看| 午夜影院在线观看欧美| 午夜av区久久| 日韩国产在线观看一区| 日韩精品一区第一页| 日韩和欧美一区二区三区| 亚洲一区二区三区四区五区中文| 亚洲一区二区三区四区中文字幕 | 麻豆精品国产传媒mv男同| 日日摸夜夜添夜夜添精品视频 | 国产视频911| 中文字幕成人av| 亚洲三级在线免费| 亚洲综合色在线| 亚洲一级在线观看| 日本欧美在线观看| 国产一区二区在线电影| www.欧美.com| 欧美视频在线观看一区二区| 91麻豆精品国产91久久久| 精品久久久久香蕉网| 国产精品免费观看视频| 有码一区二区三区| 麻豆成人综合网| 成人综合在线网站| 欧美在线不卡视频| 日韩欧美亚洲国产精品字幕久久久| 2020国产精品自拍| 亚洲欧美日韩国产中文在线| 亚洲高清免费一级二级三级| 美女一区二区三区| 99国产精品久久久| 欧美一级搡bbbb搡bbbb| 欧美激情在线观看视频免费| 亚洲国产另类av| 国产成人一级电影| 欧美二区三区91| 亚洲国产精品成人综合| 五月天精品一区二区三区| 国产大陆亚洲精品国产| 欧美自拍偷拍一区| 精品国产免费一区二区三区四区| 亚洲欧洲国产日本综合| 奇米影视一区二区三区| 成人激情电影免费在线观看| 欧美久久高跟鞋激| 亚洲免费在线看| 国产精品亚洲专一区二区三区 | 亚洲国产成人av网| 国产不卡免费视频| 欧美精品一卡二卡|