xref: /qemu/block/write-threshold.c (revision e2c1c34f)
1e2462113SFrancesco Romani /*
2e2462113SFrancesco Romani  * QEMU System Emulator block write threshold notification
3e2462113SFrancesco Romani  *
4e2462113SFrancesco Romani  * Copyright Red Hat, Inc. 2014
5e2462113SFrancesco Romani  *
6e2462113SFrancesco Romani  * Authors:
7e2462113SFrancesco Romani  *  Francesco Romani <fromani@redhat.com>
8e2462113SFrancesco Romani  *
9e2462113SFrancesco Romani  * This work is licensed under the terms of the GNU LGPL, version 2 or later.
10e2462113SFrancesco Romani  * See the COPYING.LIB file in the top-level directory.
11e2462113SFrancesco Romani  */
12e2462113SFrancesco Romani 
1380c71a24SPeter Maydell #include "qemu/osdep.h"
14e2c1c34fSMarkus Armbruster #include "block/block-io.h"
15e2462113SFrancesco Romani #include "block/block_int.h"
16e2462113SFrancesco Romani #include "block/write-threshold.h"
17e688df6bSMarkus Armbruster #include "qapi/error.h"
189af23989SMarkus Armbruster #include "qapi/qapi-commands-block-core.h"
199af23989SMarkus Armbruster #include "qapi/qapi-events-block-core.h"
20e2462113SFrancesco Romani 
21e2462113SFrancesco Romani uint64_t bdrv_write_threshold_get(const BlockDriverState *bs)
22e2462113SFrancesco Romani {
23e2462113SFrancesco Romani     return bs->write_threshold_offset;
24e2462113SFrancesco Romani }
25e2462113SFrancesco Romani 
26e2462113SFrancesco Romani void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes)
27e2462113SFrancesco Romani {
2894783301SVladimir Sementsov-Ogievskiy     bs->write_threshold_offset = threshold_bytes;
29e2462113SFrancesco Romani }
30e2462113SFrancesco Romani 
31e2462113SFrancesco Romani void qmp_block_set_write_threshold(const char *node_name,
32e2462113SFrancesco Romani                                    uint64_t threshold_bytes,
33e2462113SFrancesco Romani                                    Error **errp)
34e2462113SFrancesco Romani {
35e2462113SFrancesco Romani     BlockDriverState *bs;
36e2462113SFrancesco Romani     AioContext *aio_context;
37e2462113SFrancesco Romani 
38e2462113SFrancesco Romani     bs = bdrv_find_node(node_name);
39e2462113SFrancesco Romani     if (!bs) {
406ec46ad5SMarkus Armbruster         error_setg(errp, "Device '%s' not found", node_name);
41e2462113SFrancesco Romani         return;
42e2462113SFrancesco Romani     }
43e2462113SFrancesco Romani 
44e2462113SFrancesco Romani     aio_context = bdrv_get_aio_context(bs);
45e2462113SFrancesco Romani     aio_context_acquire(aio_context);
46e2462113SFrancesco Romani 
47e2462113SFrancesco Romani     bdrv_write_threshold_set(bs, threshold_bytes);
48e2462113SFrancesco Romani 
49e2462113SFrancesco Romani     aio_context_release(aio_context);
50e2462113SFrancesco Romani }
5194783301SVladimir Sementsov-Ogievskiy 
5294783301SVladimir Sementsov-Ogievskiy void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
5394783301SVladimir Sementsov-Ogievskiy                                       int64_t bytes)
5494783301SVladimir Sementsov-Ogievskiy {
5594783301SVladimir Sementsov-Ogievskiy     int64_t end = offset + bytes;
5694783301SVladimir Sementsov-Ogievskiy     uint64_t wtr = bs->write_threshold_offset;
5794783301SVladimir Sementsov-Ogievskiy 
5894783301SVladimir Sementsov-Ogievskiy     if (wtr > 0 && end > wtr) {
5994783301SVladimir Sementsov-Ogievskiy         qapi_event_send_block_write_threshold(bs->node_name, end - wtr, wtr);
6094783301SVladimir Sementsov-Ogievskiy 
6194783301SVladimir Sementsov-Ogievskiy         /* autodisable to avoid flooding the monitor */
6294783301SVladimir Sementsov-Ogievskiy         bdrv_write_threshold_set(bs, 0);
6394783301SVladimir Sementsov-Ogievskiy     }
6494783301SVladimir Sementsov-Ogievskiy }
65