4 * Copyright (C) 2013 Proxmox Server Solutions
5 * Copyright (c) 2021 Virtuozzo International GmbH.
8 * Dietmar Maurer (dietmar@proxmox.com)
9 * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12 * See the COPYING file in the top-level directory.
15 #include "qemu/osdep.h"
16 #include "qemu/range.h"
18 #include "block/reqlist.h"
20 void reqlist_init_req(BlockReqList
*reqs
, BlockReq
*req
, int64_t offset
,
23 assert(!reqlist_find_conflict(reqs
, offset
, bytes
));
29 qemu_co_queue_init(&req
->wait_queue
);
30 QLIST_INSERT_HEAD(reqs
, req
, list
);
33 BlockReq
*reqlist_find_conflict(BlockReqList
*reqs
, int64_t offset
,
38 QLIST_FOREACH(r
, reqs
, list
) {
39 if (ranges_overlap(offset
, bytes
, r
->offset
, r
->bytes
)) {
47 bool coroutine_fn
reqlist_wait_one(BlockReqList
*reqs
, int64_t offset
,
48 int64_t bytes
, CoMutex
*lock
)
50 BlockReq
*r
= reqlist_find_conflict(reqs
, offset
, bytes
);
56 qemu_co_queue_wait(&r
->wait_queue
, lock
);
61 void coroutine_fn
reqlist_wait_all(BlockReqList
*reqs
, int64_t offset
,
62 int64_t bytes
, CoMutex
*lock
)
64 while (reqlist_wait_one(reqs
, offset
, bytes
, lock
)) {
69 void coroutine_fn
reqlist_shrink_req(BlockReq
*req
, int64_t new_bytes
)
71 if (new_bytes
== req
->bytes
) {
75 assert(new_bytes
> 0 && new_bytes
< req
->bytes
);
77 req
->bytes
= new_bytes
;
78 qemu_co_queue_restart_all(&req
->wait_queue
);
81 void coroutine_fn
reqlist_remove_req(BlockReq
*req
)
83 QLIST_REMOVE(req
, list
);
84 qemu_co_queue_restart_all(&req
->wait_queue
);