ia64/xen-unstable

view tools/blktap/lib/blkif.c @ 15783:c93e2a822d6f

[xen, xencomm] xencomm multiple page support
Current implementation doesn't allow struct xencomm_desc::address
array to be more than single page. On IA64 it causes 64GB+ domain
creation failure. This patch generalizes xencomm to allow multipage

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author kfraser@localhost.localdomain
date Tue Aug 28 15:32:27 2007 +0100 (2007-08-28)
parents 2937703f0ed0
children
line source
1 /*
2 * tools/blktap_user/blkif.c
3 *
4 * The blkif interface for blktap. A blkif describes an in-use virtual disk.
5 * (c) 2005 Andrew Warfield and Julian Chesterfield
6 *
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:
12 *
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:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
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
29 * IN THE SOFTWARE.
30 */
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <err.h>
37 #include <unistd.h>
39 #include "blktaplib.h"
41 #if 0
42 #define DPRINTF(_f, _a...) printf ( _f , ## _a )
43 #else
44 #define DPRINTF(_f, _a...) ((void)0)
45 #endif
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)
53 {
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;
58 return blkif;
59 }
61 blkif_t *alloc_blkif(domid_t domid)
62 {
63 blkif_t *blkif;
64 DPRINTF("Alloc_blkif called [%d]\n",domid);
65 blkif = (blkif_t *)malloc(sizeof(blkif_t));
66 if (!blkif)
67 return NULL;
68 memset(blkif, 0, sizeof(*blkif));
69 blkif->domid = domid;
70 blkif->devnum = -1;
71 return blkif;
72 }
74 /*Controller callbacks*/
75 static int (*new_devmap_hook)(blkif_t *blkif) = NULL;
76 void register_new_devmap_hook(int (*fn)(blkif_t *blkif))
77 {
78 new_devmap_hook = fn;
79 }
81 static int (*new_unmap_hook)(blkif_t *blkif) = NULL;
82 void register_new_unmap_hook(int (*fn)(blkif_t *blkif))
83 {
84 new_unmap_hook = fn;
85 }
87 static int (*new_blkif_hook)(blkif_t *blkif) = NULL;
88 void register_new_blkif_hook(int (*fn)(blkif_t *blkif))
89 {
90 new_blkif_hook = fn;
91 }
93 int blkif_init(blkif_t *blkif, long int handle, long int pdev,
94 long int readonly)
95 {
96 domid_t domid;
97 blkif_t **pblkif;
98 int devnum;
100 if (blkif == NULL)
101 return -EINVAL;
103 domid = blkif->domid;
104 blkif->handle = handle;
105 blkif->pdev = pdev;
106 blkif->readonly = readonly;
108 /*
109 * Call out to the new_blkif_hook.
110 * The tap application should define this,
111 * and it should return having set blkif->ops
112 *
113 */
114 if (new_blkif_hook == NULL)
115 {
116 DPRINTF("Probe detected a new blkif, but no new_blkif_hook!");
117 return -1;
118 }
119 if (new_blkif_hook(blkif)!=0) {
120 DPRINTF("BLKIF: Image open failed\n");
121 return -1;
122 }
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 )
130 {
131 if ( ((*pblkif)->domid == domid) &&
132 ((*pblkif)->handle == handle) )
133 {
134 DPRINTF("Could not create blkif: already exists\n");
135 return -1;
136 }
137 pblkif = &(*pblkif)->hash_next;
138 }
139 blkif->hash_next = NULL;
140 *pblkif = blkif;
142 if (new_devmap_hook == NULL)
143 {
144 DPRINTF("Probe setting up new blkif but no devmap hook!");
145 return -1;
146 }
148 devnum = new_devmap_hook(blkif);
149 if (devnum == -1)
150 return -1;
151 blkif->devnum = devnum;
153 return 0;
154 }
156 void free_blkif(blkif_t *blkif)
157 {
158 blkif_t **pblkif, *curs;
159 image_t *image;
161 pblkif = &blkif_hash[BLKIF_HASH(blkif->domid, blkif->handle)];
162 while ( (curs = *pblkif) != NULL )
163 {
164 if ( blkif == curs )
165 {
166 *pblkif = curs->hash_next;
167 }
168 pblkif = &curs->hash_next;
169 }
170 if (blkif != NULL) {
171 if ((image=(image_t *)blkif->prv)!=NULL) {
172 free(blkif->prv);
173 }
174 if (blkif->info!=NULL) {
175 free(blkif->info);
176 }
177 if (new_unmap_hook != NULL) new_unmap_hook(blkif);
178 free(blkif);
179 }
180 }
182 void __init_blkif(void)
183 {
184 memset(blkif_hash, 0, sizeof(blkif_hash));
185 }