qemu/include/block/reqlist.h
<<
>>
Prefs
   1/*
   2 * reqlist API
   3 *
   4 * Copyright (C) 2013 Proxmox Server Solutions
   5 * Copyright (c) 2021 Virtuozzo International GmbH.
   6 *
   7 * Authors:
   8 *  Dietmar Maurer (dietmar@proxmox.com)
   9 *  Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
  10 *
  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.
  13 */
  14
  15#ifndef REQLIST_H
  16#define REQLIST_H
  17
  18#include "qemu/coroutine.h"
  19
  20/*
  21 * The API is not thread-safe and shouldn't be. The struct is public to be part
  22 * of other structures and protected by third-party locks, see
  23 * block/block-copy.c for example.
  24 */
  25
  26typedef struct BlockReq {
  27    int64_t offset;
  28    int64_t bytes;
  29
  30    CoQueue wait_queue; /* coroutines blocked on this req */
  31    QLIST_ENTRY(BlockReq) list;
  32} BlockReq;
  33
  34typedef QLIST_HEAD(, BlockReq) BlockReqList;
  35
  36/*
  37 * Initialize new request and add it to the list. Caller must be sure that
  38 * there are no conflicting requests in the list.
  39 */
  40void reqlist_init_req(BlockReqList *reqs, BlockReq *req, int64_t offset,
  41                      int64_t bytes);
  42/* Search for request in the list intersecting with @offset/@bytes area. */
  43BlockReq *reqlist_find_conflict(BlockReqList *reqs, int64_t offset,
  44                                int64_t bytes);
  45
  46/*
  47 * If there are no intersecting requests return false. Otherwise, wait for the
  48 * first found intersecting request to finish and return true.
  49 *
  50 * @lock is passed to qemu_co_queue_wait()
  51 * False return value proves that lock was released at no point.
  52 */
  53bool coroutine_fn reqlist_wait_one(BlockReqList *reqs, int64_t offset,
  54                                   int64_t bytes, CoMutex *lock);
  55
  56/*
  57 * Wait for all intersecting requests. It just calls reqlist_wait_one() in a
  58 * loop, caller is responsible to stop producing new requests in this region
  59 * in parallel, otherwise reqlist_wait_all() may never return.
  60 */
  61void coroutine_fn reqlist_wait_all(BlockReqList *reqs, int64_t offset,
  62                                   int64_t bytes, CoMutex *lock);
  63
  64/*
  65 * Shrink request and wake all waiting coroutines (maybe some of them are not
  66 * intersecting with shrunk request).
  67 */
  68void coroutine_fn reqlist_shrink_req(BlockReq *req, int64_t new_bytes);
  69
  70/*
  71 * Remove request and wake all waiting coroutines. Do not release any memory.
  72 */
  73void coroutine_fn reqlist_remove_req(BlockReq *req);
  74
  75#endif /* REQLIST_H */
  76