block: Add @exact parameter to bdrv_co_truncate()
We have two drivers (iscsi and file-posix) that (in some cases) return success from their .bdrv_co_truncate() implementation if the block device is larger than the requested offset, but cannot be shrunk. Some callers do not want that behavior, so this patch adds a new parameter that they can use to turn off that behavior. This patch just adds the parameter and lets the block/io.c and block/block-backend.c functions pass it around. All other callers always pass false and none of the implementations evaluate it, so that this patch does not change existing behavior. Future patches take care of that. Suggested-by: Maxim Levitsky <mlevitsk@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com> Message-id: 20190918095144.955-5-mreitz@redhat.com Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
26536c7fc2
commit
c80d8b06cf
@ -2072,15 +2072,15 @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
|
||||
BDRV_REQ_WRITE_COMPRESSED);
|
||||
}
|
||||
|
||||
int blk_truncate(BlockBackend *blk, int64_t offset, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
if (!blk_is_available(blk)) {
|
||||
error_setg(errp, "No medium inserted");
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
return bdrv_truncate(blk->root, offset, prealloc, errp);
|
||||
return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
|
||||
}
|
||||
|
||||
static void blk_pdiscard_entry(void *opaque)
|
||||
|
@ -155,7 +155,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
|
||||
}
|
||||
|
||||
if (base_len < len) {
|
||||
ret = blk_truncate(s->base, len, PREALLOC_MODE_OFF, NULL);
|
||||
ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
@ -471,7 +471,8 @@ int bdrv_commit(BlockDriverState *bs)
|
||||
* grow the backing file image if possible. If not possible,
|
||||
* we must return an error */
|
||||
if (length > backing_length) {
|
||||
ret = blk_truncate(backing, length, PREALLOC_MODE_OFF, &local_err);
|
||||
ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
|
||||
&local_err);
|
||||
if (ret < 0) {
|
||||
error_report_err(local_err);
|
||||
goto ro_cleanup;
|
||||
|
@ -113,8 +113,8 @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
|
||||
* available to the guest, so we must take account of that
|
||||
* which will be used by the crypto header
|
||||
*/
|
||||
return blk_truncate(data->blk, data->size + headerlen, data->prealloc,
|
||||
errp);
|
||||
return blk_truncate(data->blk, data->size + headerlen, false,
|
||||
data->prealloc, errp);
|
||||
}
|
||||
|
||||
|
||||
@ -297,7 +297,7 @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
static int coroutine_fn
|
||||
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
BlockCrypto *crypto = bs->opaque;
|
||||
@ -311,7 +311,7 @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
|
||||
offset += payload_offset;
|
||||
|
||||
return bdrv_co_truncate(bs->file, offset, prealloc, errp);
|
||||
return bdrv_co_truncate(bs->file, offset, false, prealloc, errp);
|
||||
}
|
||||
|
||||
static void block_crypto_close(BlockDriverState *bs)
|
||||
|
@ -2019,7 +2019,8 @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
struct stat st;
|
||||
|
@ -468,7 +468,8 @@ static void raw_close(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
LONG low, high;
|
||||
|
@ -1225,6 +1225,7 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
|
||||
|
||||
static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
|
||||
int64_t offset,
|
||||
bool exact,
|
||||
PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
|
20
block/io.c
20
block/io.c
@ -3291,8 +3291,12 @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
|
||||
|
||||
/**
|
||||
* Truncate file to 'offset' bytes (needed only for file protocols)
|
||||
*
|
||||
* If 'exact' is true, the file must be resized to exactly the given
|
||||
* 'offset'. Otherwise, it is sufficient for the node to be at least
|
||||
* 'offset' bytes in length.
|
||||
*/
|
||||
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
|
||||
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs = child->bs;
|
||||
@ -3348,9 +3352,9 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
|
||||
}
|
||||
|
||||
if (drv->bdrv_co_truncate) {
|
||||
ret = drv->bdrv_co_truncate(bs, offset, prealloc, errp);
|
||||
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
|
||||
} else if (bs->file && drv->is_filter) {
|
||||
ret = bdrv_co_truncate(bs->file, offset, prealloc, errp);
|
||||
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
|
||||
} else {
|
||||
error_setg(errp, "Image format driver does not support resize");
|
||||
ret = -ENOTSUP;
|
||||
@ -3381,6 +3385,7 @@ out:
|
||||
typedef struct TruncateCo {
|
||||
BdrvChild *child;
|
||||
int64_t offset;
|
||||
bool exact;
|
||||
PreallocMode prealloc;
|
||||
Error **errp;
|
||||
int ret;
|
||||
@ -3389,18 +3394,19 @@ typedef struct TruncateCo {
|
||||
static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
|
||||
{
|
||||
TruncateCo *tco = opaque;
|
||||
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->prealloc,
|
||||
tco->errp);
|
||||
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
|
||||
tco->prealloc, tco->errp);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
Coroutine *co;
|
||||
TruncateCo tco = {
|
||||
.child = child,
|
||||
.offset = offset,
|
||||
.exact = exact,
|
||||
.prealloc = prealloc,
|
||||
.errp = errp,
|
||||
.ret = NOT_DONE,
|
||||
|
@ -2123,7 +2123,8 @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
|
||||
}
|
||||
|
||||
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
IscsiLun *iscsilun = bs->opaque;
|
||||
Error *local_err = NULL;
|
||||
|
@ -878,8 +878,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||
}
|
||||
|
||||
if (s->bdev_length > base_length) {
|
||||
ret = blk_truncate(s->target, s->bdev_length, PREALLOC_MODE_OFF,
|
||||
NULL);
|
||||
ret = blk_truncate(s->target, s->bdev_length, false,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
if (ret < 0) {
|
||||
goto immediate_exit;
|
||||
}
|
||||
|
@ -752,7 +752,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
static int coroutine_fn
|
||||
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
NFSClient *client = bs->opaque;
|
||||
|
@ -203,7 +203,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||
} else {
|
||||
ret = bdrv_truncate(bs->file,
|
||||
(s->data_end + space) << BDRV_SECTOR_BITS,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
false, PREALLOC_MODE_OFF, NULL);
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -487,7 +487,7 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
|
||||
res->leaks += count;
|
||||
if (fix & BDRV_FIX_LEAKS) {
|
||||
Error *local_err = NULL;
|
||||
ret = bdrv_truncate(bs->file, res->image_end_offset,
|
||||
ret = bdrv_truncate(bs->file, res->image_end_offset, false,
|
||||
PREALLOC_MODE_OFF, &local_err);
|
||||
if (ret < 0) {
|
||||
error_report_err(local_err);
|
||||
@ -880,7 +880,7 @@ static void parallels_close(BlockDriverState *bs)
|
||||
if ((bs->open_flags & BDRV_O_RDWR) && !(bs->open_flags & BDRV_O_INACTIVE)) {
|
||||
s->header->inuse = 0;
|
||||
parallels_update_header(bs);
|
||||
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS,
|
||||
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, false,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
}
|
||||
|
||||
|
@ -480,7 +480,7 @@ static int get_cluster_offset(BlockDriverState *bs,
|
||||
return -E2BIG;
|
||||
}
|
||||
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
false, PREALLOC_MODE_OFF, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -1033,7 +1033,7 @@ static int qcow_make_empty(BlockDriverState *bs)
|
||||
if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
|
||||
l1_length) < 0)
|
||||
return -1;
|
||||
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length,
|
||||
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -2016,7 +2016,7 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
goto resize_fail;
|
||||
}
|
||||
|
||||
ret = bdrv_truncate(bs->file, offset + s->cluster_size,
|
||||
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
|
||||
PREALLOC_MODE_OFF, &local_err);
|
||||
if (ret < 0) {
|
||||
error_report_err(local_err);
|
||||
|
@ -3074,8 +3074,8 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
||||
if (mode == PREALLOC_MODE_METADATA) {
|
||||
mode = PREALLOC_MODE_OFF;
|
||||
}
|
||||
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, mode,
|
||||
errp);
|
||||
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
|
||||
mode, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -3489,7 +3489,8 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
}
|
||||
|
||||
/* Okay, now that we have a valid image, let's give it the right size */
|
||||
ret = blk_truncate(blk, qcow2_opts->size, qcow2_opts->preallocation, errp);
|
||||
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
|
||||
errp);
|
||||
if (ret < 0) {
|
||||
error_prepend(errp, "Could not resize image: ");
|
||||
goto out;
|
||||
@ -3937,7 +3938,8 @@ fail:
|
||||
}
|
||||
|
||||
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
uint64_t old_length;
|
||||
@ -4026,7 +4028,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
Error *local_err = NULL;
|
||||
|
||||
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
|
||||
PREALLOC_MODE_OFF, &local_err);
|
||||
false, PREALLOC_MODE_OFF, &local_err);
|
||||
if (local_err) {
|
||||
warn_reportf_err(local_err,
|
||||
"Failed to truncate the tail of the image: ");
|
||||
@ -4043,7 +4045,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
switch (prealloc) {
|
||||
case PREALLOC_MODE_OFF:
|
||||
if (has_data_file(bs)) {
|
||||
ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
|
||||
ret = bdrv_co_truncate(s->data_file, offset, false, prealloc, errp);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -4128,7 +4130,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
/* Allocate the data area */
|
||||
new_file_size = allocation_start +
|
||||
nb_new_data_clusters * s->cluster_size;
|
||||
ret = bdrv_co_truncate(bs->file, new_file_size, prealloc, errp);
|
||||
ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
|
||||
if (ret < 0) {
|
||||
error_prepend(errp, "Failed to resize underlying file: ");
|
||||
qcow2_free_clusters(bs, allocation_start,
|
||||
@ -4231,7 +4233,7 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
|
||||
if (len < 0) {
|
||||
return len;
|
||||
}
|
||||
return bdrv_co_truncate(bs->file, len, PREALLOC_MODE_OFF, NULL);
|
||||
return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
|
||||
}
|
||||
|
||||
if (offset_into_cluster(s, offset)) {
|
||||
@ -4468,7 +4470,7 @@ static int make_completely_empty(BlockDriverState *bs)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size,
|
||||
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
|
||||
PREALLOC_MODE_OFF, &local_err);
|
||||
if (ret < 0) {
|
||||
error_report_err(local_err);
|
||||
@ -5308,7 +5310,7 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = blk_truncate(blk, new_size, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, new_size, false, PREALLOC_MODE_OFF, errp);
|
||||
blk_unref(blk);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -674,7 +674,7 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
|
||||
l1_size = header.cluster_size * header.table_size;
|
||||
|
||||
/* File must start empty and grow, check truncate is supported */
|
||||
ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, 0, false, PREALLOC_MODE_OFF, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
@ -1461,6 +1461,7 @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
|
||||
static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
|
||||
int64_t offset,
|
||||
bool exact,
|
||||
PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
|
@ -370,7 +370,8 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
@ -386,7 +387,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
|
||||
s->size = offset;
|
||||
offset += s->offset;
|
||||
return bdrv_co_truncate(bs->file, offset, prealloc, errp);
|
||||
return bdrv_co_truncate(bs->file, offset, false, prealloc, errp);
|
||||
}
|
||||
|
||||
static void raw_eject(BlockDriverState *bs, bool eject_flag)
|
||||
|
@ -1087,6 +1087,7 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs)
|
||||
|
||||
static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
|
||||
int64_t offset,
|
||||
bool exact,
|
||||
PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
|
@ -2285,7 +2285,8 @@ static int64_t sd_getlength(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVSheepdogState *s = bs->opaque;
|
||||
int ret, fd;
|
||||
@ -2601,7 +2602,7 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
|
||||
|
||||
assert(!flags);
|
||||
if (offset > s->inode.vdi_size) {
|
||||
ret = sd_co_truncate(bs, offset, PREALLOC_MODE_OFF, NULL);
|
||||
ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1295,7 +1295,8 @@ static int64_t ssh_getlength(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVSSHState *s = bs->opaque;
|
||||
|
||||
|
@ -874,7 +874,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
|
||||
}
|
||||
|
||||
if (image_type == VDI_TYPE_STATIC) {
|
||||
ret = blk_truncate(blk, offset + blocks * block_size,
|
||||
ret = blk_truncate(blk, offset + blocks * block_size, false,
|
||||
PREALLOC_MODE_OFF, errp);
|
||||
if (ret < 0) {
|
||||
error_prepend(errp, "Failed to statically allocate file");
|
||||
|
@ -557,8 +557,8 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
ret = bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF,
|
||||
NULL);
|
||||
ret = bdrv_truncate(bs->file, new_file_size, false,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
@ -1263,7 +1263,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return bdrv_truncate(bs->file, *new_offset + s->block_size,
|
||||
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
}
|
||||
|
||||
@ -1702,12 +1702,13 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
|
||||
if (type == VHDX_TYPE_DYNAMIC) {
|
||||
/* All zeroes, so we can just extend the file - the end of the BAT
|
||||
* is the furthest thing we have written yet */
|
||||
ret = blk_truncate(blk, data_file_offset, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
|
||||
errp);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
} else if (type == VHDX_TYPE_FIXED) {
|
||||
ret = blk_truncate(blk, data_file_offset + image_size,
|
||||
ret = blk_truncate(blk, data_file_offset + image_size, false,
|
||||
PREALLOC_MODE_OFF, errp);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
|
@ -2076,7 +2076,7 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
return length;
|
||||
}
|
||||
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
|
||||
ret = bdrv_truncate(s->extents[i].file, length,
|
||||
ret = bdrv_truncate(s->extents[i].file, length, false,
|
||||
PREALLOC_MODE_OFF, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -2118,7 +2118,7 @@ static int vmdk_init_extent(BlockBackend *blk,
|
||||
int gd_buf_size;
|
||||
|
||||
if (flat) {
|
||||
ret = blk_truncate(blk, filesize, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
|
||||
goto exit;
|
||||
}
|
||||
magic = cpu_to_be32(VMDK4_MAGIC);
|
||||
@ -2181,7 +2181,7 @@ static int vmdk_init_extent(BlockBackend *blk,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9,
|
||||
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
|
||||
PREALLOC_MODE_OFF, errp);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
@ -2523,7 +2523,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
|
||||
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
|
||||
* for description file */
|
||||
if (desc_offset == 0) {
|
||||
ret = blk_truncate(blk, desc_len, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
@ -898,7 +898,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
|
||||
/* Add footer to total size */
|
||||
total_size += HEADER_SIZE;
|
||||
|
||||
ret = blk_truncate(blk, total_size, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -3204,7 +3204,7 @@ void qmp_block_resize(bool has_device, const char *device,
|
||||
}
|
||||
|
||||
bdrv_drained_begin(bs);
|
||||
ret = blk_truncate(blk, size, PREALLOC_MODE_OFF, errp);
|
||||
ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
|
||||
bdrv_drained_end(bs);
|
||||
|
||||
out:
|
||||
|
@ -346,10 +346,10 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
||||
const char *backing_file);
|
||||
void bdrv_refresh_filename(BlockDriverState *bs);
|
||||
|
||||
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
|
||||
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp);
|
||||
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp);
|
||||
int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
|
||||
Error **errp);
|
||||
|
||||
int64_t bdrv_nb_sectors(BlockDriverState *bs);
|
||||
int64_t bdrv_getlength(BlockDriverState *bs);
|
||||
|
@ -334,8 +334,23 @@ struct BlockDriver {
|
||||
* bdrv_parse_filename.
|
||||
*/
|
||||
const char *protocol_name;
|
||||
|
||||
/*
|
||||
* Truncate @bs to @offset bytes using the given @prealloc mode
|
||||
* when growing. Modes other than PREALLOC_MODE_OFF should be
|
||||
* rejected when shrinking @bs.
|
||||
*
|
||||
* If @exact is true, @bs must be resized to exactly @offset.
|
||||
* Otherwise, it is sufficient for @bs (if it is a host block
|
||||
* device and thus there is no way to resize it) to be at least
|
||||
* @offset bytes in length.
|
||||
*
|
||||
* If @exact is true and this function fails but would succeed
|
||||
* with @exact = false, it should return -ENOTSUP.
|
||||
*/
|
||||
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
|
||||
PreallocMode prealloc, Error **errp);
|
||||
bool exact, PreallocMode prealloc,
|
||||
Error **errp);
|
||||
|
||||
int64_t (*bdrv_getlength)(BlockDriverState *bs);
|
||||
bool has_variable_length;
|
||||
|
@ -237,8 +237,8 @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
|
||||
int bytes, BdrvRequestFlags flags);
|
||||
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
|
||||
int bytes);
|
||||
int blk_truncate(BlockBackend *blk, int64_t offset, PreallocMode prealloc,
|
||||
Error **errp);
|
||||
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp);
|
||||
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
|
||||
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
|
||||
int64_t pos, int size);
|
||||
|
@ -3831,7 +3831,7 @@ static int img_resize(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
ret = blk_truncate(blk, total_size, prealloc, &err);
|
||||
ret = blk_truncate(blk, total_size, false, prealloc, &err);
|
||||
if (ret < 0) {
|
||||
error_report_err(err);
|
||||
goto out;
|
||||
|
@ -1710,7 +1710,7 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
|
||||
return offset;
|
||||
}
|
||||
|
||||
ret = blk_truncate(blk, offset, PREALLOC_MODE_OFF, &local_err);
|
||||
ret = blk_truncate(blk, offset, false, PREALLOC_MODE_OFF, &local_err);
|
||||
if (ret < 0) {
|
||||
error_report_err(local_err);
|
||||
return ret;
|
||||
|
@ -45,7 +45,7 @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
static int coroutine_fn
|
||||
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
return 0;
|
||||
@ -185,18 +185,18 @@ static void test_sync_op_truncate(BdrvChild *c)
|
||||
int ret;
|
||||
|
||||
/* Normal success path */
|
||||
ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
|
||||
ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
|
||||
g_assert_cmpint(ret, ==, 0);
|
||||
|
||||
/* Early error: Negative offset */
|
||||
ret = bdrv_truncate(c, -2, PREALLOC_MODE_OFF, NULL);
|
||||
ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
|
||||
g_assert_cmpint(ret, ==, -EINVAL);
|
||||
|
||||
/* Error: Read-only image */
|
||||
c->bs->read_only = true;
|
||||
c->bs->open_flags &= ~BDRV_O_RDWR;
|
||||
|
||||
ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
|
||||
ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
|
||||
g_assert_cmpint(ret, ==, -EACCES);
|
||||
|
||||
c->bs->read_only = false;
|
||||
|
Loading…
Reference in New Issue
Block a user