Revision 4265d620 block.c

b/block.c
1768 1768
    return 1;
1769 1769
}
1770 1770

  
1771
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
1772
{
1773
    if (!bs->drv) {
1774
        return -ENOMEDIUM;
1775
    }
1776
    if (!bs->drv->bdrv_discard) {
1777
        return 0;
1778
    }
1779
    return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
1780
}
1781

  
1782 1771
/*
1783 1772
 * Returns true iff the specified sector is present in the disk image. Drivers
1784 1773
 * not implementing the functionality are assumed to not support backing files,
......
2754 2743
    return &acb->common;
2755 2744
}
2756 2745

  
2746
static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
2747
{
2748
    BlockDriverAIOCBCoroutine *acb = opaque;
2749
    BlockDriverState *bs = acb->common.bs;
2750

  
2751
    acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
2752
    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
2753
    qemu_bh_schedule(acb->bh);
2754
}
2755

  
2756
BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
2757
        int64_t sector_num, int nb_sectors,
2758
        BlockDriverCompletionFunc *cb, void *opaque)
2759
{
2760
    Coroutine *co;
2761
    BlockDriverAIOCBCoroutine *acb;
2762

  
2763
    trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
2764

  
2765
    acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
2766
    acb->req.sector = sector_num;
2767
    acb->req.nb_sectors = nb_sectors;
2768
    co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
2769
    qemu_coroutine_enter(co, acb);
2770

  
2771
    return &acb->common;
2772
}
2773

  
2757 2774
void bdrv_init(void)
2758 2775
{
2759 2776
    module_call_init(MODULE_INIT_BLOCK);
......
2915 2932
    return rwco.ret;
2916 2933
}
2917 2934

  
2935
static void coroutine_fn bdrv_discard_co_entry(void *opaque)
2936
{
2937
    RwCo *rwco = opaque;
2938

  
2939
    rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
2940
}
2941

  
2942
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
2943
                                 int nb_sectors)
2944
{
2945
    if (!bs->drv) {
2946
        return -ENOMEDIUM;
2947
    } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
2948
        return -EIO;
2949
    } else if (bs->read_only) {
2950
        return -EROFS;
2951
    } else if (bs->drv->bdrv_co_discard) {
2952
        return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
2953
    } else if (bs->drv->bdrv_aio_discard) {
2954
        BlockDriverAIOCB *acb;
2955
        CoroutineIOCompletion co = {
2956
            .coroutine = qemu_coroutine_self(),
2957
        };
2958

  
2959
        acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
2960
                                        bdrv_co_io_em_complete, &co);
2961
        if (acb == NULL) {
2962
            return -EIO;
2963
        } else {
2964
            qemu_coroutine_yield();
2965
            return co.ret;
2966
        }
2967
    } else if (bs->drv->bdrv_discard) {
2968
        return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
2969
    } else {
2970
        return 0;
2971
    }
2972
}
2973

  
2974
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
2975
{
2976
    Coroutine *co;
2977
    RwCo rwco = {
2978
        .bs = bs,
2979
        .sector_num = sector_num,
2980
        .nb_sectors = nb_sectors,
2981
        .ret = NOT_DONE,
2982
    };
2983

  
2984
    if (qemu_in_coroutine()) {
2985
        /* Fast-path if already in coroutine context */
2986
        bdrv_discard_co_entry(&rwco);
2987
    } else {
2988
        co = qemu_coroutine_create(bdrv_discard_co_entry);
2989
        qemu_coroutine_enter(co, &rwco);
2990
        while (rwco.ret == NOT_DONE) {
2991
            qemu_aio_wait();
2992
        }
2993
    }
2994

  
2995
    return rwco.ret;
2996
}
2997

  
2918 2998
/**************************************************************/
2919 2999
/* removable device support */
2920 3000

  

Also available in: Unified diff