# HG changeset patch
# User smh22@xxxxxxxxxxxxxxxxxxxx
# Node ID f6fdb6e0d3c96241354fe87cb264d740dfe4087c
# Parent 51f91ef6c3b5ea1f302340ca4147d5a9f4c4260f
Fix race in blkfront resume path (watch thread could fire watch during the
(short-ish) time that we were in BLKIF_STATE_DISCONNECTED).
Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
diff -r 51f91ef6c3b5 -r f6fdb6e0d3c9
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Nov 17
12:32:05 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Nov 17
13:56:50 2005
@@ -57,6 +57,7 @@
#define BLKIF_STATE_DISCONNECTED 0
#define BLKIF_STATE_CONNECTED 1
+#define BLKIF_STATE_SUSPENDED 2
#define MAXIMUM_OUTSTANDING_BLOCK_REQS \
(BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
@@ -75,7 +76,7 @@
static void blkif_restart_queue(void *arg);
static void blkif_recover(struct blkfront_info *);
static void blkif_completion(struct blk_shadow *);
-static void blkif_free(struct blkfront_info *);
+static void blkif_free(struct blkfront_info *, int);
/**
@@ -144,7 +145,7 @@
DPRINTK("blkfront_resume: %s\n", dev->nodename);
- blkif_free(info);
+ blkif_free(info, 1);
err = talk_to_backend(dev, info);
if (!err)
@@ -207,7 +208,7 @@
if (message)
xenbus_dev_fatal(dev, err, "%s", message);
destroy_blkring:
- blkif_free(info);
+ blkif_free(info, 0);
out:
return err;
}
@@ -252,7 +253,7 @@
return 0;
fail:
- blkif_free(info);
+ blkif_free(info, 0);
return err;
}
@@ -295,7 +296,8 @@
unsigned int binfo;
int err;
- if (info->connected == BLKIF_STATE_CONNECTED)
+ if( (info->connected == BLKIF_STATE_CONNECTED) ||
+ (info->connected == BLKIF_STATE_SUSPENDED) )
return;
DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
@@ -354,7 +356,7 @@
DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
- blkif_free(info);
+ blkif_free(info, 0);
kfree(info);
@@ -569,6 +571,7 @@
req->nr_sectors, req->buffer,
rq_data_dir(req) ? "write" : "read");
+
blkdev_dequeue_request(req);
if (blkif_queue_request(req)) {
blk_requeue_request(rq, req);
@@ -643,11 +646,12 @@
return IRQ_HANDLED;
}
-static void blkif_free(struct blkfront_info *info)
+static void blkif_free(struct blkfront_info *info, int suspend)
{
/* Prevent new requests being issued until we fix things up. */
spin_lock_irq(&blkif_io_lock);
- info->connected = BLKIF_STATE_DISCONNECTED;
+ info->connected = suspend ?
+ BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
spin_unlock_irq(&blkif_io_lock);
/* Free resources associated with old device channel. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|