ia64/xen-unstable

changeset 9624:24d25894f071

Do not create blkback vbd kernel thread until fully connected
to frontend driver. Otherwise the kernel thread may crash trying
to access the non-existent shared ring.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 06 18:39:00 2006 +0100 (2006-04-06)
parents 388c59fefaa6
children b6c5920e5d99
files linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6-xen-sparse/drivers/xen/blkback/common.h linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Thu Apr 06 17:49:21 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Thu Apr 06 18:39:00 2006 +0100
     1.3 @@ -287,7 +287,7 @@ static int end_block_io_op(struct bio *b
     1.4   * NOTIFICATION FROM GUEST OS.
     1.5   */
     1.6  
     1.7 -void blkif_notify_work(blkif_t *blkif)
     1.8 +static void blkif_notify_work(blkif_t *blkif)
     1.9  {
    1.10  	blkif->waiting_reqs = 1;
    1.11  	wake_up(&blkif->wq);
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Thu Apr 06 17:49:21 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Thu Apr 06 18:39:00 2006 +0100
     2.3 @@ -129,7 +129,6 @@ void blkif_interface_init(void);
     2.4  
     2.5  void blkif_xenbus_init(void);
     2.6  
     2.7 -void blkif_notify_work(blkif_t *blkif);
     2.8  irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
     2.9  int blkif_schedule(void *arg);
    2.10  
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Thu Apr 06 17:49:21 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Thu Apr 06 18:39:00 2006 +0100
     3.3 @@ -46,10 +46,29 @@ static void backend_changed(struct xenbu
     3.4  
     3.5  static void update_blkif_status(blkif_t *blkif)
     3.6  { 
     3.7 -	if (blkif->irq && blkif->vbd.bdev &&
     3.8 -	    (blkif->be->dev->state != XenbusStateConnected)) {
     3.9 -		connect(blkif->be);
    3.10 -		blkif_notify_work(blkif);
    3.11 +	int err;
    3.12 +
    3.13 +	/* Not ready to connect? */
    3.14 +	if (!blkif->irq || !blkif->vbd.bdev)
    3.15 +		return;
    3.16 +
    3.17 +	/* Already connected? */
    3.18 +	if (blkif->be->dev->state == XenbusStateConnected)
    3.19 +		return;
    3.20 +
    3.21 +	/* Attempt to connect: exit if we fail to. */
    3.22 +	connect(blkif->be);
    3.23 +	if (blkif->be->dev->state != XenbusStateConnected)
    3.24 +		return;
    3.25 +
    3.26 +	blkif->xenblkd = kthread_run(blkif_schedule, blkif,
    3.27 +				     "xvd %d %02x:%02x",
    3.28 +				     blkif->domid,
    3.29 +				     blkif->be->major, blkif->be->minor);
    3.30 +	if (IS_ERR(blkif->xenblkd)) {
    3.31 +		err = PTR_ERR(blkif->xenblkd);
    3.32 +		blkif->xenblkd = NULL;
    3.33 +		xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
    3.34  	}
    3.35  }
    3.36  
    3.37 @@ -215,17 +234,6 @@ static void backend_changed(struct xenbu
    3.38  			return;
    3.39  		}
    3.40  
    3.41 -		be->blkif->xenblkd = kthread_run(blkif_schedule, be->blkif,
    3.42 -						 "xvd %d %02x:%02x",
    3.43 -						 be->blkif->domid,
    3.44 -						 be->major, be->minor);
    3.45 -		if (IS_ERR(be->blkif->xenblkd)) {
    3.46 -			err = PTR_ERR(be->blkif->xenblkd);
    3.47 -			be->blkif->xenblkd = NULL;
    3.48 -			xenbus_dev_error(dev, err, "start xenblkd");
    3.49 -			return;
    3.50 -		}
    3.51 -
    3.52  		device_create_file(&dev->dev, &dev_attr_physical_device);
    3.53  		device_create_file(&dev->dev, &dev_attr_mode);
    3.54