From: Keir Fraser Date: Thu, 4 Feb 2010 13:08:27 +0000 (+0000) Subject: xen/blkfront: don't access freed struct xenbus_device X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=b9905fbbf225a62a7ff348f2563d335f1f3b15e5;p=legacy%2Flinux-2.6.18-xen.git xen/blkfront: don't access freed struct xenbus_device Unfortunately c/s 983 still wasn't quite right - there was a reference to freed memory left from blkfront_closing(). Signed-off-by: Jan Beulich --- diff --git a/drivers/xen/blkfront/blkfront.c b/drivers/xen/blkfront/blkfront.c index 678a7609..40d746d6 100644 --- a/drivers/xen/blkfront/blkfront.c +++ b/drivers/xen/blkfront/blkfront.c @@ -63,7 +63,7 @@ #define GRANT_INVALID_REF 0 static void connect(struct blkfront_info *); -static void blkfront_closing(struct xenbus_device *); +static void blkfront_closing(struct blkfront_info *); static int blkfront_remove(struct xenbus_device *); static int talk_to_backend(struct xenbus_device *, struct blkfront_info *); static int setup_blkring(struct xenbus_device *, struct blkfront_info *); @@ -298,7 +298,7 @@ static void backend_changed(struct xenbus_device *dev, xenbus_dev_error(dev, -EBUSY, "Device in use; refusing to close"); else - blkfront_closing(dev); + blkfront_closing(info); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) up(&bd->bd_sem); #else @@ -381,12 +381,11 @@ static void connect(struct blkfront_info *info) * the backend. Once is this done, we can switch to Closed in * acknowledgement. */ -static void blkfront_closing(struct xenbus_device *dev) +static void blkfront_closing(struct blkfront_info *info) { - struct blkfront_info *info = dev->dev.driver_data; unsigned long flags; - DPRINTK("blkfront_closing: %s removed\n", dev->nodename); + DPRINTK("blkfront_closing: %d removed\n", info->vdevice); if (info->rq == NULL) goto out; @@ -406,7 +405,8 @@ static void blkfront_closing(struct xenbus_device *dev) xlvbd_del(info); out: - xenbus_frontend_closed(dev); + if (info->xbdev) + xenbus_frontend_closed(info->xbdev); } @@ -421,7 +421,7 @@ static int blkfront_remove(struct xenbus_device *dev) if(info->users == 0) kfree(info); else - info->is_ready = -1; + info->xbdev = NULL; return 0; } @@ -484,7 +484,7 @@ int blkif_open(struct inode *inode, struct file *filep) { struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; - if(info->is_ready < 0) + if (!info->xbdev) return -ENODEV; info->users++; return 0; @@ -500,13 +500,13 @@ int blkif_release(struct inode *inode, struct file *filep) have ignored this request initially, as the device was still mounted. */ struct xenbus_device * dev = info->xbdev; - enum xenbus_state state = xenbus_read_driver_state(dev->otherend); - if(info->is_ready < 0) { - blkfront_closing(dev); + if (!dev) { + blkfront_closing(info); kfree(info); - } else if (state == XenbusStateClosing && info->is_ready) - blkfront_closing(dev); + } else if (xenbus_read_driver_state(dev->otherend) + == XenbusStateClosing && info->is_ready) + blkfront_closing(info); } return 0; } @@ -896,7 +896,7 @@ int blkfront_is_ready(struct xenbus_device *dev) { struct blkfront_info *info = dev->dev.driver_data; - return info->is_ready > 0; + return info->is_ready && info->xbdev; }