block: Add PreallocMode to BD.bdrv_truncate()
Add a PreallocMode parameter to the bdrv_truncate() function implemented by each block driver. Currently, we always pass PREALLOC_MODE_OFF and no driver accepts anything else. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 20170613202107.10125-2-mreitz@redhat.com Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
32a1681adc
commit
8243ccb743
2
block.c
2
block.c
@ -3434,7 +3434,7 @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp)
|
|||||||
|
|
||||||
assert(!(bs->open_flags & BDRV_O_INACTIVE));
|
assert(!(bs->open_flags & BDRV_O_INACTIVE));
|
||||||
|
|
||||||
ret = drv->bdrv_truncate(bs, offset, errp);
|
ret = drv->bdrv_truncate(bs, offset, PREALLOC_MODE_OFF, errp);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
|
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
|
||||||
bdrv_dirty_bitmap_truncate(bs);
|
bdrv_dirty_bitmap_truncate(bs);
|
||||||
|
@ -821,8 +821,15 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
|
|||||||
return bdrv_getlength(bs->file->bs);
|
return bdrv_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int blkdebug_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int blkdebug_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
return bdrv_truncate(bs->file, offset, errp);
|
return bdrv_truncate(bs->file, offset, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,12 +361,18 @@ static int block_crypto_create_generic(QCryptoBlockFormat format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
|
static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
Error **errp)
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BlockCrypto *crypto = bs->opaque;
|
BlockCrypto *crypto = bs->opaque;
|
||||||
size_t payload_offset =
|
size_t payload_offset =
|
||||||
qcrypto_block_get_payload_offset(crypto->block);
|
qcrypto_block_get_payload_offset(crypto->block);
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
offset += payload_offset;
|
offset += payload_offset;
|
||||||
|
|
||||||
return bdrv_truncate(bs->file, offset, errp);
|
return bdrv_truncate(bs->file, offset, errp);
|
||||||
|
@ -1624,12 +1624,19 @@ static void raw_close(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int raw_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (fstat(s->fd, &st)) {
|
if (fstat(s->fd, &st)) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
error_setg_errno(errp, -ret, "Failed to fstat() the file");
|
error_setg_errno(errp, -ret, "Failed to fstat() the file");
|
||||||
|
@ -461,12 +461,19 @@ static void raw_close(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int raw_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
LONG low, high;
|
LONG low, high;
|
||||||
DWORD dwPtrLow;
|
DWORD dwPtrLow;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
low = offset;
|
low = offset;
|
||||||
high = offset >> 32;
|
high = offset >> 32;
|
||||||
|
|
||||||
|
@ -1096,11 +1096,17 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset,
|
static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
Error **errp)
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
BDRVGlusterState *s = bs->opaque;
|
BDRVGlusterState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
ret = glfs_ftruncate(s->fd, offset);
|
ret = glfs_ftruncate(s->fd, offset);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
|
@ -2079,11 +2079,18 @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iscsi_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int iscsi_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
IscsiLun *iscsilun = bs->opaque;
|
IscsiLun *iscsilun = bs->opaque;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (iscsilun->type != TYPE_DISK) {
|
if (iscsilun->type != TYPE_DISK) {
|
||||||
error_setg(errp, "Cannot resize non-disk iSCSI devices");
|
error_setg(errp, "Cannot resize non-disk iSCSI devices");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
@ -759,11 +759,18 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
|||||||
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
|
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int nfs_file_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
NFSClient *client = bs->opaque;
|
NFSClient *client = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
ret = nfs_ftruncate(client->context, client->fh, offset);
|
ret = nfs_ftruncate(client->context, client->fh, offset);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret, "Failed to truncate file");
|
error_setg_errno(errp, -ret, "Failed to truncate file");
|
||||||
|
@ -3058,12 +3058,19 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int64_t new_l1_size;
|
int64_t new_l1_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset & 511) {
|
if (offset & 511) {
|
||||||
error_setg(errp, "The new size must be a multiple of 512");
|
error_setg(errp, "The new size must be a multiple of 512");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1342,12 +1342,19 @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
|
|||||||
QED_AIOCB_WRITE | QED_AIOCB_ZERO);
|
QED_AIOCB_WRITE | QED_AIOCB_ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
uint64_t old_image_size;
|
uint64_t old_image_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (!qed_is_image_size_valid(offset, s->header.cluster_size,
|
if (!qed_is_image_size_valid(offset, s->header.cluster_size,
|
||||||
s->header.table_size)) {
|
s->header.table_size)) {
|
||||||
error_setg(errp, "Invalid image size specified");
|
error_setg(errp, "Invalid image size specified");
|
||||||
|
@ -352,10 +352,17 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int raw_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->has_size) {
|
if (s->has_size) {
|
||||||
error_setg(errp, "Cannot resize fixed-size raw disks");
|
error_setg(errp, "Cannot resize fixed-size raw disks");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
@ -936,11 +936,18 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs)
|
|||||||
return info.size;
|
return info.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVRBDState *s = bs->opaque;
|
BDRVRBDState *s = bs->opaque;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
r = rbd_resize(s->image, offset);
|
r = rbd_resize(s->image, offset);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
error_setg_errno(errp, -r, "Failed to resize file");
|
error_setg_errno(errp, -r, "Failed to resize file");
|
||||||
|
@ -2153,13 +2153,20 @@ static int64_t sd_getlength(BlockDriverState *bs)
|
|||||||
return s->inode.vdi_size;
|
return s->inode.vdi_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sd_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
|
static int sd_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVSheepdogState *s = bs->opaque;
|
BDRVSheepdogState *s = bs->opaque;
|
||||||
int ret, fd;
|
int ret, fd;
|
||||||
unsigned int datalen;
|
unsigned int datalen;
|
||||||
uint64_t max_vdi_size;
|
uint64_t max_vdi_size;
|
||||||
|
|
||||||
|
if (prealloc != PREALLOC_MODE_OFF) {
|
||||||
|
error_setg(errp, "Unsupported preallocation mode '%s'",
|
||||||
|
PreallocMode_lookup[prealloc]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS;
|
max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS;
|
||||||
if (offset < s->inode.vdi_size) {
|
if (offset < s->inode.vdi_size) {
|
||||||
error_setg(errp, "shrinking is not supported");
|
error_setg(errp, "shrinking is not supported");
|
||||||
@ -2448,7 +2455,7 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
|
|||||||
BDRVSheepdogState *s = bs->opaque;
|
BDRVSheepdogState *s = bs->opaque;
|
||||||
|
|
||||||
if (offset > s->inode.vdi_size) {
|
if (offset > s->inode.vdi_size) {
|
||||||
ret = sd_truncate(bs, offset, NULL);
|
ret = sd_truncate(bs, offset, PREALLOC_MODE_OFF, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,8 @@ struct BlockDriver {
|
|||||||
int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
|
int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
|
||||||
|
|
||||||
const char *protocol_name;
|
const char *protocol_name;
|
||||||
int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, Error **errp);
|
int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset,
|
||||||
|
PreallocMode prealloc, Error **errp);
|
||||||
|
|
||||||
int64_t (*bdrv_getlength)(BlockDriverState *bs);
|
int64_t (*bdrv_getlength)(BlockDriverState *bs);
|
||||||
bool has_variable_length;
|
bool has_variable_length;
|
||||||
|
Loading…
Reference in New Issue
Block a user