mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Fri May 22 10:00:53 2015 BST using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" * remotes/stefanha/tags/block-pull-request: (38 commits) block: get_block_status: use "else" when testing the opposite condition qemu-iotests: Test unaligned sub-block zero write block: Fix NULL deference for unaligned write if qiov is NULL Revert "block: Fix unaligned zero write" block: align bounce buffers to page block: minimal bounce buffer alignment block: return EPERM on writes or discards to read-only devices configure: Add workaround for ccache and clang configure: silence glib unknown attribute __alloc_size__ configure: factor out supported flag check configure: handle clang -nopie argument warning block/parallels: improve image writing performance further block/parallels: optimize linear image expansion block/parallels: add prealloc-mode and prealloc-size open paramemets block/parallels: delay writing to BAT till bdrv_co_flush_to_os block/parallels: create bat_entry_off helper block/parallels: improve image reading performance iotests, parallels: check for incorrectly closed image in tests block/parallels: implement incorrect close detection block/parallels: implement parallels_check method of block driver ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -106,13 +106,23 @@ int is_windows_drive(const char *filename)
|
||||
size_t bdrv_opt_mem_align(BlockDriverState *bs)
|
||||
{
|
||||
if (!bs || !bs->drv) {
|
||||
/* 4k should be on the safe side */
|
||||
return 4096;
|
||||
/* page size or 4k (hdd sector size) should be on the safe side */
|
||||
return MAX(4096, getpagesize());
|
||||
}
|
||||
|
||||
return bs->bl.opt_mem_alignment;
|
||||
}
|
||||
|
||||
size_t bdrv_min_mem_align(BlockDriverState *bs)
|
||||
{
|
||||
if (!bs || !bs->drv) {
|
||||
/* page size or 4k (hdd sector size) should be on the safe side */
|
||||
return MAX(4096, getpagesize());
|
||||
}
|
||||
|
||||
return bs->bl.min_mem_alignment;
|
||||
}
|
||||
|
||||
/* check if the path starts with "<protocol>:" */
|
||||
int path_has_protocol(const char *path)
|
||||
{
|
||||
@@ -890,6 +900,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
|
||||
}
|
||||
|
||||
assert(bdrv_opt_mem_align(bs) != 0);
|
||||
assert(bdrv_min_mem_align(bs) != 0);
|
||||
assert((bs->request_alignment != 0) || bs->sg);
|
||||
return 0;
|
||||
|
||||
|
||||
+111
-48
@@ -201,9 +201,11 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
}
|
||||
bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
|
||||
bs->bl.max_transfer_length = bs->file->bl.max_transfer_length;
|
||||
bs->bl.min_mem_alignment = bs->file->bl.min_mem_alignment;
|
||||
bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
|
||||
} else {
|
||||
bs->bl.opt_mem_alignment = 512;
|
||||
bs->bl.min_mem_alignment = 512;
|
||||
bs->bl.opt_mem_alignment = getpagesize();
|
||||
}
|
||||
|
||||
if (bs->backing_hd) {
|
||||
@@ -221,6 +223,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
bs->bl.opt_mem_alignment =
|
||||
MAX(bs->bl.opt_mem_alignment,
|
||||
bs->backing_hd->bl.opt_mem_alignment);
|
||||
bs->bl.min_mem_alignment =
|
||||
MAX(bs->bl.min_mem_alignment,
|
||||
bs->backing_hd->bl.min_mem_alignment);
|
||||
}
|
||||
|
||||
/* Then let the driver override it */
|
||||
@@ -929,19 +934,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint64_t bdrv_get_align(BlockDriverState *bs)
|
||||
{
|
||||
/* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
|
||||
return MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
|
||||
}
|
||||
|
||||
static inline bool bdrv_req_is_aligned(BlockDriverState *bs,
|
||||
int64_t offset, size_t bytes)
|
||||
{
|
||||
int64_t align = bdrv_get_align(bs);
|
||||
return !(offset & (align - 1) || (bytes & (align - 1)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a read request in coroutine context
|
||||
*/
|
||||
@@ -952,7 +944,8 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
|
||||
BlockDriver *drv = bs->drv;
|
||||
BdrvTrackedRequest req;
|
||||
|
||||
uint64_t align = bdrv_get_align(bs);
|
||||
/* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
|
||||
uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
|
||||
uint8_t *head_buf = NULL;
|
||||
uint8_t *tail_buf = NULL;
|
||||
QEMUIOVector local_qiov;
|
||||
@@ -1186,6 +1179,94 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
|
||||
int64_t offset,
|
||||
unsigned int bytes,
|
||||
BdrvRequestFlags flags,
|
||||
BdrvTrackedRequest *req)
|
||||
{
|
||||
uint8_t *buf = NULL;
|
||||
QEMUIOVector local_qiov;
|
||||
struct iovec iov;
|
||||
uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
|
||||
unsigned int head_padding_bytes, tail_padding_bytes;
|
||||
int ret = 0;
|
||||
|
||||
head_padding_bytes = offset & (align - 1);
|
||||
tail_padding_bytes = align - ((offset + bytes) & (align - 1));
|
||||
|
||||
|
||||
assert(flags & BDRV_REQ_ZERO_WRITE);
|
||||
if (head_padding_bytes || tail_padding_bytes) {
|
||||
buf = qemu_blockalign(bs, align);
|
||||
iov = (struct iovec) {
|
||||
.iov_base = buf,
|
||||
.iov_len = align,
|
||||
};
|
||||
qemu_iovec_init_external(&local_qiov, &iov, 1);
|
||||
}
|
||||
if (head_padding_bytes) {
|
||||
uint64_t zero_bytes = MIN(bytes, align - head_padding_bytes);
|
||||
|
||||
/* RMW the unaligned part before head. */
|
||||
mark_request_serialising(req, align);
|
||||
wait_serialising_requests(req);
|
||||
BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_HEAD);
|
||||
ret = bdrv_aligned_preadv(bs, req, offset & ~(align - 1), align,
|
||||
align, &local_qiov, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
|
||||
|
||||
memset(buf + head_padding_bytes, 0, zero_bytes);
|
||||
ret = bdrv_aligned_pwritev(bs, req, offset & ~(align - 1), align,
|
||||
&local_qiov,
|
||||
flags & ~BDRV_REQ_ZERO_WRITE);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
offset += zero_bytes;
|
||||
bytes -= zero_bytes;
|
||||
}
|
||||
|
||||
assert(!bytes || (offset & (align - 1)) == 0);
|
||||
if (bytes >= align) {
|
||||
/* Write the aligned part in the middle. */
|
||||
uint64_t aligned_bytes = bytes & ~(align - 1);
|
||||
ret = bdrv_aligned_pwritev(bs, req, offset, aligned_bytes,
|
||||
NULL, flags);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
bytes -= aligned_bytes;
|
||||
offset += aligned_bytes;
|
||||
}
|
||||
|
||||
assert(!bytes || (offset & (align - 1)) == 0);
|
||||
if (bytes) {
|
||||
assert(align == tail_padding_bytes + bytes);
|
||||
/* RMW the unaligned part after tail. */
|
||||
mark_request_serialising(req, align);
|
||||
wait_serialising_requests(req);
|
||||
BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_TAIL);
|
||||
ret = bdrv_aligned_preadv(bs, req, offset, align,
|
||||
align, &local_qiov, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
|
||||
|
||||
memset(buf, 0, bytes);
|
||||
ret = bdrv_aligned_pwritev(bs, req, offset, align,
|
||||
&local_qiov, flags & ~BDRV_REQ_ZERO_WRITE);
|
||||
}
|
||||
fail:
|
||||
qemu_vfree(buf);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a write request in coroutine context
|
||||
*/
|
||||
@@ -1194,7 +1275,8 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
|
||||
BdrvRequestFlags flags)
|
||||
{
|
||||
BdrvTrackedRequest req;
|
||||
uint64_t align = bdrv_get_align(bs);
|
||||
/* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
|
||||
uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
|
||||
uint8_t *head_buf = NULL;
|
||||
uint8_t *tail_buf = NULL;
|
||||
QEMUIOVector local_qiov;
|
||||
@@ -1205,7 +1287,7 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
if (bs->read_only) {
|
||||
return -EACCES;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ret = bdrv_check_byte_request(bs, offset, bytes);
|
||||
@@ -1225,6 +1307,11 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
|
||||
*/
|
||||
tracked_request_begin(&req, bs, offset, bytes, true);
|
||||
|
||||
if (!qiov) {
|
||||
ret = bdrv_co_do_zero_pwritev(bs, offset, bytes, flags, &req);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (offset & (align - 1)) {
|
||||
QEMUIOVector head_qiov;
|
||||
struct iovec head_iov;
|
||||
@@ -1293,23 +1380,19 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
|
||||
bytes = ROUND_UP(bytes, align);
|
||||
}
|
||||
|
||||
if (use_local_qiov) {
|
||||
/* Local buffer may have non-zero data. */
|
||||
flags &= ~BDRV_REQ_ZERO_WRITE;
|
||||
}
|
||||
ret = bdrv_aligned_pwritev(bs, &req, offset, bytes,
|
||||
use_local_qiov ? &local_qiov : qiov,
|
||||
flags);
|
||||
|
||||
fail:
|
||||
tracked_request_end(&req);
|
||||
|
||||
if (use_local_qiov) {
|
||||
qemu_iovec_destroy(&local_qiov);
|
||||
}
|
||||
qemu_vfree(head_buf);
|
||||
qemu_vfree(tail_buf);
|
||||
|
||||
out:
|
||||
tracked_request_end(&req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1337,32 +1420,14 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs,
|
||||
int64_t sector_num, int nb_sectors,
|
||||
BdrvRequestFlags flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags);
|
||||
|
||||
if (!(bs->open_flags & BDRV_O_UNMAP)) {
|
||||
flags &= ~BDRV_REQ_MAY_UNMAP;
|
||||
}
|
||||
if (bdrv_req_is_aligned(bs, sector_num << BDRV_SECTOR_BITS,
|
||||
nb_sectors << BDRV_SECTOR_BITS)) {
|
||||
ret = bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
|
||||
BDRV_REQ_ZERO_WRITE | flags);
|
||||
} else {
|
||||
uint8_t *buf;
|
||||
QEMUIOVector local_qiov;
|
||||
size_t bytes = nb_sectors << BDRV_SECTOR_BITS;
|
||||
|
||||
buf = qemu_memalign(bdrv_opt_mem_align(bs), bytes);
|
||||
memset(buf, 0, bytes);
|
||||
qemu_iovec_init(&local_qiov, 1);
|
||||
qemu_iovec_add(&local_qiov, buf, bytes);
|
||||
|
||||
ret = bdrv_co_do_writev(bs, sector_num, nb_sectors, &local_qiov,
|
||||
BDRV_REQ_ZERO_WRITE | flags);
|
||||
qemu_vfree(buf);
|
||||
}
|
||||
return ret;
|
||||
return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
|
||||
BDRV_REQ_ZERO_WRITE | flags);
|
||||
}
|
||||
|
||||
int bdrv_flush_all(void)
|
||||
@@ -1456,9 +1521,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
|
||||
|
||||
if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
|
||||
ret |= BDRV_BLOCK_ALLOCATED;
|
||||
}
|
||||
|
||||
if (!(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO)) {
|
||||
} else {
|
||||
if (bdrv_unallocated_blocks_are_zero(bs)) {
|
||||
ret |= BDRV_BLOCK_ZERO;
|
||||
} else if (bs->backing_hd) {
|
||||
@@ -2340,7 +2403,7 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
} else if (bs->read_only) {
|
||||
return -EROFS;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
bdrv_reset_dirty(bs, sector_num, nb_sectors);
|
||||
@@ -2489,7 +2552,7 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
|
||||
bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
|
||||
{
|
||||
int i;
|
||||
size_t alignment = bdrv_opt_mem_align(bs);
|
||||
size_t alignment = bdrv_min_mem_align(bs);
|
||||
|
||||
for (i = 0; i < qiov->niov; i++) {
|
||||
if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
|
||||
|
||||
+617
-72
File diff suppressed because it is too large
Load Diff
+8
-6
@@ -301,6 +301,7 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
char *buf;
|
||||
size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
|
||||
|
||||
/* For /dev/sg devices the alignment is not really used.
|
||||
With buffered I/O, we don't have any restrictions. */
|
||||
@@ -330,9 +331,9 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
|
||||
/* If we could not get the sizes so far, we can only guess them */
|
||||
if (!s->buf_align) {
|
||||
size_t align;
|
||||
buf = qemu_memalign(MAX_BLOCKSIZE, 2 * MAX_BLOCKSIZE);
|
||||
for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) {
|
||||
if (raw_is_io_aligned(fd, buf + align, MAX_BLOCKSIZE)) {
|
||||
buf = qemu_memalign(max_align, 2 * max_align);
|
||||
for (align = 512; align <= max_align; align <<= 1) {
|
||||
if (raw_is_io_aligned(fd, buf + align, max_align)) {
|
||||
s->buf_align = align;
|
||||
break;
|
||||
}
|
||||
@@ -342,8 +343,8 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
|
||||
|
||||
if (!bs->request_alignment) {
|
||||
size_t align;
|
||||
buf = qemu_memalign(s->buf_align, MAX_BLOCKSIZE);
|
||||
for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) {
|
||||
buf = qemu_memalign(s->buf_align, max_align);
|
||||
for (align = 512; align <= max_align; align <<= 1) {
|
||||
if (raw_is_io_aligned(fd, buf, align)) {
|
||||
bs->request_alignment = align;
|
||||
break;
|
||||
@@ -725,7 +726,8 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
raw_probe_alignment(bs, s->fd, errp);
|
||||
bs->bl.opt_mem_alignment = s->buf_align;
|
||||
bs->bl.min_mem_alignment = s->buf_align;
|
||||
bs->bl.opt_mem_alignment = MAX(s->buf_align, getpagesize());
|
||||
}
|
||||
|
||||
static int check_for_dasd(int fd)
|
||||
|
||||
@@ -103,7 +103,8 @@ update_cxxflags() {
|
||||
}
|
||||
|
||||
compile_object() {
|
||||
do_cc $QEMU_CFLAGS -c -o $TMPO $TMPC
|
||||
local_cflags="$1"
|
||||
do_cc $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
|
||||
}
|
||||
|
||||
compile_prog() {
|
||||
@@ -436,6 +437,12 @@ EOF
|
||||
compile_object
|
||||
}
|
||||
|
||||
write_c_skeleton() {
|
||||
cat > $TMPC <<EOF
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
}
|
||||
|
||||
if check_define __linux__ ; then
|
||||
targetos="Linux"
|
||||
elif check_define _WIN32 ; then
|
||||
@@ -705,9 +712,7 @@ if test "$mingw32" = "yes" ; then
|
||||
# enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later)
|
||||
QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS"
|
||||
LIBS="-lwinmm -lws2_32 -liphlpapi $LIBS"
|
||||
cat > $TMPC << EOF
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
write_c_skeleton;
|
||||
if compile_prog "" "-liberty" ; then
|
||||
LIBS="-liberty $LIBS"
|
||||
fi
|
||||
@@ -1445,10 +1450,7 @@ if test -z "$werror" ; then
|
||||
fi
|
||||
|
||||
# check that the C compiler works.
|
||||
cat > $TMPC <<EOF
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
|
||||
write_c_skeleton;
|
||||
if compile_object ; then
|
||||
: C compiler works ok
|
||||
else
|
||||
@@ -1496,16 +1498,20 @@ gcc_flags="-Wno-string-plus-int $gcc_flags"
|
||||
# enable it for all configure tests. If a configure test failed due
|
||||
# to -Werror this would just silently disable some features,
|
||||
# so it's too error prone.
|
||||
cat > $TMPC << EOF
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
for flag in $gcc_flags; do
|
||||
|
||||
cc_has_warning_flag() {
|
||||
write_c_skeleton;
|
||||
|
||||
# Use the positive sense of the flag when testing for -Wno-wombat
|
||||
# support (gcc will happily accept the -Wno- form of unknown
|
||||
# warning options).
|
||||
optflag="$(echo $flag | sed -e 's/^-Wno-/-W/')"
|
||||
if compile_prog "-Werror $optflag" "" ; then
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
|
||||
optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
|
||||
compile_prog "-Werror $optflag" ""
|
||||
}
|
||||
|
||||
for flag in $gcc_flags; do
|
||||
if cc_has_warning_flag $flag ; then
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1607,7 +1613,7 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
if compile_prog "-fno-pie" "-nopie"; then
|
||||
if compile_prog "-Werror -fno-pie" "-nopie"; then
|
||||
CFLAGS_NOPIE="-fno-pie"
|
||||
LDFLAGS_NOPIE="-nopie"
|
||||
fi
|
||||
@@ -2802,6 +2808,18 @@ if ! $pkg_config --atleast-version=2.38 glib-2.0; then
|
||||
glib_subprocess=no
|
||||
fi
|
||||
|
||||
# Silence clang 3.5.0 warnings about glib attribute __alloc_size__ usage
|
||||
cat > $TMPC << EOF
|
||||
#include <glib.h>
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
|
||||
if cc_has_warning_flag "-Wno-unknown-attributes"; then
|
||||
glib_cflags="-Wno-unknown-attributes $glib_cflags"
|
||||
CFLAGS="-Wno-unknown-attributes $CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# SHA command probe for modules
|
||||
if test "$modules" = yes; then
|
||||
@@ -4192,6 +4210,33 @@ if compile_prog "" "" ; then
|
||||
getauxval=yes
|
||||
fi
|
||||
|
||||
########################################
|
||||
# check if ccache is interfering with
|
||||
# semantic analysis of macros
|
||||
|
||||
ccache_cpp2=no
|
||||
cat > $TMPC << EOF
|
||||
static const int Z = 1;
|
||||
#define fn() ({ Z; })
|
||||
#define TAUT(X) ((X) == Z)
|
||||
#define PAREN(X, Y) (X == Y)
|
||||
#define ID(X) (X)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
x = ID(x);
|
||||
x = fn();
|
||||
fn();
|
||||
if (PAREN(x, y)) return 0;
|
||||
if (TAUT(Z)) return 0;
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
if ! compile_object "-Werror"; then
|
||||
ccache_cpp2=yes
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# End of CC checks
|
||||
# After here, no more $cc or $ld runs
|
||||
@@ -5485,6 +5530,10 @@ if test "$numa" = "yes"; then
|
||||
echo "CONFIG_NUMA=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$ccache_cpp2" = "yes"; then
|
||||
echo "export CCACHE_CPP2=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
# build tree in object directory in case the source is not in the current directory
|
||||
DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
|
||||
DIRS="$DIRS fsdev"
|
||||
|
||||
@@ -440,6 +440,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
||||
|
||||
/* Returns the alignment in bytes that is required so that no bounce buffer
|
||||
* is required throughout the stack */
|
||||
size_t bdrv_min_mem_align(BlockDriverState *bs);
|
||||
/* Returns optimal alignment in bytes for bounce buffer */
|
||||
size_t bdrv_opt_mem_align(BlockDriverState *bs);
|
||||
void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
|
||||
void *qemu_blockalign(BlockDriverState *bs, size_t size);
|
||||
|
||||
@@ -313,6 +313,9 @@ typedef struct BlockLimits {
|
||||
int max_transfer_length;
|
||||
|
||||
/* memory alignment so that no bounce buffer is needed */
|
||||
size_t min_mem_alignment;
|
||||
|
||||
/* memory alignment for bounce buffer */
|
||||
size_t opt_mem_alignment;
|
||||
} BlockLimits;
|
||||
|
||||
|
||||
@@ -78,6 +78,19 @@ for align in 512 4k; do
|
||||
echo
|
||||
echo "== verifying patterns (2) =="
|
||||
do_test $align "read -P 0x0 0x400 0x20000" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "== rewriting unaligned zeroes =="
|
||||
do_test $align "write -P 0xb 0x0 0x1000" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "write -z 0x200 0x200" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "== verifying patterns (3) =="
|
||||
do_test $align "read -P 0xb 0x0 0x200" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "read -P 0x0 0x200 0x200" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "read -P 0xb 0x400 0xc00" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
done
|
||||
|
||||
# success, all done
|
||||
|
||||
@@ -27,6 +27,21 @@ wrote 65536/65536 bytes at offset 65536
|
||||
read 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== rewriting unaligned zeroes ==
|
||||
wrote 4096/4096 bytes at offset 0
|
||||
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (3) ==
|
||||
read 512/512 bytes at offset 0
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 3072/3072 bytes at offset 1024
|
||||
3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
|
||||
== preparing image ==
|
||||
wrote 1024/1024 bytes at offset 512
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
@@ -52,4 +67,19 @@ wrote 65536/65536 bytes at offset 65536
|
||||
== verifying patterns (2) ==
|
||||
read 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== rewriting unaligned zeroes ==
|
||||
wrote 4096/4096 bytes at offset 0
|
||||
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (3) ==
|
||||
read 512/512 bytes at offset 0
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 3072/3072 bytes at offset 1024
|
||||
3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
*** done
|
||||
|
||||
+10
-5
@@ -49,31 +49,36 @@ nb_sectors_offset=$((0x24))
|
||||
echo
|
||||
echo "== Read from a valid v1 image =="
|
||||
_use_sample_img parallels-v1.bz2
|
||||
{ $QEMU_IO -c "read -P 0x11 0 64k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo
|
||||
echo "== Negative catalog size =="
|
||||
_use_sample_img parallels-v1.bz2
|
||||
poke_file "$TEST_IMG" "$catalog_entries_offset" "\xff\xff\xff\xff"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo
|
||||
echo "== Overflow in catalog allocation =="
|
||||
_use_sample_img parallels-v1.bz2
|
||||
poke_file "$TEST_IMG" "$nb_sectors_offset" "\xff\xff\xff\xff"
|
||||
poke_file "$TEST_IMG" "$catalog_entries_offset" "\x01\x00\x00\x40"
|
||||
{ $QEMU_IO -c "read 64M 64M" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read 64M 64M" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo
|
||||
echo "== Zero sectors per track =="
|
||||
_use_sample_img parallels-v1.bz2
|
||||
poke_file "$TEST_IMG" "$tracks_offset" "\x00\x00\x00\x00"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo
|
||||
echo "== Read from a valid v2 image =="
|
||||
_use_sample_img parallels-v2.bz2
|
||||
{ $QEMU_IO -c "read -P 0x11 0 64k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "write -P 0x21 1024k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "write -P 0x22 1025k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read -P 0x21 1024k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read -P 0x22 1025k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
{ $QEMU_IO -c "read -P 0 1026k 62k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
|
||||
@@ -19,4 +19,14 @@ no file open, try 'help open'
|
||||
== Read from a valid v2 image ==
|
||||
read 65536/65536 bytes at offset 0
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 1024/1024 bytes at offset 1048576
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 1024/1024 bytes at offset 1049600
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 1024/1024 bytes at offset 1048576
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 1024/1024 bytes at offset 1049600
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 63488/63488 bytes at offset 1050624
|
||||
62 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
*** done
|
||||
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# parallels format validation tests (created by QEMU)
|
||||
#
|
||||
# Copyright (C) 2014 Denis V. Lunev <den@openvz.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=den@openvz.org
|
||||
|
||||
seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
_supported_fmt parallels
|
||||
_supported_proto file
|
||||
_supported_os Linux
|
||||
|
||||
inuse_offset=$((0x2c))
|
||||
|
||||
size=64M
|
||||
CLUSTER_SIZE=64k
|
||||
IMGFMT=parallels
|
||||
_make_test_img $size
|
||||
|
||||
echo == read empty image ==
|
||||
{ $QEMU_IO -c "read -P 0 32k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
echo == write more than 1 block in a row ==
|
||||
{ $QEMU_IO -c "write -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
echo == read less than block ==
|
||||
{ $QEMU_IO -c "read -P 0x11 32k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
echo == read exactly 1 block ==
|
||||
{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
echo == read more than 1 block ==
|
||||
{ $QEMU_IO -c "read -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
echo == check that there is no trash after written ==
|
||||
{ $QEMU_IO -c "read -P 0 160k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
echo == check that there is no trash before written ==
|
||||
{ $QEMU_IO -c "read -P 0 0 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo "== Corrupt image =="
|
||||
poke_file "$TEST_IMG" "$inuse_offset" "\x59\x6e\x6f\x74"
|
||||
{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
_check_test_img
|
||||
_check_test_img -r all
|
||||
{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
status=0
|
||||
@@ -0,0 +1,41 @@
|
||||
QA output created by 131
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
== read empty image ==
|
||||
read 65536/65536 bytes at offset 32768
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== write more than 1 block in a row ==
|
||||
wrote 131072/131072 bytes at offset 32768
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== read less than block ==
|
||||
read 32768/32768 bytes at offset 32768
|
||||
32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== read exactly 1 block ==
|
||||
read 65536/65536 bytes at offset 65536
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== read more than 1 block ==
|
||||
read 131072/131072 bytes at offset 32768
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== check that there is no trash after written ==
|
||||
read 32768/32768 bytes at offset 163840
|
||||
32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== check that there is no trash before written ==
|
||||
read 32768/32768 bytes at offset 0
|
||||
32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
== Corrupt image ==
|
||||
qemu-io: can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write
|
||||
no file open, try 'help open'
|
||||
ERROR image was not closed correctly
|
||||
|
||||
1 errors were found on the image.
|
||||
Data may be corrupted, or further writes to the image may corrupt it.
|
||||
Repairing image was not closed correctly
|
||||
The following inconsistencies were found and repaired:
|
||||
|
||||
0 leaked clusters
|
||||
1 corruptions
|
||||
|
||||
Double checking the fixed image now...
|
||||
No errors were found on the image.
|
||||
read 65536/65536 bytes at offset 65536
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
*** done
|
||||
@@ -128,3 +128,4 @@
|
||||
128 rw auto quick
|
||||
129 rw auto quick
|
||||
130 rw auto quick
|
||||
131 rw auto quick
|
||||
|
||||
Reference in New Issue
Block a user