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 --- |