ia64/xen-unstable

changeset 8182:265f68795ebf

Avoid a hang when probing the partition table on imported block
devices. If you export a device so the importing domain sees it as a
whole disk rather than a partition, then add_disk will try to probe
its partition table. However, we were calling add_disk before the
device was properly connected, and then not connecting it until
add_disk had finished. This meant that we ended up never actually
connecting the device, and any accesses to it would then hang.

Fix this by not calling add_disk until we're connected.

Signed-off-by: Steven Smith, sos22@cam.ac.uk
author sos22@douglas.cl.cam.ac.uk
date Fri Dec 02 15:16:37 2005 +0100 (2005-12-02)
parents d4ab8e46136c
children 7062c49e99af
files linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Dec 02 13:27:39 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Dec 02 15:16:37 2005 +0100
     1.3 @@ -311,7 +311,7 @@ static void connect(struct blkfront_info
     1.4  	int err;
     1.5  
     1.6          if( (info->connected == BLKIF_STATE_CONNECTED) || 
     1.7 -	    (info->connected == BLKIF_STATE_SUSPENDED) ) 
     1.8 +	    (info->connected == BLKIF_STATE_SUSPENDED) )
     1.9  		return;
    1.10  
    1.11  	DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
    1.12 @@ -327,16 +327,18 @@ static void connect(struct blkfront_info
    1.13  				 info->xbdev->otherend);
    1.14  		return;
    1.15  	}
    1.16 -	
    1.17 +
    1.18          xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
    1.19  
    1.20  	(void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected); 
    1.21 -	
    1.22 +
    1.23  	/* Kick pending requests. */
    1.24  	spin_lock_irq(&blkif_io_lock);
    1.25  	info->connected = BLKIF_STATE_CONNECTED;
    1.26  	kick_pending_request_queues(info);
    1.27  	spin_unlock_irq(&blkif_io_lock);
    1.28 +
    1.29 +	add_disk(info->gd);
    1.30  }
    1.31  
    1.32  /**
    1.33 @@ -588,7 +590,6 @@ void do_blkif_request(request_queue_t *r
    1.34  
    1.35  	while ((req = elv_next_request(rq)) != NULL) {
    1.36  		info = req->rq_disk->private_data;
    1.37 -
    1.38  		if (!blk_fs_request(req)) {
    1.39  			end_request(req, 0);
    1.40  			continue;
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Dec 02 13:27:39 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Dec 02 15:16:37 2005 +0100
     2.3 @@ -146,6 +146,9 @@ extern int blkif_revalidate(dev_t dev);
     2.4  extern void do_blkif_request (request_queue_t *rq); 
     2.5  
     2.6  /* Virtual block-device subsystem. */
     2.7 +/* Note that xlvbd_add doesn't call add_disk for you: you're expected
     2.8 +   to call add_disk on info->gd once the disk is properly connected
     2.9 +   up. */
    2.10  int xlvbd_add(blkif_sector_t capacity, int device,
    2.11  	      u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
    2.12  void xlvbd_del(struct blkfront_info *info);
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Dec 02 13:27:39 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Dec 02 15:16:37 2005 +0100
     3.3 @@ -261,7 +261,6 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
     3.4  	if (vdisk_info & VDISK_CDROM)
     3.5  		gd->flags |= GENHD_FL_CD;
     3.6  
     3.7 -	add_disk(gd);
     3.8  	info->gd = gd;
     3.9  
    3.10  	return 0;