diff options
Diffstat (limited to 'drivers/block/xen-blkback/xenbus.c')
-rw-r--r-- | drivers/block/xen-blkback/xenbus.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index e0fd92a2a4cd..1f1ade6d6e09 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -105,6 +105,7 @@ static void xen_update_blkif_status(struct xen_blkif *blkif) | |||
105 | static struct xen_blkif *xen_blkif_alloc(domid_t domid) | 105 | static struct xen_blkif *xen_blkif_alloc(domid_t domid) |
106 | { | 106 | { |
107 | struct xen_blkif *blkif; | 107 | struct xen_blkif *blkif; |
108 | int i; | ||
108 | 109 | ||
109 | blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL); | 110 | blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL); |
110 | if (!blkif) | 111 | if (!blkif) |
@@ -124,6 +125,21 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
124 | blkif->free_pages_num = 0; | 125 | blkif->free_pages_num = 0; |
125 | atomic_set(&blkif->persistent_gnt_in_use, 0); | 126 | atomic_set(&blkif->persistent_gnt_in_use, 0); |
126 | 127 | ||
128 | blkif->pending_reqs = kcalloc(XEN_BLKIF_REQS, | ||
129 | sizeof(blkif->pending_reqs[0]), | ||
130 | GFP_KERNEL); | ||
131 | if (!blkif->pending_reqs) { | ||
132 | kmem_cache_free(xen_blkif_cachep, blkif); | ||
133 | return ERR_PTR(-ENOMEM); | ||
134 | } | ||
135 | INIT_LIST_HEAD(&blkif->pending_free); | ||
136 | spin_lock_init(&blkif->pending_free_lock); | ||
137 | init_waitqueue_head(&blkif->pending_free_wq); | ||
138 | |||
139 | for (i = 0; i < XEN_BLKIF_REQS; i++) | ||
140 | list_add_tail(&blkif->pending_reqs[i].free_list, | ||
141 | &blkif->pending_free); | ||
142 | |||
127 | return blkif; | 143 | return blkif; |
128 | } | 144 | } |
129 | 145 | ||
@@ -203,8 +219,18 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) | |||
203 | 219 | ||
204 | static void xen_blkif_free(struct xen_blkif *blkif) | 220 | static void xen_blkif_free(struct xen_blkif *blkif) |
205 | { | 221 | { |
222 | struct pending_req *req; | ||
223 | int i = 0; | ||
224 | |||
206 | if (!atomic_dec_and_test(&blkif->refcnt)) | 225 | if (!atomic_dec_and_test(&blkif->refcnt)) |
207 | BUG(); | 226 | BUG(); |
227 | |||
228 | /* Check that there is no request in use */ | ||
229 | list_for_each_entry(req, &blkif->pending_free, free_list) | ||
230 | i++; | ||
231 | BUG_ON(i != XEN_BLKIF_REQS); | ||
232 | |||
233 | kfree(blkif->pending_reqs); | ||
208 | kmem_cache_free(xen_blkif_cachep, blkif); | 234 | kmem_cache_free(xen_blkif_cachep, blkif); |
209 | } | 235 | } |
210 | 236 | ||