2
* tools/blktap_user/blkif.c
4
* The blkif interface for blktap. A blkif describes an in-use virtual disk.
5
* (c) 2005 Andrew Warfield and Julian Chesterfield
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License version 2
9
* as published by the Free Software Foundation; or, when distributed
10
* separately from the Linux kernel or incorporated into other
11
* software packages, subject to the following license:
13
* Permission is hereby granted, free of charge, to any person obtaining a copy
14
* of this source file (the "Software"), to deal in the Software without
15
* restriction, including without limitation the rights to use, copy, modify,
16
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
17
* and to permit persons to whom the Software is furnished to do so, subject to
18
* the following conditions:
20
* The above copyright notice and this permission notice shall be included in
21
* all copies or substantial portions of the Software.
23
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
39
#include "blktaplib.h"
42
#define DPRINTF(_f, _a...) printf ( _f , ## _a )
44
#define DPRINTF(_f, _a...) ((void)0)
47
#define BLKIF_HASHSZ 1024
48
#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
50
static blkif_t *blkif_hash[BLKIF_HASHSZ];
52
blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
54
blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
55
while ( (blkif != NULL) &&
56
((blkif->domid != domid) || (blkif->handle != handle)) )
57
blkif = blkif->hash_next;
61
blkif_t *alloc_blkif(domid_t domid)
64
DPRINTF("Alloc_blkif called [%d]\n",domid);
65
blkif = (blkif_t *)malloc(sizeof(blkif_t));
68
memset(blkif, 0, sizeof(*blkif));
74
/*Controller callbacks*/
75
static int (*new_devmap_hook)(blkif_t *blkif) = NULL;
76
void register_new_devmap_hook(int (*fn)(blkif_t *blkif))
81
static int (*new_unmap_hook)(blkif_t *blkif) = NULL;
82
void register_new_unmap_hook(int (*fn)(blkif_t *blkif))
87
static int (*new_blkif_hook)(blkif_t *blkif) = NULL;
88
void register_new_blkif_hook(int (*fn)(blkif_t *blkif))
93
int blkif_init(blkif_t *blkif, long int handle, long int pdev,
103
domid = blkif->domid;
104
blkif->handle = handle;
106
blkif->readonly = readonly;
109
* Call out to the new_blkif_hook.
110
* The tap application should define this,
111
* and it should return having set blkif->ops
114
if (new_blkif_hook == NULL)
116
DPRINTF("Probe detected a new blkif, but no new_blkif_hook!");
119
if (new_blkif_hook(blkif)!=0) {
120
DPRINTF("BLKIF: Image open failed\n");
124
/* Now wire it in. */
125
pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
126
DPRINTF("Created hash entry: %d [%d,%ld]\n",
127
BLKIF_HASH(domid, handle), domid, handle);
129
while ( *pblkif != NULL )
131
if ( ((*pblkif)->domid == domid) &&
132
((*pblkif)->handle == handle) )
134
DPRINTF("Could not create blkif: already exists\n");
137
pblkif = &(*pblkif)->hash_next;
139
blkif->hash_next = NULL;
142
if (new_devmap_hook == NULL)
144
DPRINTF("Probe setting up new blkif but no devmap hook!");
148
devnum = new_devmap_hook(blkif);
151
blkif->devnum = devnum;
156
void free_blkif(blkif_t *blkif)
158
blkif_t **pblkif, *curs;
161
pblkif = &blkif_hash[BLKIF_HASH(blkif->domid, blkif->handle)];
162
while ( (curs = *pblkif) != NULL )
166
*pblkif = curs->hash_next;
168
pblkif = &curs->hash_next;
171
if ((image=(image_t *)blkif->prv)!=NULL) {
174
if (blkif->info!=NULL) {
177
if (new_unmap_hook != NULL) new_unmap_hook(blkif);
182
void __init_blkif(void)
184
memset(blkif_hash, 0, sizeof(blkif_hash));