~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/blktap/lib/blkif.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 */
 
31
 
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <errno.h>
 
35
#include <string.h>
 
36
#include <err.h>
 
37
#include <unistd.h>
 
38
 
 
39
#include "blktaplib.h"
 
40
 
 
41
#if 0
 
42
#define DPRINTF(_f, _a...) printf ( _f , ## _a )
 
43
#else
 
44
#define DPRINTF(_f, _a...) ((void)0)
 
45
#endif
 
46
 
 
47
#define BLKIF_HASHSZ 1024
 
48
#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
 
49
 
 
50
static blkif_t      *blkif_hash[BLKIF_HASHSZ];
 
51
 
 
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
}
 
60
 
 
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
}
 
73
 
 
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
}
 
80
 
 
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
}
 
86
 
 
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
}
 
92
 
 
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;
 
99
        
 
100
        if (blkif == NULL)
 
101
                return -EINVAL;
 
102
        
 
103
        domid = blkif->domid;
 
104
        blkif->handle   = handle;
 
105
        blkif->pdev     = pdev;
 
106
        blkif->readonly = readonly;
 
107
        
 
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
        }
 
123
        
 
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);
 
128
        
 
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;
 
141
        
 
142
        if (new_devmap_hook == NULL)
 
143
        {
 
144
                DPRINTF("Probe setting up new blkif but no devmap hook!");
 
145
                return -1;
 
146
        }
 
147
        
 
148
        devnum = new_devmap_hook(blkif);
 
149
        if (devnum == -1)
 
150
                return -1;
 
151
        blkif->devnum = devnum;
 
152
        
 
153
        return 0;
 
154
}
 
155
 
 
156
void free_blkif(blkif_t *blkif)
 
157
{
 
158
        blkif_t **pblkif, *curs;
 
159
        image_t *image;
 
160
        
 
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
}
 
181
 
 
182
void __init_blkif(void)
 
183
{    
 
184
        memset(blkif_hash, 0, sizeof(blkif_hash));
 
185
}