# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 8a89c0ff3f87af175531e27ddca16840f43587ee
# Parent ab0cae84cfeceb5a71484167e4f1abc7b2896239
[LINUX][BLKBACK] Support temporary disconnection from frontend.
Signed-off-by: Steven Smith <sos22@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 1
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 22 ++++++++++++++-----
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 6 +++--
3 files changed, 22 insertions(+), 7 deletions(-)
diff -r ab0cae84cfec -r 8a89c0ff3f87
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jun 27 15:38:32
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jun 27 18:08:46
2006 +0100
@@ -95,6 +95,7 @@ typedef struct blkif_st {
} blkif_t;
blkif_t *blkif_alloc(domid_t domid);
+void blkif_disconnect(blkif_t *blkif);
void blkif_free(blkif_t *blkif);
int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
diff -r ab0cae84cfec -r 8a89c0ff3f87
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Jun 27
15:38:32 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Jun 27
18:08:46 2006 +0100
@@ -32,6 +32,7 @@
#include "common.h"
#include <xen/evtchn.h>
+#include <linux/kthread.h>
static kmem_cache_t *blkif_cachep;
@@ -139,22 +140,33 @@ int blkif_map(blkif_t *blkif, unsigned l
return 0;
}
-void blkif_free(blkif_t *blkif)
+void blkif_disconnect(blkif_t *blkif)
{
+ if (blkif->xenblkd) {
+ kthread_stop(blkif->xenblkd);
+ blkif->xenblkd = NULL;
+ }
+
atomic_dec(&blkif->refcnt);
wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
+ atomic_inc(&blkif->refcnt);
- /* Already disconnected? */
- if (blkif->irq)
+ if (blkif->irq) {
unbind_from_irqhandler(blkif->irq, blkif);
-
- vbd_free(&blkif->vbd);
+ blkif->irq = 0;
+ }
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
+ blkif->blk_ring.sring = NULL;
}
+}
+void blkif_free(blkif_t *blkif)
+{
+ if (!atomic_dec_and_test(&blkif->refcnt))
+ BUG();
kmem_cache_free(blkif_cachep, blkif);
}
diff -r ab0cae84cfec -r 8a89c0ff3f87
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jun 27 15:38:32
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jun 27 18:08:46
2006 +0100
@@ -105,9 +105,10 @@ static int blkback_remove(struct xenbus_
kfree(be->backend_watch.node);
be->backend_watch.node = NULL;
}
+
if (be->blkif) {
- if (be->blkif->xenblkd)
- kthread_stop(be->blkif->xenblkd);
+ blkif_disconnect(be->blkif);
+ vbd_free(&be->blkif->vbd);
blkif_free(be->blkif);
be->blkif = NULL;
}
@@ -273,6 +274,7 @@ static void frontend_changed(struct xenb
break;
case XenbusStateClosing:
+ blkif_disconnect(be->blkif);
xenbus_switch_state(dev, XenbusStateClosing);
break;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|