block: New BlockBackend
[qemu/cris-port.git] / block / block-backend.c
blobe89caa9611f5282d87e692b24539a055ba5972a3
1 /*
2 * QEMU Block backends
4 * Copyright (C) 2014 Red Hat, Inc.
6 * Authors:
7 * Markus Armbruster <armbru@redhat.com>,
9 * This work is licensed under the terms of the GNU LGPL, version 2.1
10 * or later. See the COPYING.LIB file in the top-level directory.
13 #include "sysemu/block-backend.h"
14 #include "block/block_int.h"
16 struct BlockBackend {
17 char *name;
18 int refcnt;
19 QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
22 /* All the BlockBackends */
23 static QTAILQ_HEAD(, BlockBackend) blk_backends =
24 QTAILQ_HEAD_INITIALIZER(blk_backends);
27 * Create a new BlockBackend with @name, with a reference count of one.
28 * @name must not be null or empty.
29 * Fail if a BlockBackend with this name already exists.
30 * Store an error through @errp on failure, unless it's null.
31 * Return the new BlockBackend on success, null on failure.
33 BlockBackend *blk_new(const char *name, Error **errp)
35 BlockBackend *blk;
37 assert(name && name[0]);
38 if (blk_by_name(name)) {
39 error_setg(errp, "Device with id '%s' already exists", name);
40 return NULL;
43 blk = g_new0(BlockBackend, 1);
44 blk->name = g_strdup(name);
45 blk->refcnt = 1;
46 QTAILQ_INSERT_TAIL(&blk_backends, blk, link);
47 return blk;
50 static void blk_delete(BlockBackend *blk)
52 assert(!blk->refcnt);
53 QTAILQ_REMOVE(&blk_backends, blk, link);
54 g_free(blk->name);
55 g_free(blk);
59 * Increment @blk's reference count.
60 * @blk must not be null.
62 void blk_ref(BlockBackend *blk)
64 blk->refcnt++;
68 * Decrement @blk's reference count.
69 * If this drops it to zero, destroy @blk.
70 * For convenience, do nothing if @blk is null.
72 void blk_unref(BlockBackend *blk)
74 if (blk) {
75 assert(blk->refcnt > 0);
76 if (!--blk->refcnt) {
77 blk_delete(blk);
83 * Return the BlockBackend after @blk.
84 * If @blk is null, return the first one.
85 * Else, return @blk's next sibling, which may be null.
87 * To iterate over all BlockBackends, do
88 * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
89 * ...
90 * }
92 BlockBackend *blk_next(BlockBackend *blk)
94 return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends);
98 * Return @blk's name, a non-null, non-empty string.
100 const char *blk_name(BlockBackend *blk)
102 return blk->name;
106 * Return the BlockBackend with name @name if it exists, else null.
107 * @name must not be null.
109 BlockBackend *blk_by_name(const char *name)
111 BlockBackend *blk;
113 assert(name);
114 QTAILQ_FOREACH(blk, &blk_backends, link) {
115 if (!strcmp(name, blk->name)) {
116 return blk;
119 return NULL;