block.c (0f01b9fdd4ba0a3d38e26e89e1b1faf1213eb4f1) block.c (061ca8a368165fae300748c17971824a089f521f)
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 3774 unchanged lines hidden (view full) ---

3783exit:
3784 bdrv_unref(top);
3785 return ret;
3786}
3787
3788/**
3789 * Truncate file to 'offset' bytes (needed only for file protocols)
3790 */
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 3774 unchanged lines hidden (view full) ---

3783exit:
3784 bdrv_unref(top);
3785 return ret;
3786}
3787
3788/**
3789 * Truncate file to 'offset' bytes (needed only for file protocols)
3790 */
3791int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
3792 Error **errp)
3791int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
3792 PreallocMode prealloc, Error **errp)
3793{
3794 BlockDriverState *bs = child->bs;
3795 BlockDriver *drv = bs->drv;
3796 int ret;
3797
3798 assert(child->perm & BLK_PERM_RESIZE);
3799
3800 /* if bs->drv == NULL, bs is closed, so there's nothing to do here */
3801 if (!drv) {
3802 error_setg(errp, "No medium inserted");
3803 return -ENOMEDIUM;
3804 }
3805 if (offset < 0) {
3806 error_setg(errp, "Image size cannot be negative");
3807 return -EINVAL;
3808 }
3809
3793{
3794 BlockDriverState *bs = child->bs;
3795 BlockDriver *drv = bs->drv;
3796 int ret;
3797
3798 assert(child->perm & BLK_PERM_RESIZE);
3799
3800 /* if bs->drv == NULL, bs is closed, so there's nothing to do here */
3801 if (!drv) {
3802 error_setg(errp, "No medium inserted");
3803 return -ENOMEDIUM;
3804 }
3805 if (offset < 0) {
3806 error_setg(errp, "Image size cannot be negative");
3807 return -EINVAL;
3808 }
3809
3810 if (!drv->bdrv_truncate) {
3810 bdrv_inc_in_flight(bs);
3811
3812 if (!drv->bdrv_co_truncate) {
3811 if (bs->file && drv->is_filter) {
3813 if (bs->file && drv->is_filter) {
3812 return bdrv_truncate(bs->file, offset, prealloc, errp);
3814 ret = bdrv_co_truncate(bs->file, offset, prealloc, errp);
3815 goto out;
3813 }
3814 error_setg(errp, "Image format driver does not support resize");
3816 }
3817 error_setg(errp, "Image format driver does not support resize");
3815 return -ENOTSUP;
3818 ret = -ENOTSUP;
3819 goto out;
3816 }
3817 if (bs->read_only) {
3818 error_setg(errp, "Image is read-only");
3820 }
3821 if (bs->read_only) {
3822 error_setg(errp, "Image is read-only");
3819 return -EACCES;
3823 ret = -EACCES;
3824 goto out;
3820 }
3821
3822 assert(!(bs->open_flags & BDRV_O_INACTIVE));
3823
3825 }
3826
3827 assert(!(bs->open_flags & BDRV_O_INACTIVE));
3828
3824 ret = drv->bdrv_truncate(bs, offset, prealloc, errp);
3829 ret = drv->bdrv_co_truncate(bs, offset, prealloc, errp);
3825 if (ret < 0) {
3830 if (ret < 0) {
3826 return ret;
3831 goto out;
3827 }
3828 ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
3829 if (ret < 0) {
3830 error_setg_errno(errp, -ret, "Could not refresh total sector count");
3831 } else {
3832 offset = bs->total_sectors * BDRV_SECTOR_SIZE;
3833 }
3834 bdrv_dirty_bitmap_truncate(bs, offset);
3835 bdrv_parent_cb_resize(bs);
3836 atomic_inc(&bs->write_gen);
3832 }
3833 ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
3834 if (ret < 0) {
3835 error_setg_errno(errp, -ret, "Could not refresh total sector count");
3836 } else {
3837 offset = bs->total_sectors * BDRV_SECTOR_SIZE;
3838 }
3839 bdrv_dirty_bitmap_truncate(bs, offset);
3840 bdrv_parent_cb_resize(bs);
3841 atomic_inc(&bs->write_gen);
3842
3843out:
3844 bdrv_dec_in_flight(bs);
3837 return ret;
3838}
3839
3845 return ret;
3846}
3847
3848typedef struct TruncateCo {
3849 BdrvChild *child;
3850 int64_t offset;
3851 PreallocMode prealloc;
3852 Error **errp;
3853 int ret;
3854} TruncateCo;
3855
3856static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
3857{
3858 TruncateCo *tco = opaque;
3859 tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->prealloc,
3860 tco->errp);
3861}
3862
3863int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
3864 Error **errp)
3865{
3866 Coroutine *co;
3867 TruncateCo tco = {
3868 .child = child,
3869 .offset = offset,
3870 .prealloc = prealloc,
3871 .errp = errp,
3872 .ret = NOT_DONE,
3873 };
3874
3875 if (qemu_in_coroutine()) {
3876 /* Fast-path if already in coroutine context */
3877 bdrv_truncate_co_entry(&tco);
3878 } else {
3879 co = qemu_coroutine_create(bdrv_truncate_co_entry, &tco);
3880 qemu_coroutine_enter(co);
3881 BDRV_POLL_WHILE(child->bs, tco.ret == NOT_DONE);
3882 }
3883
3884 return tco.ret;
3885}
3886
3840/**
3841 * Length of a allocated file in bytes. Sparse files are counted by actual
3842 * allocated space. Return < 0 if error or unknown.
3843 */
3844int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
3845{
3846 BlockDriver *drv = bs->drv;
3847 if (!drv) {

--- 1555 unchanged lines hidden ---
3887/**
3888 * Length of a allocated file in bytes. Sparse files are counted by actual
3889 * allocated space. Return < 0 if error or unknown.
3890 */
3891int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
3892{
3893 BlockDriver *drv = bs->drv;
3894 if (!drv) {

--- 1555 unchanged lines hidden ---